From: Jan Michel Date: Thu, 7 Jan 2016 15:58:33 +0000 (+0100) Subject: adding more channels to input statistics and trigger logic X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=96c389c0606d47e8634f1253c194e7c621a212f5;p=trb3.git adding more channels to input statistics and trigger logic --- diff --git a/32PinAddOn/config.vhd b/32PinAddOn/config.vhd index 356cde7..3949319 100644 --- a/32PinAddOn/config.vhd +++ b/32PinAddOn/config.vhd @@ -32,9 +32,9 @@ package config is --input monitor and trigger generation logic constant INCLUDE_TRIGGER_LOGIC : integer := c_YES; constant INCLUDE_STATISTICS : integer := c_YES; - constant TRIG_GEN_INPUT_NUM : integer := 16; + constant TRIG_GEN_INPUT_NUM : integer := 32; constant TRIG_GEN_OUTPUT_NUM : integer := 4; - constant MONITOR_INPUT_NUM : integer := 24; + constant MONITOR_INPUT_NUM : integer := 36; constant USE_SINGLE_FIFO : integer := c_YES; -- single fifo for statistics --Run wih 125 MHz instead of 100 MHz, use received clock from serdes or external clock input diff --git a/32PinAddOn/trb3_periph_32PinAddOn.prj b/32PinAddOn/trb3_periph_32PinAddOn.prj index 2692802..5154322 100644 --- a/32PinAddOn/trb3_periph_32PinAddOn.prj +++ b/32PinAddOn/trb3_periph_32PinAddOn.prj @@ -153,7 +153,7 @@ add_file -vhdl -lib work "../../trbnet/special/spi_ltc2600.vhd" add_file -vhdl -lib work "../../trbnet/optical_link/f_divider.vhd" add_file -vhdl -lib work "../../trb3sc/code/load_settings.vhd" add_file -vhdl -lib work "../../trb3sc/code/spi_master_generic.vhd" -add_file -vhdl -lib work "../base/code/input_to_trigger_logic.vhd" +add_file -vhdl -lib work "../base/code/input_to_trigger_logic_record.vhd" add_file -vhdl -lib work "../base/code/input_statistics.vhd" add_file -vhdl -lib work "../base/code/sedcheck.vhd" diff --git a/32PinAddOn/trb3_periph_32PinAddOn.vhd b/32PinAddOn/trb3_periph_32PinAddOn.vhd index e4edf0b..7567b09 100644 --- a/32PinAddOn/trb3_periph_32PinAddOn.vhd +++ b/32PinAddOn/trb3_periph_32PinAddOn.vhd @@ -326,9 +326,9 @@ THE_ENDPOINT : entity work.trb_net16_endpoint_hades_full_handler_record DEBUG_TX_OUT => debug_tx, --Trigger & Monitor - MONITOR_INPUTS(19 downto 0) => INP(19 downto 0), - MONITOR_INPUTS(23 downto 20) => trig_gen_out_i, - TRIG_GEN_INPUTS => INP(15 downto 0), + MONITOR_INPUTS(31 downto 0) => INP(31 downto 0), + MONITOR_INPUTS(35 downto 32) => trig_gen_out_i, + TRIG_GEN_INPUTS => INP(31 downto 0), TRIG_GEN_OUTPUTS => trig_gen_out_i, LCD_OUT => lcd_out, --SED diff --git a/base/code/input_statistics.vhd b/base/code/input_statistics.vhd index 7fb052f..fab23ee 100644 --- a/base/code/input_statistics.vhd +++ b/base/code/input_statistics.vhd @@ -6,7 +6,7 @@ use work.trb_net_std.all; entity input_statistics is generic( - INPUTS : integer range 1 to 32 := 16; + INPUTS : integer range 1 to 96 := 16; SINGLE_FIFO_ONLY : integer := 0 ); port( @@ -32,13 +32,14 @@ signal inp_reg : std_logic_vector(INPUTS-1 downto 0); signal inp_reg_last : std_logic_vector(INPUTS-1 downto 0); signal inp_inv : std_logic_vector(INPUTS-1 downto 0); signal inp_stretch : std_logic_vector(INPUTS-1 downto 0); +signal inp_reg_95 : std_logic_vector(95 downto 0); signal trigger_fifo : std_logic; signal reset_cnt : std_logic; signal timer_rst : std_logic; -signal enable : std_logic_vector(31 downto 0); -signal invert : std_logic_vector(31 downto 0); +signal enable : std_logic_vector(95 downto 0); +signal invert : std_logic_vector(95 downto 0); signal rate : unsigned(31 downto 0); signal fifo_cnt_in : std_logic_vector(17 downto 0); @@ -46,8 +47,8 @@ signal fifo_read : std_logic_vector(LAST_FIFO_NUM downto 0); signal fifo_wait,fifo_wait2,fifo_wait3 : std_logic; signal fifo_empty : std_logic_vector(LAST_FIFO_NUM downto 0); signal fifo_write : std_logic; -signal fifo_select : integer range 0 to 31; -signal fifo_in_sel : integer range 0 to 31; +signal fifo_select : integer range 0 to 95; +signal fifo_in_sel : integer range 0 to 95; type cnt_t is array(0 to INPUTS-1) of unsigned(23 downto 0); @@ -86,10 +87,15 @@ begin if ADDR_IN(6 downto 4) = "000" then ACK_OUT <= '1'; case ADDR_IN(3 downto 0) is - when x"0" => enable <= DATA_IN; - when x"1" => invert <= DATA_IN; + when x"0" => enable(31 downto 0) <= DATA_IN; + when x"1" => invert(31 downto 0) <= DATA_IN; when x"2" => rate <= unsigned(DATA_IN); timer_rst <= '1'; + when x"5" => enable(63 downto 32) <= DATA_IN; + when x"6" => invert(63 downto 32) <= DATA_IN; + when x"7" => enable(95 downto 64) <= DATA_IN; + when x"8" => invert(95 downto 64) <= DATA_IN; + when x"f" => trigger_fifo <= DATA_IN(0); reset_cnt <= DATA_IN(1); fifo_in_sel <= to_integer(unsigned(DATA_IN(20 downto 16))); @@ -102,14 +108,20 @@ begin if ADDR_IN(6 downto 4) = "000" then ACK_OUT <= '1'; case ADDR_IN(3 downto 0) is - when x"0" => DATA_OUT <= enable; - when x"1" => DATA_OUT <= invert; + when x"0" => DATA_OUT <= enable(31 downto 0); + when x"1" => DATA_OUT <= invert(31 downto 0); when x"2" => DATA_OUT <= std_logic_vector(rate); when x"3" => DATA_OUT <= timer; when x"4" => DATA_OUT <= status_reg; - when x"e" => DATA_OUT <= (others => '0'); DATA_OUT(INPUTS-1 downto 0) <= inp_reg; + when x"5" => DATA_OUT <= enable(63 downto 32); + when x"6" => DATA_OUT <= invert(63 downto 32); + when x"7" => DATA_OUT <= enable(95 downto 64); + when x"8" => DATA_OUT <= invert(95 downto 64); + when x"c" => DATA_OUT <= (others => '0'); DATA_OUT <= inp_reg_95(31 downto 0); + when x"d" => DATA_OUT <= (others => '0'); DATA_OUT <= inp_reg_95(63 downto 32); + when x"e" => DATA_OUT <= (others => '0'); DATA_OUT <= inp_reg_95(95 downto 64); when x"f" => DATA_OUT <= (others => '0'); DATA_OUT(20 downto 16) <= std_logic_vector(to_unsigned(fifo_in_sel,5)); - DATA_OUT(12 downto 8) <= std_logic_vector(to_unsigned(INPUTS,5)); + DATA_OUT(14 downto 8) <= std_logic_vector(to_unsigned(INPUTS,7)); DATA_OUT(15 downto 15) <= std_logic_vector(to_unsigned(SINGLE_FIFO_ONLY,1)); when others => DATA_OUT <= (others => '0'); end case; @@ -138,6 +150,8 @@ fifo_wait3 <= fifo_wait2 when rising_edge(CLK); inp_inv <= INPUT xor invert(INPUTS-1 downto 0); inp_stretch <= (inp_inv or inp_stretch) and not inp_reg; +inp_reg_95(INPUTS-1 downto 0) <= inp_reg; + process begin wait until rising_edge(CLK); inp_reg <= inp_inv or inp_stretch; diff --git a/base/code/input_to_trigger_logic_record.vhd b/base/code/input_to_trigger_logic_record.vhd new file mode 100644 index 0000000..b4a263e --- /dev/null +++ b/base/code/input_to_trigger_logic_record.vhd @@ -0,0 +1,166 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.trb_net_std.all; + + +entity input_to_trigger_logic_record is + generic( + INPUTS : integer range 1 to 96 := 24; + OUTPUTS : integer range 1 to 8 := 4 + ); + port( + CLK : in std_logic; + + INPUT : in std_logic_vector(INPUTS-1 downto 0); + OUTPUT : out std_logic_vector(OUTPUTS-1 downto 0); + + BUS_RX : in CTRLBUS_RX; + BUS_TX : out CTRLBUS_TX + ); +end entity; + + +architecture input_to_trigger_logic_arch of input_to_trigger_logic_record is +constant register_bits : integer := (INPUTS-1)/32*32+32-1; +type reg_t is array(0 to OUTPUTS-1) of std_logic_vector(register_bits downto 0); +signal enable : reg_t; +signal invert : std_logic_vector(register_bits downto 0); +signal coincidence1 : std_logic_vector(register_bits downto 0); +signal coincidence2 : std_logic_vector(register_bits downto 0); +signal coin_in_1 : std_logic; +signal coin_in_2 : std_logic; +signal stretch_inp : std_logic_vector(register_bits downto 0); + +type inp_t is array(0 to 4) of std_logic_vector(INPUTS-1 downto 0); +signal inp_shift : inp_t; + +signal inp_inv : std_logic_vector(INPUTS-1 downto 0); +signal inp_long : std_logic_vector(INPUTS-1 downto 0); +signal inp_verylong : std_logic_vector(INPUTS-1 downto 0); + +signal output_i : std_logic_vector(OUTPUTS-1 downto 0); +signal out_reg : std_logic_vector(OUTPUTS-1 downto 0); +signal got_coincidence : std_logic; +signal coin_enable : std_logic; + +begin +THE_CONTROL : process + variable outchan : integer range 0 to 7; + variable slice : integer range 0 to 3; +begin + wait until rising_edge(CLK); + BUS_TX.ack <= '0'; + BUS_TX.nack <= '0'; + BUS_TX.unknown <= '0'; + outchan := to_integer(unsigned(BUS_RX.addr(4 downto 2))); + slice := to_integer(unsigned(BUS_RX.addr(1 downto 0))); + + if BUS_RX.write = '1' then + BUS_TX.ack <= '1'; + if BUS_RX.addr(5) = '0' and outchan < OUTPUTS then + if slice=0 then enable(outchan)(31 downto 0) <= BUS_RX.data; + elsif slice=1 and INPUTS > 32 then enable(outchan)(63 downto 32) <= BUS_RX.data; + elsif slice=2 and INPUTS > 64 then enable(outchan)(95 downto 64) <= BUS_RX.data; + end if; + elsif BUS_RX.addr(5 downto 4) = "10" then + if slice=0 then + case BUS_RX.addr(3 downto 2) is + when "00" => stretch_inp(31 downto 0) <= BUS_RX.data; + when "01" => invert(31 downto 0) <= BUS_RX.data; + when "10" => coincidence1(31 downto 0)<= BUS_RX.data; + when "11" => coincidence2(31 downto 0)<= BUS_RX.data; + end case; + elsif slice=1 and INPUTS > 32 then + case BUS_RX.addr(3 downto 2) is + when "00" => stretch_inp(63 downto 32) <= BUS_RX.data; + when "01" => invert(63 downto 32) <= BUS_RX.data; + when "10" => coincidence1(63 downto 32)<= BUS_RX.data; + when "11" => coincidence2(63 downto 32)<= BUS_RX.data; + end case; + elsif slice=2 and INPUTS > 64 then + case BUS_RX.addr(3 downto 2) is + when "00" => stretch_inp(95 downto 64) <= BUS_RX.data; + when "01" => invert(95 downto 64) <= BUS_RX.data; + when "10" => coincidence1(95 downto 64)<= BUS_RX.data; + when "11" => coincidence2(95 downto 64)<= BUS_RX.data; + end case; + end if; + else + BUS_TX.nack <= '1'; + BUS_TX.ack <= '0'; + end if; + end if; + if BUS_RX.read = '1' then + BUS_TX.ack <= '1'; + if BUS_RX.addr(5) = '0' and outchan < OUTPUTS then + if slice=0 then BUS_TX.data <= enable(outchan)(31 downto 0); + elsif slice=1 and INPUTS > 32 then BUS_TX.data <= enable(outchan)(63 downto 32); + elsif slice=2 and INPUTS > 64 then BUS_TX.data <= enable(outchan)(95 downto 64); + else BUS_TX.data <= (others => '0'); + end if; + elsif BUS_RX.addr(5 downto 4) = "10" then + if slice=0 then + case BUS_RX.addr(3 downto 2) is + when "00" => BUS_TX.data <= stretch_inp(31 downto 0) ; + when "01" => BUS_TX.data <= invert(31 downto 0) ; + when "10" => BUS_TX.data <= coincidence1(31 downto 0); + when "11" => BUS_TX.data <= coincidence2(31 downto 0); + end case; + elsif slice=1 and INPUTS > 32 then + case BUS_RX.addr(3 downto 2) is + when "00" => BUS_TX.data <= stretch_inp(63 downto 32) ; + when "01" => BUS_TX.data <= invert(63 downto 32) ; + when "10" => BUS_TX.data <= coincidence1(63 downto 32); + when "11" => BUS_TX.data <= coincidence2(63 downto 32); + end case; + elsif slice=2 and INPUTS > 64 then + case BUS_RX.addr(3 downto 2) is + when "00" => BUS_TX.data <= stretch_inp(95 downto 64) ; + when "01" => BUS_TX.data <= invert(95 downto 64) ; + when "10" => BUS_TX.data <= coincidence1(95 downto 64); + when "11" => BUS_TX.data <= coincidence2(95 downto 64); + end case; + else BUS_TX.data <= (others => '0'); + end if; + elsif BUS_RX.addr(5 downto 0) = "110000" then + BUS_TX.data(OUTPUTS-1 downto 0) <= out_reg; + BUS_TX.data(31 downto OUTPUTS) <= (others => '0'); + elsif BUS_RX.addr(5 downto 0) = "110001" then + BUS_TX.data <= (others => '0'); + BUS_TX.data( 6 downto 0) <= std_logic_vector(to_unsigned(INPUTS,7)); + BUS_TX.data(11 downto 8) <= std_logic_vector(to_unsigned(OUTPUTS,4)); + else + BUS_TX.nack <= '1'; + BUS_TX.ack <= '0'; + end if; + end if; + +end process; + + + inp_shift(0) <= (inp_inv or inp_shift(0)) and not (inp_shift(1) and not inp_inv); +gen_shift: for i in 1 to 4 generate + inp_shift(i) <= inp_shift(i-1) when rising_edge(CLK); +end generate; + +coin_enable <= or_all(coincidence1) when rising_edge(CLK); + +inp_inv <= INPUT xor invert(INPUTS-1 downto 0); +inp_long <= inp_shift(0) or inp_shift(1); +inp_verylong <= inp_shift(1) or inp_shift(2) or inp_shift(3) or inp_shift(4) when rising_edge(CLK); + +coin_in_1 <= or_all(coincidence1(INPUTS-1 downto 0) and inp_verylong) when rising_edge(CLK); +coin_in_2 <= or_all(coincidence2(INPUTS-1 downto 0) and inp_verylong) when rising_edge(CLK); +got_coincidence <= coin_in_1 and coin_in_2 and coin_enable when rising_edge(CLK); + +gen_outs : for i in 0 to OUTPUTS-1 generate + output_i(i) <= or_all(((inp_long and stretch_inp(INPUTS-1 downto 0)) or (inp_inv(INPUTS-1 downto 0) and not stretch_inp(INPUTS-1 downto 0))) and enable(i)(INPUTS-1 downto 0)) or got_coincidence; +end generate; + + +out_reg <= output_i when rising_edge(CLK); + +OUTPUT <= output_i; + +end architecture; \ No newline at end of file diff --git a/base/code/trb3_tools.vhd b/base/code/trb3_tools.vhd index b7eb11b..1de5be5 100644 --- a/base/code/trb3_tools.vhd +++ b/base/code/trb3_tools.vhd @@ -294,7 +294,7 @@ end generate; -- Trigger logic --------------------------------------------------------------------------- gen_TRIG_LOGIC : if INCLUDE_TRIGGER_LOGIC = 1 generate - THE_TRIG_LOGIC : input_to_trigger_logic + THE_TRIG_LOGIC : entity work.input_to_trigger_logic_record generic map( INPUTS => TRIG_GEN_INPUT_NUM, OUTPUTS => TRIG_GEN_OUTPUT_NUM @@ -305,13 +305,8 @@ gen_TRIG_LOGIC : if INCLUDE_TRIGGER_LOGIC = 1 generate INPUT => TRIG_GEN_INPUTS, OUTPUT => TRIG_GEN_OUTPUTS, - DATA_IN => bustrig_rx.data, - DATA_OUT => bustrig_tx.data, - WRITE_IN => bustrig_rx.write, - READ_IN => bustrig_rx.read, - ACK_OUT => bustrig_tx.ack, - NACK_OUT => bustrig_tx.nack, - ADDR_IN => bustrig_rx.addr + BUS_RX => bustrig_rx, + BUS_TX => bustrig_tx ); end generate; diff --git a/cts/trb3_central.vhd b/cts/trb3_central.vhd index e11cdfe..88c0a89 100644 --- a/cts/trb3_central.vhd +++ b/cts/trb3_central.vhd @@ -1453,7 +1453,7 @@ begin DAT_DATA_IN => handler_data_out, DAT_DATA_OUT => regio_data_in, DAT_READ_ENABLE_IN => handler_read, - DAT_WRITE_ENABLE_IN => handler_read, + DAT_WRITE_ENABLE_IN => handler_write, DAT_TIMEOUT_IN => regio_timeout_out, DAT_DATAREADY_OUT => regio_dataready_in, DAT_WRITE_ACK_OUT => regio_write_ack_in, @@ -2034,7 +2034,7 @@ begin handler_write <= bus_debug_rx_out.write when debug_active = '1' else regio_write_enable_out; bus_debug_tx_in.data <= regio_data_in; - bus_debug_tx_in.ack <= regio_dataready_in or regio_write_ack_in; + bus_debug_tx_in.ack <= regio_dataready_in or regio_write_ack_in ; bus_debug_tx_in.nack <= regio_no_more_data_in; bus_debug_tx_in.unknown <= regio_unknown_addr_in;