]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
adding more channels to input statistics and trigger logic
authorJan Michel <j.michel@gsi.de>
Thu, 7 Jan 2016 15:58:33 +0000 (16:58 +0100)
committerJan Michel <j.michel@gsi.de>
Thu, 7 Jan 2016 15:58:33 +0000 (16:58 +0100)
32PinAddOn/config.vhd
32PinAddOn/trb3_periph_32PinAddOn.prj
32PinAddOn/trb3_periph_32PinAddOn.vhd
base/code/input_statistics.vhd
base/code/input_to_trigger_logic_record.vhd [new file with mode: 0644]
base/code/trb3_tools.vhd
cts/trb3_central.vhd

index 356cde72ba7a52f11e02d7769686c79c98cd9c8b..394931962b5c3f4053475f4c0408ee56525397b5 100644 (file)
@@ -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
index 269280250807288d987e3d5a8b2e53975dc9e158..5154322480db503ffdb06e6a2717913b4251fc62 100644 (file)
@@ -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"
 
index e4edf0b8f7c152381f228b96e3182dcec2cceaaa..7567b09968de41913e6110899b7dbf05a5faa5c7 100644 (file)
@@ -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
index 7fb052f00d855329debeb24d6a589d493d53d9f5..fab23ee1f1101d33d240d8f33ab6810bac6ded4f 100644 (file)
@@ -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 (file)
index 0000000..b4a263e
--- /dev/null
@@ -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
index b7eb11b1ec7e49ee3b7217eaca3dc1e71e71d8be..1de5be592e0430dd7c4a304bcc80db96650acdfb 100644 (file)
@@ -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;
index e11cdfe75cef5eea59ada230c0567a4e1abf15f0..88c0a891e6bda7e465c9313ad574312409375966 100644 (file)
@@ -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;