]> jspc29.x-matter.uni-frankfurt.de Git - trb3sc.git/commitdiff
add hades spill mon and R3B timestamp receiver options to CTS design
authorJan Michel <j.michel@gsi.de>
Tue, 28 Jun 2022 14:48:37 +0000 (16:48 +0200)
committerJan Michel <j.michel@gsi.de>
Tue, 28 Jun 2022 14:48:37 +0000 (16:48 +0200)
code/hadesspillmon.vhd [new file with mode: 0644]
cts/config_compile_frankfurt.pl
cts/config_spillmon.vhd [new file with mode: 0644]
cts/trb3sc_cts.prj
cts/trb3sc_cts.vhd

diff --git a/code/hadesspillmon.vhd b/code/hadesspillmon.vhd
new file mode 100644 (file)
index 0000000..002512c
--- /dev/null
@@ -0,0 +1,319 @@
+library ieee;
+  use ieee.std_logic_1164.all;
+  use ieee.numeric_std.all;
+  
+library work;
+  use work.trb_net_components.all;
+  use work.trb_net_std.all;
+  use work.trb3_components.all;
+  use work.config.all;
+
+entity hadesspillmon is
+  generic(
+    INPUT_NUM : integer := 16
+    );
+  port(
+    CLK       : in std_logic;
+    CLK_200   : in std_logic;
+    RESET     : in std_logic;
+    
+    INP       : in std_logic_vector(INPUT_NUM-1 downto 0);
+    START     : in std_logic;
+    
+    BUS_RX    : in  CTRLBUS_RX;
+    BUS_TX    : out CTRLBUS_TX
+    );
+end entity;
+
+
+architecture arch of hadesspillmon is
+
+  signal CONF_binwidth     : integer range 0 to 65000 := 2000;
+  signal CONF_meanwidth    : integer range 0 to 65000 := 2100;
+  signal CONF_disable      : std_logic_vector(INPUT_NUM-1 downto 0);
+  signal CONF_recordoffset : unsigned(23 downto 0);
+
+  signal inp_reg, inp_reg_last  : std_logic_vector(INPUT_NUM-1 downto 0);
+  
+  type state_t is (RUN, SUMUP, MAKEMEAN, SAVE);
+  signal state : state_t;
+  
+  type count_arr is array(0 to INPUT_NUM-1) of unsigned(27 downto 0);
+  signal counter, counter_reg : count_arr; 
+  signal counter_totalbin, counter_totalmean : unsigned(27 downto 0);
+  signal counter_maxbin, counter_minbin      : unsigned(27 downto 0);
+  
+  signal timer         : unsigned(27 downto 0);
+  signal timer_bin, timer_mean : integer  range 0 to 65000;
+  signal reset_counter : std_logic := '0';
+  
+  signal qffifo_data, qffifo_dout  : std_logic_vector(31 downto 0);
+  signal qffifo_read, qffifo_write : std_logic;
+  signal qffifo_count              : std_logic_vector(9 downto 0);
+  signal qffifo_empty, qffifo_full : std_logic;
+  signal qffifo_reset              : std_logic := '1';
+
+  signal binfifo_data, binfifo_dout  : std_logic_vector(15 downto 0);
+  signal binfifo_read, binfifo_write : std_logic;
+  signal binfifo_count               : std_logic_vector(13 downto 0);
+  signal binfifo_empty, binfifo_full : std_logic;
+  signal binfifo_reset               : std_logic := '1';
+  signal binfifo_reset_1, binfifo_reset_2 : std_logic;
+
+  signal qffifo_read_q,  qffifo_read_qq  : std_logic;
+  signal binfifo_read_q, binfifo_read_qq : std_logic;
+  
+  signal start_store, reg_start, last_start : std_logic;
+  signal start_counter : unsigned(23 downto 0);
+  signal triggered, reset_triggered : std_logic;
+  
+begin
+---------------------------------------------------------------------------
+-- Input Counters
+---------------------------------------------------------------------------
+
+inp_reg      <= INP      when rising_edge(CLK_200);
+inp_reg_last <= inp_reg  when rising_edge(CLK_200);
+reg_start    <= START    when rising_edge(CLK);
+
+
+gen_counters : for i in 0 to INPUT_NUM-1 generate
+  process begin
+    wait until rising_edge(CLK_200);
+    if reset_counter = '1' then
+      counter(i) <= (others => '0');
+    elsif inp_reg(i) = '1' and inp_reg_last(i) = '0' and CONF_disable(i) = '0' then
+      counter(i) <= counter(i) + 1;
+    end if;
+  end process;
+end generate;
+
+---------------------------------------------------------------------------
+-- Control State Machine
+---------------------------------------------------------------------------
+PROC_CONTROL : process 
+  variable i : integer range 0 to 16;
+begin
+  wait until rising_edge(CLK);
+  timer_bin <= timer_bin + 1;
+  timer     <= timer + 1;
+  reset_counter <= '0';
+  binfifo_write <= '0';
+  binfifo_reset_2 <= '0';
+  triggered <= triggered and not reset_triggered;
+  last_start <= reg_start;
+  start_store <= start_store or (reg_start and not last_start);
+  
+  
+  case state is
+    when RUN =>
+      if timer_bin = CONF_binwidth then
+        timer_bin        <= 1;
+        timer_mean       <= timer_mean + 1;
+        reset_counter    <= '1';
+        counter_reg      <= counter;
+        counter_totalbin <= 0;
+        i := 0;
+        state <= SUMUP;
+      end if;
+      
+    when SUMUP =>   
+      counter_totalbin <= counter_totalbin + counter_reg(i);
+      if i = INPUT_NUM - 1 then
+        state <= MAKEMEAN;
+      else  
+        i := i + 1;
+      end if;  
+
+    when MAKEMEAN =>
+      counter_totalmean <= counter_totalmean + counter_totalbin;
+      if counter_maxbin < counter_totalbin then
+        counter_maxbin <= counter_totalbin;
+      end if;
+      
+      if start_counter = x"000001" then
+        binfifo_reset_2 <= '1';
+      end if;
+      if start_counter /= 0 then
+        start_counter <= start_counter - 1;
+      end if;
+      if start_store = '1' then
+        start_store <= '0';
+        triggered   <= '1';
+        start_counter <= CONF_recordoffset;
+      end if;
+      
+      binfifo_data  <= counter_totalbin(15 downto 0);
+      binfifo_write <= not binfifo_full;
+      
+      if timer_mean = CONF_meanwidth then
+        state        <= SAVE;
+        qffifo_write <= not qffifo_full;
+        qffifo_data  <= x"8" & std_logic_vector(timer);
+        i := 0;
+      else
+        state        <= RUN;
+      end if;
+      
+    when SAVE =>
+      if i = 0 then
+        qffifo_data  <= x"9" & std_logic_vector(counter_maxbin);
+      elsif i = 1 then
+        qffifo_data  <= x"a" & std_logic_vector(counter_totalmean);
+      elsif i = 2 then
+        state <= RUN;
+        qffifo_write      <= '0';
+        counter_maxbin    <= 0;
+        counter_totalmean <= 0;
+        timer_mean        <= 0;
+      end if;
+      
+      i := i + 1;
+      
+      
+  end case;
+  if RESET = '1' then
+    state         <= RUN;
+    timer_bin     <= 0;
+    timer_mean    <= 0;
+    reset_counter <= '1';    
+    counter_totalmean <= 0;
+    counter_totalbin  <= 0;
+    triggered         <= '0';
+  end if;  
+end process;
+
+
+---------------------------------------------------------------------------
+-- Data Fifo
+---------------------------------------------------------------------------
+THE_QF_FIFO : entity work.fifo_36x512_oreg
+  port map (
+    Data(31 downto 0)  => qffifo_data,
+    Data(35 downto 32) => x"0",
+    Clock              => CLK, 
+    WrEn               => qffifo_write,
+    RdEn               => qffifo_read,
+    Reset              => qffifo_reset,
+    AmFullThresh       => "111111000",
+    Q(31 downto 0)     => qffifo_dout,
+    WCNT               => qffifo_count,
+    Empty              => qffifo_empty, 
+    Full               => open,
+    AlmostFull         => qffifo_full
+    );
+
+THE_BIN_FIFO : entity work.fifo_18x8k_oreg
+  port map (
+    Data(15 downto 0)  => binfifo_data,
+    Data(17 downto 16) => "00",
+    Clock              => CLK, 
+    WrEn               => binfifo_write,
+    RdEn               => binfifo_read,
+    Reset              => binfifo_reset,
+    AmFullThresh       => "1111110100100",
+    Q(15 downto 0)     => binfifo_dout,
+    WCNT               => binfifo_count,
+    Empty              => binfifo_empty, 
+    Full               => open,
+    AlmostFull         => binfifo_full
+    );
+    
+binfifo_reset <= binfifo_reset_1 or binfifo_reset_2;    
+
+
+
+---------------------------------------------------------------------------
+-- Slow Control
+---------------------------------------------------------------------------
+PROC_REG : process begin
+  wait until rising_edge(CLK);
+  BUS_TX.ack     <= '0';
+  BUS_TX.nack    <= '0';
+  BUS_TX.unknown <= '0';
+  BUS_TX.data    <= (others => '0');
+  
+  qffifo_reset   <= '0';
+  qffifo_read    <= '0'; qffifo_read_q <= qffifo_read; qffifo_read_qq <= qffifo_read_q;
+  binfifo_read   <= '0'; binfifo_read_q <= binfifo_read; binfifo_read_qq <= binfifo_read_q;
+  binfifo_reset_1 <= '0';  
+  reset_triggered <= '0';
+  
+  if BUS_RX.read = '1' then
+    BUS_TX.ack     <= '1';
+    if BUS_RX.addr(7 downto 0) = x"00" then
+      BUS_TX.data(15 downto 0)  <= std_logic_vector(to_unsigned(CONF_binwidth,16));
+      BUS_TX.data(31 downto 16) <= std_logic_vector(to_unsigned(CONF_meanwidth,16));
+    elsif BUS_RX.addr(7 downto 0) = x"01" then
+      BUS_TX.data               <= (others => '0');
+    elsif BUS_RX.addr(7 downto 0) = x"02" then
+      BUS_TX.data(9 downto 0)   <= qffifo_count;
+      BUS_TX.data(14)           <= qffifo_empty;
+      BUS_TX.data(15)           <= qffifo_full;
+      BUS_TX.data(29 downto 16) <= binfifo_count;
+      BUS_TX.data(30)           <= binfifo_empty;
+      BUS_TX.data(31)           <= binfifo_full;
+    elsif  BUS_RX.addr(7 downto 0) = x"03" then
+      BUS_TX.data(27 downto 0)  <= std_logic_vector(counter_totalbin);
+    elsif  BUS_RX.addr(7 downto 0) = x"04" then
+      BUS_TX.data(INPUT_NUM-1 downto 0)  <= CONF_disable;
+    elsif  BUS_RX.addr(7 downto 0) = x"05" then
+      BUS_TX.data(23 downto 0)  <= std_logic_vector(CONF_recordoffset);      
+    elsif  BUS_RX.addr(7 downto 0) = x"06" then
+      BUS_TX.data(0)           <= triggered;    
+      BUS_TX.data(1)           <= binfifo_full;    
+      reset_triggered          <= binfifo_full;
+    elsif  BUS_RX.addr(7 downto 0) = x"10" then
+      if qffifo_empty = '1' then
+        BUS_TX.ack     <= '0';
+        BUS_TX.nack    <= '1';        
+      else
+        BUS_TX.ack     <= '0';
+        qffifo_read    <= '1';
+      end if;  
+    elsif  BUS_RX.addr(7 downto 0) = x"11" then
+      if binfifo_empty = '1' then
+        BUS_TX.ack     <= '0';
+        BUS_TX.nack    <= '1';        
+      else
+        BUS_TX.ack     <= '0';
+        binfifo_read   <= '1';
+      end if;      
+    elsif  BUS_RX.addr(7 downto 4) = x"2" then
+      BUS_TX.data      <= x"0" & std_logic_vector(counter_reg(to_integer(unsigned(BUS_RX.addr(3 downto 0)))));
+    else
+      BUS_TX.ack     <= '0';
+      BUS_TX.unknown <= '1';
+    end if;  
+  end if;  
+  if BUS_RX.write = '1' then
+    BUS_TX.ack <= '1';
+    if BUS_RX.addr(7 downto 0) = x"00" then
+      CONF_binwidth  <= to_integer(unsigned(BUS_RX.data(15 downto 0)));
+      CONF_meanwidth <= to_integer(unsigned(BUS_RX.data(31 downto 16)));
+    
+    elsif BUS_RX.addr(7 downto 0) = x"01" then
+      qffifo_reset     <= BUS_RX.data(30);
+      binfifo_reset_1  <= BUS_RX.data(31);
+    elsif BUS_RX.addr(7 downto 0) = x"04" then
+      CONF_disable   <= BUS_RX.data(INPUT_NUM-1 downto 0);
+    elsif BUS_RX.addr(7 downto 0) = x"05" then
+      CONF_recordoffset <= unsigned(BUS_RX.data(23 downto 0));
+    else  
+      BUS_TX.ack     <= '0';
+      BUS_TX.unknown <= '1';
+    end if;      
+  end if;
+  
+  if qffifo_read_qq = '1' then
+    BUS_TX.ack     <= '1';
+    BUS_TX.data    <= qffifo_dout;
+  end if;
+  
+  if binfifo_read_qq = '1' then
+    BUS_TX.ack     <= '1';
+    BUS_TX.data(15 downto 0) <= binfifo_dout;
+  end if;  
+end process;
+
+end architecture;
index f2124c601263fdeeb8d8f5d1a321d65b8445de99..840d113b6fc68be69992b1e5adc0e439d32a638e 100644 (file)
@@ -2,7 +2,7 @@ TOPNAME                      => "trb3sc_cts",
 lm_license_file_for_synplify => "27020\@jspc29", #"27000\@lxcad01.gsi.de";
 lm_license_file_for_par      => "1702\@hadeb05.gsi.de",
 lattice_path                 => '/d/jspc29/lattice/diamond/3.11_x64',
