From 5d2eb11066584e2e8ffddcf31935766016f8de77 Mon Sep 17 00:00:00 2001 From: Jan Michel Date: Thu, 17 Dec 2015 13:31:00 +0100 Subject: [PATCH] Adding new feature to pulser AddOn - generating multiple pulses --- pulser/code/pulser.vhd | 164 ++++++++++++++++---------- pulser/code/single_channel_pulser.vhd | 3 +- pulser/config_compile_frankfurt.pl | 2 +- pulser/par.p2t | 3 +- pulser/trb3sc_pulser.lpf | 23 +++- pulser/trb3sc_pulser.vhd | 2 +- 6 files changed, 128 insertions(+), 69 deletions(-) diff --git a/pulser/code/pulser.vhd b/pulser/code/pulser.vhd index 1a6b3cb..41260a9 100644 --- a/pulser/code/pulser.vhd +++ b/pulser/code/pulser.vhd @@ -54,44 +54,49 @@ end entity; --Pulsers: 0 - 15: OUTP, 16 - 19: OUTP_FAN, 20 - 29: OUTP_ANA ---0x00 Pulser enable ---0x01 Pulser invert ---0x10 Pulser control strobe +--0x000 - 0x00f Pulser enable +--0x010 - 0x01f Pulser invert +--0x040 - 0x041 Analog configuration (Bit0-4: SEL, Bit 8-9 SELO +--0x0f0 Pulser control strobe ---0x40 - 0x41 Analog configuration (Bit0-4: SEL, Bit 8-9 SELO ---0x80 - 0x9f pulser period, 5 ns ---0xa0 - 0xbf pulse length, 1.25 ns (only multiples of 5ns supported) ---0xc0 - 0xdf pulser offset, 5 ns +--0x100 - 0x1ff pulser period, 5 ns +--0x200 - 0x2ff pulse length, 1.25 ns (only multiples of 5ns supported) +--0x300 - 0x3ff pulser offset, 5 ns architecture pulser_arch of pulser is +constant channel_num : integer := 48; +constant channel_reg_num : integer := 64; signal clk_slow_left, clk_slow_right : std_logic; -type arr_32unsigned_t is array(0 to 31) of unsigned(31 downto 0); +type arr_32unsigned_t is array(0 to channel_num-1) of unsigned(31 downto 0); +type arr_1920slv_t is array(0 to 19) of std_logic_vector(15 downto 0); signal period : arr_32unsigned_t; signal length : arr_32unsigned_t; signal offset : arr_32unsigned_t; -signal timer : arr_32unsigned_t; +signal use_add: arr_1920slv_t; signal ana1_in_select, ana2_in_select : std_logic_vector(3 downto 0); signal ana1_out_select, ana2_out_select: std_logic_vector(1 downto 0); signal control_strobes : std_logic_vector(31 downto 0); -signal pulser_enable : std_logic_vector(31 downto 0); -signal pulser_invert : std_logic_vector(31 downto 0); +signal pulser_enable : std_logic_vector(channel_reg_num-1 downto 0); +signal pulser_invert : std_logic_vector(channel_reg_num-1 downto 0); signal pulser_reset : std_logic; signal next_pulser_reset : std_logic; -- type pulse_ddr_t is array(0 to 31) of std_logic_vector(3 downto 0); -- signal pulse : pulse_ddr_t; - +type d_t is array(0 to 3) of std_logic_vector(channel_num-1 downto 0); type dleft_t is array(0 to 3) of std_logic_vector(19 downto 0); type dright_t is array(0 to 3) of std_logic_vector(9 downto 0); -signal data_left : dleft_t; +type dadd_t is array(0 to 3) of std_logic_vector(7 downto 0); +signal data_all : d_t; +signal data_left : dleft_t; signal data_right : dright_t; - +signal data_add : dadd_t; begin @@ -106,12 +111,11 @@ multi_ch_pulser_left : for n in 0 to 19 generate FREQUENCY => period(n)(23 downto 0), PULSE_WIDTH => length(n)(23 downto 0), OFFSET => offset(n)(23 downto 0), - INVERT => pulser_invert(n), ENABLE => pulser_enable(n), - PULSE(0) => data_left(0)(n), - PULSE(1) => data_left(1)(n), - PULSE(2) => data_left(2)(n), - PULSE(3) => data_left(3)(n) + PULSE(0) => data_all(0)(n), + PULSE(1) => data_all(1)(n), + PULSE(2) => data_all(2)(n), + PULSE(3) => data_all(3)(n) ); end generate; @@ -124,28 +128,53 @@ multi_ch_pulser_right : for n in 0 to 9 generate FREQUENCY => period(n+20)(23 downto 0), PULSE_WIDTH => length(n+20)(23 downto 0), OFFSET => offset(n+20)(23 downto 0), - INVERT => pulser_invert(n+20), ENABLE => pulser_enable(n+20), - PULSE(0) => data_right(0)(n), - PULSE(1) => data_right(1)(n), - PULSE(2) => data_right(2)(n), - PULSE(3) => data_right(3)(n) + PULSE(0) => data_all(0)(n+20), + PULSE(1) => data_all(1)(n+20), + PULSE(2) => data_all(2)(n+20), + PULSE(3) => data_all(3)(n+20) + ); +end generate; + +multi_ch_pulser_addleft : for n in 0 to 7 generate + pulser : entity work.single_channel_pulser + port map ( + CLK => clk_slow_left, + RESET => pulser_reset, + FREQUENCY => period(n+32)(23 downto 0), + PULSE_WIDTH => length(n+32)(23 downto 0), + OFFSET => offset(n+32)(23 downto 0), + ENABLE => pulser_enable(n+32), + PULSE(0) => data_all(0)(n+32), + PULSE(1) => data_all(1)(n+32), + PULSE(2) => data_all(2)(n+32), + PULSE(3) => data_all(3)(n+32) ); end generate; +gen_left : for i in 0 to 19 generate + process begin + wait until rising_edge(clk_slow_left); + data_left(0)(i) <= (data_all(0)(i) or or_all(data_add(0)(7 downto 0) and use_add(i)(7 downto 0))) xor pulser_invert(i); + data_left(1)(i) <= (data_all(1)(i) or or_all(data_add(1)(7 downto 0) and use_add(i)(7 downto 0))) xor pulser_invert(i); + data_left(2)(i) <= (data_all(2)(i) or or_all(data_add(2)(7 downto 0) and use_add(i)(7 downto 0))) xor pulser_invert(i); + data_left(3)(i) <= (data_all(3)(i) or or_all(data_add(3)(7 downto 0) and use_add(i)(7 downto 0))) xor pulser_invert(i); + end process; +end generate; + +gen_right : for i in 20 to 29 generate + data_right(0)(i-20) <= data_all(0)(i) xor pulser_invert(i) when rising_edge(clk_slow_right); + data_right(1)(i-20) <= data_all(1)(i) xor pulser_invert(i) when rising_edge(clk_slow_right); + data_right(2)(i-20) <= data_all(2)(i) xor pulser_invert(i) when rising_edge(clk_slow_right); + data_right(3)(i-20) <= data_all(3)(i) xor pulser_invert(i) when rising_edge(clk_slow_right); +end generate; +data_add(0) <= data_all(0)(39 downto 32) when rising_edge(clk_slow_left); +data_add(1) <= data_all(1)(39 downto 32) when rising_edge(clk_slow_left); +data_add(2) <= data_all(2)(39 downto 32) when rising_edge(clk_slow_left); +data_add(3) <= data_all(3)(39 downto 32) when rising_edge(clk_slow_left); --- gen_outp : for n in 0 to 15 generate --- OUTP(n+1) <= data_left(0)(n); --- end generate; --- --- gen_outp_fan : for n in 0 to 3 generate --- OUTP_FAN(n) <= data_left(0)(n+16); --- end generate; --- gen_outp_ana : for n in 0 to 9 generate --- OUTP_ANA(n) <= pulse(n+20)(0); --- end generate; THE_LEFT_DDR : entity work.ddr_20 port map( @@ -185,29 +214,38 @@ THE_RIGHT_DDR : entity work.ddr_10 ------------------------------------------------- - proc_ctrlbus : process begin + proc_ctrlbus : process + variable channel : integer range 0 to 255; + begin wait until rising_edge(SYSCLK); BUS_TX.ack <= '0'; BUS_TX.nack <= '0'; BUS_TX.unknown <= '0'; control_strobes <= (others => '0'); next_pulser_reset <= '0'; pulser_reset <= RESET or next_pulser_reset; + channel := to_integer(unsigned(BUS_RX.addr(7 downto 0))); if BUS_RX.read = '1' then BUS_TX.ack <= '1'; - if BUS_RX.addr(7 downto 5) = "100" then - BUS_TX.data <= std_logic_vector(period(to_integer(unsigned(BUS_RX.addr(4 downto 0))))); - elsif BUS_RX.addr(7 downto 5) = "101" then - BUS_TX.data <= std_logic_vector(length(to_integer(unsigned(BUS_RX.addr(4 downto 0))))); - elsif BUS_RX.addr(7 downto 5) = "110" then - BUS_TX.data <= std_logic_vector(offset(to_integer(unsigned(BUS_RX.addr(4 downto 0))))); - elsif BUS_RX.addr(7 downto 0) = x"00" then - BUS_TX.data <= pulser_enable; - elsif BUS_RX.addr(7 downto 0) = x"01" then - BUS_TX.data <= pulser_invert; - elsif BUS_RX.addr(7 downto 0) = x"40" then + if BUS_RX.addr(11 downto 8) = x"1" and channel < channel_num then + BUS_TX.data <= std_logic_vector(period(channel)); + elsif BUS_RX.addr(11 downto 8) = x"2" and channel < channel_num then + BUS_TX.data <= std_logic_vector(length(channel)); + elsif BUS_RX.addr(11 downto 8) = x"3" and channel < channel_num then + BUS_TX.data <= std_logic_vector(offset(channel)); + elsif BUS_RX.addr(11 downto 8) = x"4" and channel < 20 then + BUS_TX.data <= x"0000" & std_logic_vector(use_add(channel)); + elsif BUS_RX.addr(11 downto 0) = x"000" then + BUS_TX.data <= pulser_enable(31 downto 0); + elsif BUS_RX.addr(11 downto 0) = x"001" then + BUS_TX.data <= pulser_enable(63 downto 32); + elsif BUS_RX.addr(11 downto 0) = x"010" then + BUS_TX.data <= pulser_invert(31 downto 0); + elsif BUS_RX.addr(11 downto 0) = x"011" then + BUS_TX.data <= pulser_invert(63 downto 32); + elsif BUS_RX.addr(11 downto 0) = x"040" then BUS_TX.data(3 downto 0) <= ana1_in_select; BUS_TX.data(9 downto 8) <= ana1_out_select; - elsif BUS_RX.addr(7 downto 0) = x"41" then + elsif BUS_RX.addr(11 downto 0) = x"041" then BUS_TX.data(3 downto 0) <= ana2_in_select; BUS_TX.data(9 downto 8) <= ana2_out_select; else @@ -217,26 +255,32 @@ THE_RIGHT_DDR : entity work.ddr_10 elsif BUS_RX.write = '1' then BUS_TX.ack <= '1'; - if BUS_RX.addr(7 downto 5) = "100" then - period(to_integer(unsigned(BUS_RX.addr(4 downto 0)))) <= unsigned(BUS_RX.data); + if BUS_RX.addr(11 downto 8) = x"1" and channel < channel_num then + period(channel) <= unsigned(BUS_RX.data); next_pulser_reset <= '1'; - elsif BUS_RX.addr(7 downto 5) = "101" then - length(to_integer(unsigned(BUS_RX.addr(4 downto 0)))) <= unsigned(BUS_RX.data); + elsif BUS_RX.addr(11 downto 8) = x"2" and channel < channel_num then + length(channel) <= unsigned(BUS_RX.data); next_pulser_reset <= '1'; - elsif BUS_RX.addr(7 downto 5) = "110" then - offset(to_integer(unsigned(BUS_RX.addr(4 downto 0)))) <= unsigned(BUS_RX.data); + elsif BUS_RX.addr(11 downto 8) = x"3" and channel < channel_num then + offset(channel) <= unsigned(BUS_RX.data); next_pulser_reset <= '1'; - elsif BUS_RX.addr(7 downto 0) = x"00" then - pulser_enable <= BUS_RX.data; - elsif BUS_RX.addr(7 downto 0) = x"01" then - pulser_invert <= BUS_RX.data; - elsif BUS_RX.addr(7 downto 0) = x"10" then + elsif BUS_RX.addr(11 downto 8) = x"4" and channel < 20 then + use_add(channel) <= BUS_RX.data(15 downto 0); + elsif BUS_RX.addr(11 downto 0) = x"000" then + pulser_enable(31 downto 0) <= BUS_RX.data; + elsif BUS_RX.addr(11 downto 0) = x"001" then + pulser_enable(63 downto 32) <= BUS_RX.data; + elsif BUS_RX.addr(11 downto 0) = x"010" then + pulser_invert(31 downto 0) <= BUS_RX.data; + elsif BUS_RX.addr(11 downto 0) = x"011" then + pulser_invert(63 downto 32) <= BUS_RX.data; + elsif BUS_RX.addr(11 downto 0) = x"0f0" then control_strobes <= BUS_RX.data; pulser_reset <= BUS_RX.data(0); - elsif BUS_RX.addr(7 downto 0) = x"40" then + elsif BUS_RX.addr(11 downto 0) = x"040" then ana1_in_select <= BUS_RX.data(3 downto 0); ana1_out_select <= BUS_RX.data(9 downto 8); - elsif BUS_RX.addr(7 downto 0) = x"41" then + elsif BUS_RX.addr(11 downto 0) = x"041" then ana2_in_select <= BUS_RX.data(3 downto 0); ana2_out_select <= BUS_RX.data(9 downto 8); else diff --git a/pulser/code/single_channel_pulser.vhd b/pulser/code/single_channel_pulser.vhd index a3ffeee..facc7f1 100644 --- a/pulser/code/single_channel_pulser.vhd +++ b/pulser/code/single_channel_pulser.vhd @@ -16,7 +16,6 @@ entity single_channel_pulser is FREQUENCY : in unsigned(23 downto 0); PULSE_WIDTH : in unsigned(23 downto 0); OFFSET : in unsigned(23 downto 0); - INVERT : in std_logic; ENABLE : in std_logic; PULSE : out std_logic_vector(3 downto 0) ); @@ -126,7 +125,7 @@ last_timer <= timer when rising_edge(CLK); end case; - PULSE <= p xor (INVERT & INVERT & INVERT & INVERT); + PULSE <= p; end if; diff --git a/pulser/config_compile_frankfurt.pl b/pulser/config_compile_frankfurt.pl index cb3c4d4..2e74381 100644 --- a/pulser/config_compile_frankfurt.pl +++ b/pulser/config_compile_frankfurt.pl @@ -6,7 +6,7 @@ synplify_path => '/d/jspc29/lattice/synplify/J-2014.09-SP2/', synplify_command => "/d/jspc29/lattice/diamond/3.6_x64/bin/lin64/synpwrap -fg -options", #synplify_command => "/d/jspc29/lattice/synplify/J-2014.09-SP2/bin/synplify_premier_dp", -nodelist_file => 'nodelist_frankfurt.txt', +nodelist_file => 'nodes_frankfurt.txt', #Include only necessary lpf files diff --git a/pulser/par.p2t b/pulser/par.p2t index 45f542e..d3d3093 100644 --- a/pulser/par.p2t +++ b/pulser/par.p2t @@ -1,10 +1,9 @@ -w -i 15 -l 5 --n 1 -y -s 12 --t 24 +-t 26 -c 1 -e 2 #-g guidefile.ncd diff --git a/pulser/trb3sc_pulser.lpf b/pulser/trb3sc_pulser.lpf index 73650b3..d98c07a 100644 --- a/pulser/trb3sc_pulser.lpf +++ b/pulser/trb3sc_pulser.lpf @@ -14,6 +14,7 @@ BLOCK NET "THE_PULSER/length*" ; BLOCK NET "THE_PULSER/offset*" ; BLOCK NET "THE_PULSER/pulser_reset*" ; BLOCK NET "THE_PULSER/pulser_enable*" ; +BLOCK NET "THE_PULSER/use_add*" ; CLOCK_TO_OUT "OUTP*" 30 NS CLKNET = "THE_PULSER/THE_LEFT_DDR/clkop"; CLOCK_TO_OUT "OUTP*" 30 NS CLKNET = "THE_PULSER/THE_RIGHT_DDR/clkop"; @@ -21,7 +22,7 @@ CLOCK_TO_OUT "SEL*" 40 NS CLKNET = "clk_sys"; # REGION "REGION_PULSER_LEFT" "R2C2D" 114 36 DEVSIZE; -UGROUP "Pulser_left" BBOX 114 20 +UGROUP "Pulser_left" BBOX 114 30 BLKNAME THE_PULSER/multi_ch_pulser_left.0.pulser BLKNAME THE_PULSER/multi_ch_pulser_left.1.pulser BLKNAME THE_PULSER/multi_ch_pulser_left.2.pulser @@ -42,11 +43,27 @@ UGROUP "Pulser_left" BBOX 114 20 BLKNAME THE_PULSER/multi_ch_pulser_left.17.pulser BLKNAME THE_PULSER/multi_ch_pulser_left.18.pulser BLKNAME THE_PULSER/multi_ch_pulser_left.19.pulser + BLKNAME THE_PULSER/multi_ch_pulser_addleft.0.pulser + BLKNAME THE_PULSER/multi_ch_pulser_addleft.1.pulser + BLKNAME THE_PULSER/multi_ch_pulser_addleft.2.pulser + BLKNAME THE_PULSER/multi_ch_pulser_addleft.3.pulser + BLKNAME THE_PULSER/multi_ch_pulser_addleft.4.pulser + BLKNAME THE_PULSER/multi_ch_pulser_addleft.5.pulser + BLKNAME THE_PULSER/multi_ch_pulser_addleft.6.pulser + BLKNAME THE_PULSER/multi_ch_pulser_addleft.7.pulser +# BLKNAME THE_PULSER/multi_ch_pulser_addleft.8.pulser +# BLKNAME THE_PULSER/multi_ch_pulser_addleft.9.pulser +# BLKNAME THE_PULSER/multi_ch_pulser_addleft.10.pulser +# BLKNAME THE_PULSER/multi_ch_pulser_addleft.11.pulser +# BLKNAME THE_PULSER/multi_ch_pulser_addleft.12.pulser +# BLKNAME THE_PULSER/multi_ch_pulser_addleft.13.pulser +# BLKNAME THE_PULSER/multi_ch_pulser_addleft.14.pulser +# BLKNAME THE_PULSER/multi_ch_pulser_addleft.15.pulser ; LOCATE UGROUP "Pulser_left" SITE "R2C2D"; # REGION "REGION_PULSER_RIGHT" "R2C147D" 114 35 DEVSIZE; -UGROUP "Pulser_right" BBOX 114 20 +UGROUP "Pulser_right" BBOX 114 30 BLKNAME THE_PULSER/multi_ch_pulser_right.0.pulser BLKNAME THE_PULSER/multi_ch_pulser_right.1.pulser BLKNAME THE_PULSER/multi_ch_pulser_right.2.pulser @@ -58,4 +75,4 @@ UGROUP "Pulser_right" BBOX 114 20 BLKNAME THE_PULSER/multi_ch_pulser_right.8.pulser BLKNAME THE_PULSER/multi_ch_pulser_right.9.pulser ; -LOCATE UGROUP "Pulser_right" SITE "R2C152D"; \ No newline at end of file +LOCATE UGROUP "Pulser_right" SITE "R2C142D"; \ No newline at end of file diff --git a/pulser/trb3sc_pulser.vhd b/pulser/trb3sc_pulser.vhd index 723a04e..c7dadc7 100644 --- a/pulser/trb3sc_pulser.vhd +++ b/pulser/trb3sc_pulser.vhd @@ -299,7 +299,7 @@ THE_ENDPOINT : entity work.trb_net16_endpoint_hades_full_handler_record generic map( PORT_NUMBER => 4, PORT_ADDRESSES => (0 => x"d000", 1 => x"b000", 2 => x"d300", 3 => x"a000", others => x"0000"), - PORT_ADDR_MASK => (0 => 12, 1 => 9, 2 => 1, 3 => 8, others => 0), + PORT_ADDR_MASK => (0 => 12, 1 => 9, 2 => 1, 3 => 12, others => 0), PORT_MASK_ENABLE => 1 ) port map( -- 2.43.0