-synplify_path                => '/d/jspc29/lattice/synplify/P-2019.09-SP1',
+synplify_path                => '/d/jspc29/lattice/synplify/R-2020.09-SP1',
 #synplify_command             => "/d/jspc29/lattice/diamond/3.5_x64/bin/lin64/synpwrap -fg -options",
 #synplify_command             => "/d/jspc29/lattice/synplify/J-2014.09-SP2/bin/synplify_premier_dp",
 
diff --git a/cts/config_spillmon.vhd b/cts/config_spillmon.vhd
new file mode 100644 (file)
index 0000000..219c583
--- /dev/null
@@ -0,0 +1,212 @@
+library ieee;
+USE IEEE.std_logic_1164.ALL;
+use ieee.numeric_std.all;
+use work.trb_net_std.all;
+use work.trb_net16_hub_func.all;
+
+package config is
+
+
+------------------------------------------------------------------------------
+--Begin of design configuration
+------------------------------------------------------------------------------
+
+--design options: backplane or front SFP, with or without GBE
+    constant USE_BACKPLANE : integer := c_NO;  --c_YES doesn't work
+    constant USE_ADDON     : integer := c_NO;
+    constant USE_RJADAPT   : integer := c_NO;    --!!! Change pin-out file!
+    constant INCLUDE_GBE   : integer := c_YES;  --c_NO doesn't work
+
+--Runs with 120 MHz instead of 100 MHz     
+    constant USE_120_MHZ            : integer := c_NO; 
+    constant USE_200MHZOSCILLATOR   : integer := c_YES;
+    constant USE_EXTERNAL_CLOCK     : integer := c_YES; --'no' not implemented.
+    constant CLOCK_FAST_SELECT      : integer := c_YES; --fast clock select (135us) or slow (280ms)?
+    
+--Use sync mode, RX clock for all parts of the FPGA
+    constant USE_RXCLOCK            : integer := c_NO;
+   
+--Address settings   
+    constant INIT_ADDRESS           : std_logic_vector := x"F3C7";
+    constant BROADCAST_SPECIAL_ADDR : std_logic_vector := x"62";  --62 for SFP, 63 for backplane
+   
+
+    constant INCLUDE_UART           : integer  := c_NO;
+    constant INCLUDE_SPI            : integer  := c_YES;
+    constant INCLUDE_LCD            : integer  := c_NO;
+    constant INCLUDE_DEBUG_INTERFACE: integer  := c_NO;
+
+    --input monitor and trigger generation logic
+    constant INCLUDE_TDC            : integer  := c_NO;
+    constant INCLUDE_TRIGGER_LOGIC  : integer  := c_NO;
+    constant INCLUDE_STATISTICS     : integer  := c_YES;
+    constant TRIG_GEN_INPUT_NUM     : integer  := 18;
+    constant TRIG_GEN_OUTPUT_NUM    : integer  := 2;
+    constant MONITOR_INPUT_NUM      : integer  := 18;    
+
+    
+    constant FPGA_TYPE               : integer  := 3;  --3: ECP3, 5: ECP5
+
+    
+    constant NUM_TDC_MODULES         : integer range 1 to 4  := 1;  -- number of tdc modules to implement
+    constant NUM_TDC_CHANNELS        : integer range 1 to 65 := 33; -- number of tdc channels per module
+    constant NUM_TDC_CHANNELS_POWER2 : integer range 0 to 6  := 4;  --the nearest power of two, for convenience reasons 
+    constant DOUBLE_EDGE_TYPE        : integer range 0 to 3  := 3;  --double edge type:  0, 1, 2,  3
+    -- 0: single edge only,
+    -- 1: same channel,
+    -- 2: alternating channels,
+    -- 3: same channel with stretcher
+    constant RING_BUFFER_SIZE        : integer range 0 to 7  := 7;  --ring buffer size:  0, 1, 2,  3,  7   --> change names in constraints file
+                                                                    --ring buffer size: 32,64,96,128,dyn
+    constant TDC_DATA_FORMAT         : integer := 0;                                                                  
+
+    constant EVENT_BUFFER_SIZE       : integer range 9 to 13 := 13; -- size of the event buffer, 2**N
+    constant EVENT_MAX_SIZE          : integer := 1023;             --maximum event size. Should not exceed 
+    
+    constant GEN_BUSY_OUTPUT : integer := c_NO;
+    
+    constant TRIGGER_COIN_COUNT      : integer := 0;
+    constant TRIGGER_PULSER_COUNT    : integer := 3;
+    constant TRIGGER_RAND_PULSER     : integer := 1;
+    constant TRIGGER_ADDON_COUNT     : integer := 2;
+    constant PERIPH_TRIGGER_COUNT    : integer := 0;      
+    constant ADDON_LINE_COUNT        : integer := 36 - USE_RJADAPT*12;  --36 with Padiwa, 22 with RJ-adapter
+    constant CTS_OUTPUT_MULTIPLEXERS : integer := 0;
+--TODO:    
+--     constant INCLUDE_MBS_MASTER : integer range c_NO to c_YES := c_NO; 
+--Which external trigger module (ETM) to use?
+     constant INCLUDE_ETM : integer range c_NO to c_YES := c_YES;
+     type ETM_CHOICE_type is (ETM_CHOICE_MBS_VULOM, ETM_CHOICE_MAINZ_A2, ETM_CHOICE_CBMNET, ETM_CHOICE_M26, ETM_CHOICE_R3B, ETM_CHOICE_SPILLMON);
+     constant ETM_CHOICE : ETM_CHOICE_type := ETM_CHOICE_SPILLMON;
+     constant ETM_ID : std_logic_vector(7 downto 0);
+
+   constant INCLUDE_TIMESTAMP_GENERATOR : integer := c_NO;
+    
+    
+    
+------------------------------------------------------------------------------
+--End of design configuration
+------------------------------------------------------------------------------
+
+  type data_t is array (0 to 1023) of std_logic_vector(7 downto 0);
+  constant LCD_DATA : data_t := (
+      others => x"00");
+
+
+    type hub_mii_t is array(0 to 3) of integer;    
+    type hub_ct    is array(0 to 16) of integer;
+    type hub_cfg_t is array(0 to 3) of hub_ct;    
+    type hw_info_t is array(0 to 3) of std_logic_vector(31 downto 0);
+    type intlist_t is array(0 to 7) of integer;
+--  0     opt. link      opt. link
+--  0-7   SFP 1-8
+--  1(8)  CTS read-out   internal         0 1 -   X X O   --downlink only
+--  2(9)  CTS TRG        Sctrl GbE        2 3 4   X X X   --uplink only
+
+    --Order:
+    --       no backplane, no AddOn, 1x SFP, 1x GBE
+-- -- --     --       no backplane, 4x AddOn, 1x SFP, 1x GBE
+    --       no backplane, 8x AddOn, 0x SFP, 1x GBE
+-- -- --     --          backplane,           9x backplane, 1x GBE
+    constant SFP_NUM_ARR    : hub_mii_t := (1,0,8,0);    
+    constant INTERFACE_NUM_ARR    : hub_mii_t := (1,5,8,10);
+--                                                 0 1 2 3 4 5 6 7 8 9 a b c d e f 
+    constant IS_UPLINK_ARR        : hub_cfg_t := ((0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
+                                                  (0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0),  
+--                                                   (0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0),  
+                                                  (0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0),
+                                                  (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0));
+    constant IS_DOWNLINK_ARR      : hub_cfg_t := ((1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),     
+                                                  (1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0),  
+--                                                   (1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0),  
+                                                  (1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0),
+                                                  (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0));
+    constant IS_UPLINK_ONLY_ARR   : hub_cfg_t := ((0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
+                                                  (0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0),  
+                                                  (0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0),  
+--                                                   (0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0),  
+                                                  (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)); 
+                          
+    constant INTERFACE_NUM        : integer;
+    constant IS_UPLINK            : hub_ct;
+    constant IS_DOWNLINK          : hub_ct;
+    constant IS_UPLINK_ONLY       : hub_ct;
+   
+------------------------------------------------------------------------------
+--Select settings by configuration 
+------------------------------------------------------------------------------
+    constant cts_rdo_additional_ports : integer := INCLUDE_TDC + INCLUDE_TIMESTAMP_GENERATOR + INCLUDE_ETM; --for TDC
+    
+    constant HW_INFO_BASE            : unsigned(31 downto 0) := x"9500A000";
+    
+    constant CLOCK_FREQUENCY_ARR  : intlist_t := (100,120, others => 0);
+    constant MEDIA_FREQUENCY_ARR  : intlist_t := (200,240, others => 0);
+                          
+  --declare constants, filled in body                          
+    constant HARDWARE_INFO        : std_logic_vector(31 downto 0);
+    constant CLOCK_FREQUENCY      : integer;
+    constant MEDIA_FREQUENCY      : integer;
+    constant INCLUDED_FEATURES    : std_logic_vector(63 downto 0);
+    
+    
+end;
+
+package body config is
+--compute correct configuration mode
+  
+  constant HARDWARE_INFO        : std_logic_vector(31 downto 0) := std_logic_vector(
+                                      HW_INFO_BASE );
+  constant CLOCK_FREQUENCY      : integer := CLOCK_FREQUENCY_ARR(USE_120_MHZ);
+  constant MEDIA_FREQUENCY      : integer := MEDIA_FREQUENCY_ARR(USE_120_MHZ);
+
+  constant CFG_MODE : integer := USE_ADDON*2;--*2 + USE_BACKPLANE;
+  
+  constant INTERFACE_NUM        : integer := INTERFACE_NUM_ARR(CFG_MODE);
+  constant IS_UPLINK            : hub_ct  := IS_UPLINK_ARR(CFG_MODE);
+  constant IS_DOWNLINK          : hub_ct  := IS_DOWNLINK_ARR(CFG_MODE);
+  constant IS_UPLINK_ONLY       : hub_ct  := IS_UPLINK_ONLY_ARR(CFG_MODE); 
+
+  function etm_id_func return std_logic_vector is
+   variable res : unsigned(7 downto 0);
+  begin
+   res := x"00";
+   if INCLUDE_ETM=c_YES then
+      res := x"60";
+      res := res + TO_UNSIGNED(ETM_CHOICE_type'pos(ETM_CHOICE), 4);
+   end if;
+   return std_logic_vector(res);
+  end function;
+  
+  constant ETM_ID : std_logic_vector(7 downto 0) := etm_id_func;
+   
+  
+function generateIncludedFeatures return std_logic_vector is
+  variable t : std_logic_vector(63 downto 0);
+  begin
+    t               := (others => '0');
+    t(63 downto 56) := std_logic_vector(to_unsigned(1,8)); --table version 1
+    t(3 downto 0)   := std_logic_vector(TO_UNSIGNED(ETM_CHOICE_type'pos(ETM_CHOICE), 4));
+    t(7 downto 7)   := std_logic_vector(to_unsigned(USE_RJADAPT,1));
+    t(11 downto 8)  := std_logic_vector(to_unsigned(DOUBLE_EDGE_TYPE,4));
+    t(14 downto 12) := std_logic_vector(to_unsigned(RING_BUFFER_SIZE,3));
+    t(15 downto 15) := std_logic_vector(to_unsigned(INCLUDE_TDC,1)); --TDC
+    t(16 downto 16) := std_logic_vector(to_unsigned(INCLUDE_GBE,1)); --data via GbE
+    t(17 downto 17) := std_logic_vector(to_unsigned(INCLUDE_GBE,1)); --sctrl via GbE
+    t(23 downto 23) := std_logic_vector(to_unsigned(INCLUDE_GBE,1));
+    t(26 downto 24) := std_logic_vector(to_unsigned(SFP_NUM_ARR(CFG_MODE),3)); --num SFPs with TrbNet
+    t(28 downto 28) := std_logic_vector(to_unsigned(USE_BACKPLANE,1));
+    t(40 downto 40) := std_logic_vector(to_unsigned(INCLUDE_LCD,1));
+    t(42 downto 42) := std_logic_vector(to_unsigned(INCLUDE_SPI,1));
+    t(43 downto 43) := std_logic_vector(to_unsigned(INCLUDE_UART,1));
+    t(44 downto 44) := std_logic_vector(to_unsigned(INCLUDE_STATISTICS,1));
+    t(51 downto 48) := std_logic_vector(to_unsigned(INCLUDE_TRIGGER_LOGIC,4));
+    t(52 downto 52) := std_logic_vector(to_unsigned(USE_120_MHZ,1));
+    t(53 downto 53) := std_logic_vector(to_unsigned(USE_RXCLOCK,1));
+    t(54 downto 54) := std_logic_vector(to_unsigned(USE_EXTERNAL_CLOCK,1));
+    t(55 downto 55) := std_logic_vector(to_unsigned(USE_200MHZOSCILLATOR,1));
+    return t;
+  end function;  
+
+  constant INCLUDED_FEATURES : std_logic_vector(63 downto 0) := generateIncludedFeatures;    
+
+end package body;
index 1ad9b458e0701c27fdfe90f17100eafbe96bc6f1..646d4a6f71638a95d2aed8d446561d7e36608f42 100644 (file)
@@ -99,6 +99,7 @@ add_file -vhdl -lib work "../../trbnet/lattice/ecp3/fifo/fifo_18x256_oreg.vhd"
 add_file -vhdl -lib work "../../trbnet/lattice/ecp3/fifo/fifo_18x512_oreg.vhd"
 add_file -vhdl -lib work "../../trbnet/lattice/ecp3/fifo/fifo_18x1k_oreg.vhd"
 add_file -vhdl -lib work "../../trbnet/lattice/ecp3/fifo/fifo_18x2k_oreg.vhd"
+add_file -vhdl -lib work "../../trbnet/lattice/ecp3/fifo/fifo_18x8k_oreg.vhd"
 add_file -vhdl -lib work "../../trbnet/lattice/ecp3/fifo/fifo_9x2k_oreg.vhd"
 add_file -vhdl -lib work "../../trbnet/lattice/ecp2m/fifo/fifo_var_oreg.vhd"
 add_file -vhdl -lib work "../../trbnet/lattice/ecp3/fifo/fifo_19x16_obuf.vhd"
@@ -264,6 +265,9 @@ add_file -vhdl -lib work "../../trb3/cts/source/cts_trg_pseudorand_pulser.vhd"
 add_file -vhdl -lib work "../../trb3/cts/source/cts_trigger.vhd"
 add_file -vhdl -lib work "../../trb3/cts/source/cts.vhd"
 add_file -vhdl -lib work "../../trb3/base/code/mbs_vulom_recv.vhd"
+add_file -vhdl -lib work "../../trb3/cts/source/r3b_timestamp_recv.vhd"
+add_file -vhdl -lib work "../../trb3sc/code/hadesspillmon.vhd"
+
 
 #TDC
 add_file -vhdl -lib work "../../trb3sc/tdc_release/tdc_version.vhd"
@@ -297,6 +301,37 @@ add_file -vhdl -lib work "../../tdc/base/cores/ecp3/FIFO/FIFO_36x32_OutReg.vhd"
 add_file -vhdl -lib work "../../tdc/base/cores/ecp3/PLL/pll_in125_out33.vhd"
 
 
+#R3B timestamps
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/generic/rataser_4phase_sample.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_4phase_deser.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_big_xor.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_clock_recv.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_clock_send.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_hamming_decode_dual.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_hamming_decode.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_hamming_encode.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_hamming_util.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_min_max_filter.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_records.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_signals_recv.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_signals_send.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_sym24word8_decode.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_sym24word8_diff.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_sym24word8_util.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_sym8word1_decode.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_symburst_decode.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_symburst_diff.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_symburst_util.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_sync_count.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_timestamp_decode.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_track_bitslots.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_track_bitstream.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_track_edge.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_trig_recv.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_trig_send.vhd"
+add_file -vhdl -lib work "../../rataser-20211012/vhdl/rataser_util.vhd"
+
+
 add_file -vhdl -lib work "./trb3sc_cts.vhd"
 #add_file -fpga_constraint "./synplify.fdc"
 
index 9c49e5d8372fcebf04eaeb871619fee0d4866508..9db196fb963f86d1429ba76edce053f247ce5fa1 100644 (file)
@@ -28,6 +28,7 @@ entity trb3sc_cts is
     SPARE_IN             : in    std_logic_vector( 1 downto  0);
     INP                  : in    std_logic_vector(31-12*USE_RJADAPT downto  0); 
     RJ_IO                : out   std_logic_vector( 3 downto  0); --0, inner RJ trigger output
+    RJ_IO_IN             : in    std_logic_vector( 1 downto  0);
     REFOUT               : out   std_logic_vector( 8*USE_RJADAPT-1 downto  0);
     
     --LED
@@ -125,9 +126,9 @@ architecture trb3sc_arch of trb3sc_cts is
   signal med2int           : med2int_array_t(0 to INTERFACE_NUM-1);
   signal int2med           : int2med_array_t(0 to INTERFACE_NUM-1);
   
-  signal ctrlbus_rx, bussci1_rx, bussci2_rx, bussci3_rx, bustools_rx, buscts_rx,
+  signal ctrlbus_rx, bussci1_rx, bussci2_rx, bussci3_rx, bustools_rx, buscts_rx, busr3b_rx,
          bustc_rx, busgbeip_rx, busgbereg_rx, bus_master_out, handlerbus_rx, bustdc_rx  : CTRLBUS_RX;
-  signal ctrlbus_tx, bussci1_tx, bussci2_tx, bussci3_tx, bustools_tx, buscts_tx,
+  signal ctrlbus_tx, bussci1_tx, bussci2_tx, bussci3_tx, bustools_tx, buscts_tx, busr3b_tx,
          bustc_tx, busgbeip_tx, busgbereg_tx, bus_master_in, bustdc_tx : CTRLBUS_TX;
   
   signal sed_error_i    : std_logic;
@@ -821,7 +822,7 @@ end generate;
         CLK      => clk_sys,
         RESET_IN => reset_i,
 
-        MBS_IN  => INP(0),
+        MBS_IN  => RJ_IO_IN(1),
         CLK_200 => clk_full,
 
         TRG_ASYNC_OUT => mbs_async_out, --TODO MBS async connect to TDC
@@ -845,15 +846,79 @@ end generate;
         );
   end generate;
   
+
+---------------------------------------------------------------------------
+-- R3B Input Adapter
+---------------------------------------------------------------------------
+  gen_r3b_etm : if ETM_CHOICE = ETM_CHOICE_R3B and INCLUDE_ETM = c_YES generate
+    signal etm_trigger_in : std_logic;
+  begin
+    etm_trigger_in <= cts_rdo_rx.valid_timing_trg or cts_rdo_rx.valid_notiming_trg or cts_rdo_rx.invalid_trg;
+  
+  
+    THE_R3B : entity work.r3b_timestamp_recv
+      port map(
+        CLK            => clk_sys,
+        CLK_SENDER     => CLK_SUPPL_PCLK, --125 Mhz
+        RESET_IN       => reset_i,
+          
+        SERIAL_IN      => RJ_IO_IN(1),
+        SERIAL_OUT     => RJ_IO(2),
+        TRG_SYNC_OUT   => cts_ext_trigger,
+        
+        BUS_RX         => busr3b_rx,
+        BUS_TX         => busr3b_tx,
+        
+        --data output for read-out
+        TRIGGER_IN     => etm_trigger_in,
+        DATA_OUT       => cts_rdo_additional(0).data,
+        WRITE_OUT      => cts_rdo_additional(0).data_write,
+        FINISHED_OUT   => cts_rdo_additional(0).data_finished,
+        STATUSBIT_OUT  => cts_rdo_additional(0).statusbits,
+        HEADER_REG_OUT => cts_ext_header,
+
+        --Registers / Debug     
+        CONTROL_REG_IN => cts_ext_control,
+        STATUS_REG_OUT => cts_ext_status
+        );
+  end generate;
+  gen_nor3b_etm : if (ETM_CHOICE /= ETM_CHOICE_R3B and ETM_CHOICE /= ETM_CHOICE_SPILLMON) or INCLUDE_ETM = c_NO generate
+    busr3b_tx.unknown <= busr3b_rx.read or busr3b_rx.write when rising_edge(clk_sys);
+  end generate;
+
+  
+---------------------------------------------------------------------------
+-- Hades Spill Mon - not a real CTS module, but CTS framework needed
+---------------------------------------------------------------------------  
+  gen_hsm_etm : if ETM_CHOICE = ETM_CHOICE_SPILLMON and INCLUDE_ETM = c_YES generate
+    THE_SPILLMON : entity work.hadesspillmon
+      port map(
+        CLK     => clk_sys,
+        CLK_200 => clk_full,
+        RESET   => reset_i,
+        
+        INP     => INP(15 downto 0),
+        START   => SPARE_IN(0),
+        
+        BUS_RX         => busr3b_rx,
+        BUS_TX         => busr3b_tx
+        );
+        
+    cts_rdo_additional(0).data          <= (others => '0');
+    cts_rdo_additional(0).data_write    <= '0';
+    cts_rdo_additional(0).data_finished <= '1';
+    cts_rdo_additional(0).statusbits    <= (others => '0');
+  end generate;
+  
   
 ---------------------------------------------------------------------------
 -- Bus Handler
 ---------------------------------------------------------------------------
   THE_BUS_HANDLER : entity work.trb_net16_regio_bus_handler_record
     generic map(
-      PORT_NUMBER      => 9,
-      PORT_ADDRESSES   => (0 => x"d000", 1 => x"d300", 2 => x"b000", 3 => x"b200", 4 => x"b400", 5 => x"8100", 6 => x"8300", 7 => x"a000", 8 => x"c000", others => x"0000"),
-      PORT_ADDR_MASK   => (0 => 12,      1 => 1,       2 => 9,       3 => 9,       4 => 9,       5 => 8,       6 => 8,       7 => 11,      8 => 12,      others => 0),
+      PORT_NUMBER      => 10,
+      PORT_ADDRESSES   => (0 => x"d000", 1 => x"d300", 2 => x"b000", 3 => x"b200", 4 => x"b400", 5 => x"8100", 6 => x"8300", 7 => x"a000", 8 => x"c000", 9 => x"b800", others => x"0000"),
+      PORT_ADDR_MASK   => (0 => 12,      1 => 1,       2 => 9,       3 => 9,       4 => 9,       5 => 8,       6 => 8,       7 => 11,      8 => 12,      9 => 8, others => 0),
       PORT_MASK_ENABLE => 1
       )
     port map(
@@ -872,6 +937,7 @@ end generate;
       BUS_RX(6) => busgbereg_rx,
       BUS_RX(7) => buscts_rx,
       BUS_RX(8) => bustdc_rx,
+      BUS_RX(9) => busr3b_rx,
       BUS_TX(0) => bustools_tx,
       BUS_TX(1) => bustc_tx,
       BUS_TX(2) => bussci1_tx,
@@ -881,6 +947,7 @@ end generate;
       BUS_TX(6) => busgbereg_tx,
       BUS_TX(7) => buscts_tx,
       BUS_TX(8) => bustdc_tx,
+      BUS_TX(9) => busr3b_tx,
       STAT_DEBUG => open
       );
 
@@ -931,7 +998,7 @@ end generate;
       DEBUG_OUT  => open
       );      
 
-monitor_inputs_i <= cts_addon_triggers_in; --INP;
+monitor_inputs_i <= cts_addon_triggers_in(MONITOR_INPUT_NUM-1 downto 0); --INP;
       
 gen_reboot_no_gbe : if INCLUDE_GBE = c_NO generate
   do_reboot_i <= common_ctrl_reg(15);
@@ -966,6 +1033,12 @@ gen_reftime_out : if USE_RJADAPT = 1 generate
 end generate;
   
   RJ_IO(0)                           <= cts_trigger_out;
+  
+  
+gen_busy : if GEN_BUSY_OUTPUT = c_YES generate
+  RJ_IO(3)  <= trigger_busy_i;
+end generate;
+
 
 ---------------------------------------------------------------------------
 -- LED
@@ -1013,34 +1086,45 @@ end generate;
 -------------------------------------------------------------------------------
 -- TDC
 -------------------------------------------------------------------------------
- THE_TDC : entity work.TDC_record
-   generic map (
-     CHANNEL_NUMBER => NUM_TDC_CHANNELS,  -- Number of TDC channels per module
-     STATUS_REG_NR  => 21,             -- Number of status regs
-     DEBUG          => c_YES,
-     SIMULATION     => c_NO)
-   port map (
-     RESET              => reset_i,
-     CLK_TDC            => clk_full_osc,
-     CLK_READOUT        => clk_sys,    -- Clock for the readout
-     REFERENCE_TIME     => cts_trigger_out,  -- Reference time input
-     HIT_IN             => hit_in_i(NUM_TDC_CHANNELS-1 downto 1),  -- Channel start signals
-     HIT_CAL_IN         => clk_cal,    -- Hits for calibrating the TDC
-     -- Trigger signals from handler
-     BUSRDO_RX          => cts_rdo_rx,
-     BUSRDO_TX          => cts_rdo_additional(INCLUDE_TIMESTAMP_GENERATOR + INCLUDE_ETM),
-     -- Slow control bus
-     BUS_RX             => bustdc_rx,
-     BUS_TX             => bustdc_tx,
-     -- Dubug signals
-     INFO_IN            => timer,
-     LOGIC_ANALYSER_OUT => open
-     );
-
- -- For single edge measurements
- gen_single : if DOUBLE_EDGE_TYPE = 0 or DOUBLE_EDGE_TYPE = 1 or DOUBLE_EDGE_TYPE = 3 generate
-   hit_in_i(NUM_TDC_CHANNELS-1 downto 1) <= INP(NUM_TDC_CHANNELS-2 downto 0);
- end generate;
+ --THE_TDC : entity work.TDC_record
+   --generic map (
+     --CHANNEL_NUMBER => NUM_TDC_CHANNELS,  -- Number of TDC channels per module
+     --STATUS_REG_NR  => 21,             -- Number of status regs
+     --DEBUG          => c_YES,
+     --SIMULATION     => c_NO)
+   --port map (
+     --RESET              => reset_i,
+     --CLK_TDC            => clk_full_osc,
+     --CLK_READOUT        => clk_sys,    -- Clock for the readout
+     --REFERENCE_TIME     => cts_trigger_out,  -- Reference time input
+     --HIT_IN             => hit_in_i(NUM_TDC_CHANNELS-1 downto 1),  -- Channel start signals
+     --HIT_CAL_IN         => clk_cal,    -- Hits for calibrating the TDC
+     ---- Trigger signals from handler
+     --BUSRDO_RX          => cts_rdo_rx,
+     --BUSRDO_TX          => cts_rdo_additional(INCLUDE_TIMESTAMP_GENERATOR + INCLUDE_ETM),
+     ---- Slow control bus
+     --BUS_RX             => bustdc_rx,
+     --BUS_TX             => bustdc_tx,
+     ---- Dubug signals
+     --INFO_IN            => timer,
+     --LOGIC_ANALYSER_OUT => open
+     --);
+
+ ---- For single edge measurements
+ --gen_single : if ETM_CHOICE /= ETM_CHOICE_R3B generate
+   --hit_in_i(NUM_TDC_CHANNELS-1 downto 1) <= INP(NUM_TDC_CHANNELS-2 downto 0);
+ --end generate;
+
+ --gen_TDC_R3B : if ETM_CHOICE = ETM_CHOICE_R3B generate
+   --hit_in_i(2 downto 1) <= SPARE_IN;
+   --hit_in_i(NUM_TDC_CHANNELS-1 downto 3) <= INP(NUM_TDC_CHANNELS-4 downto 0);
+ --end generate; 
+
+--Handle Control bus without TDC
+gen_sctrl_dummy : if INCLUDE_TDC = c_NO generate
+  bustdc_tx.unknown <= bustdc_rx.read  or bustdc_rx.write when rising_edge(clk_sys);
+end generate;
   
 end architecture;