From 2e0ecdbdecbadcecd2d80b630e08683184e9fcb7 Mon Sep 17 00:00:00 2001
From: David Gabriel Monk <david.gabriel.monk@cern.ch>
Date: Sat, 2 Sep 2023 15:17:10 +0200
Subject: [PATCH] Added global header block

---
 common/firmware/cfg/module.dep                |   1 +
 common/firmware/hdl/LinkCombinerCore.vhd      |  48 +-------
 common/firmware/hdl/LinkCombinerIPBus.vhd     |   5 +-
 common/firmware/hdl/MProcessor.vhd            |   9 +-
 .../firmware/hdl/PayloadHeaderGenerator.vhd   | 107 ++++++++++++++++++
 common/firmware/hdl/mprocessor_constants.vhd  |   1 +
 top/firmware/hdl/emp_payload.vhd              |  24 +++-
 7 files changed, 143 insertions(+), 52 deletions(-)
 create mode 100644 common/firmware/hdl/PayloadHeaderGenerator.vhd

diff --git a/common/firmware/cfg/module.dep b/common/firmware/cfg/module.dep
index f8a06571..d9a3da95 100644
--- a/common/firmware/cfg/module.dep
+++ b/common/firmware/cfg/module.dep
@@ -10,6 +10,7 @@ src LinkAggregatorIPBus.vhd
 src LinkCombinerCore.vhd
 src LinkCombinerIPBus.vhd
 src --vhdl2008 TrackReconstructor.vhd
+src PayloadHeaderGenerator.vhd
 
 src ipbus_decode_link_aggregator.vhd
 src ipbus_decode_mprocessor.vhd
diff --git a/common/firmware/hdl/LinkCombinerCore.vhd b/common/firmware/hdl/LinkCombinerCore.vhd
index deb58e18..89aa7012 100644
--- a/common/firmware/hdl/LinkCombinerCore.vhd
+++ b/common/firmware/hdl/LinkCombinerCore.vhd
@@ -20,8 +20,7 @@ entity LinkCombinerCore is
         output_enable    : in std_logic := '0';
         links_in         : in ldata(N_INPUT_LINKS - 1 downto 0);
         packet_start     : in std_logic;
-        header_in        : in tCICHeaderArray(cNumberOfFEModules * cNumberOfCICs - 1 downto 0) := (others => ('0', (others => '0'), (others => '0'), (others => '0')));
-        header_user_bits : in std_logic_vector(31 downto 0) := (others => '0');
+        payload_header   : in std_logic_vector(127 downto 0) := (others => '0');
         --- Ouput Ports ---
         link_out        : out lword := LWORD_NULL;
         --- Debug Ports ---
@@ -310,30 +309,12 @@ begin
             output_din     <= input_dout_array(output_pointer_buffered);
             output_wr_en   <= input_valid_array(output_pointer_buffered) and (not reset);
             
-            
-            if reset = '1' then
-                packet_stub_count <= (others => '0');
-                packet_stub_count_previous <= packet_stub_count;
-                packet_stub_counter_pointer <= 0;
-                packet_stub_count_done <= '0';
-            else
-                if packet_stub_count_done = '0' then
-                    if packet_stub_counter_pointer = (cNumberOfFEModules - 1) * cNumberOfCICs then
-                        packet_stub_count_done <= '1';
-                    end if;
-                    packet_stub_count <= packet_stub_count + unsigned(header_in(packet_stub_counter_pointer).stub_count) + unsigned(header_in(packet_stub_counter_pointer + 1).stub_count);
-                    packet_stub_counter_pointer <= packet_stub_counter_pointer + cNumberOfCICs;
-                end if;
-            end if;
-            
             if counter = 1 then
-                output_wr_en_buf            <= '1';
-                output_din_buf(63 downto 32) <= header_user_bits;
-                output_din_buf(31 downto 0)  <= std_logic_vector(super_id);
+                output_wr_en_buf <= '1';
+                output_din_buf   <= payload_header(63 downto 0);
             elsif counter = 2 then
                 output_din_buf <= (others => '0');
-                output_din_buf(11 downto 0) <= bcid_sr(bcid_sr'high);
-                output_din_buf(19 downto 12) <= std_logic_vector(packet_stub_count_previous);
+                output_din_buf(19 downto 0) <= payload_header(83 downto 64);
                 output_wr_en_buf <= '1';
             else
                 output_wr_en_buf  <= output_wr_en and (not reset);
@@ -343,27 +324,6 @@ begin
         end if;
     end process pCombineBuffers;
 
-
-    --==============================--
-    pBufferHeader: process(clk_p)
-    --==============================--
-        variable bcid             : std_logic_vector(12 - 1 downto 0)                                     := (others => '0');
-    begin
-        if rising_edge(clk_p) then
-            if output_reset = '1' then
-                super_id <= (others => '0');
-            else
-                if packet_start = '1' then
-                    bcid      := std_logic_vector(header_in(0).bcid);
-                    bcid_sr   <= bcid_sr(bcid_sr'high - 1 downto 0) & bcid;
-                    if unsigned(bcid_sr(bcid_sr'high)) > unsigned(bcid_sr(bcid_sr'high - 1)) then
-                        super_id <= super_id + 1;
-                    end if;
-                end if;
-            end if;
-        end if;
-    end process pBufferHeader;
-
     --==============================--
     -- Debug
     --==============================--
diff --git a/common/firmware/hdl/LinkCombinerIPBus.vhd b/common/firmware/hdl/LinkCombinerIPBus.vhd
index 7abbaee7..47ce1078 100644
--- a/common/firmware/hdl/LinkCombinerIPBus.vhd
+++ b/common/firmware/hdl/LinkCombinerIPBus.vhd
@@ -21,7 +21,7 @@ entity LinkCombinerIPBus is
         reset            : in std_logic;
         links_in         : in ldata(N_INPUT_LINKS - 1 downto 0);
         packet_start     : in std_logic;
-        header_in        : in tCICHeaderArray(cNumberOfFEModules * cNumberOfCICs - 1 downto 0) := (others => ('0', (others => '0'), (others => '0'), (others => '0')));
+        payload_header   : in std_logic_vector(127 downto 0) := (others => '0');
         lff              : in std_logic;
         output_srst      : in std_logic := '0';
         --- Ouput Ports ---
@@ -109,8 +109,7 @@ begin
         output_enable    => link_combiner_rd_en,
         links_in         => masked_input,
         packet_start     => packet_start,
-        header_in        => header_in,
-        header_user_bits => control_registers(1),
+        payload_header   => payload_header,
         --- Output Ports ---
         link_out         => link_out,
         --- Debug Ports ---
diff --git a/common/firmware/hdl/MProcessor.vhd b/common/firmware/hdl/MProcessor.vhd
index 4455cea1..d8a4465b 100644
--- a/common/firmware/hdl/MProcessor.vhd
+++ b/common/firmware/hdl/MProcessor.vhd
@@ -23,8 +23,8 @@ entity MProcessor is
         --- Input Ports ---
         clk_p              : in  std_logic;
         links_in           : in  ldata(N_LINKS - 1 downto 0);
-        header_in          : in  tCICHeaderArray(cNumberOfFEModules * cNumberOfCICs - 1 downto 0) := (others => ('0', (others => '0'), (others => '0'), (others => '0')));
         header_start_array : in  tHeaderStartArray                                                := (others => (others => '0'));
+        payload_header     : in  std_logic_vector(127 downto 0)                                   := (others => '0');
         gbe_backpressure   : in  std_logic                                                        := '0';
         srst               : in  std_logic                                                        := '0';
         --- Output Ports ---
@@ -33,7 +33,9 @@ entity MProcessor is
         ipb_clk            : in  std_logic;
         ipb_rst            : in  std_logic;
         ipb_in             : in  ipb_wbus;
-        ipb_out            : out ipb_rbus
+        ipb_out            : out ipb_rbus;
+        --- Debug Ports ---
+        debug_readout_reset : out std_logic := '0'
     );
 end MProcessor;
 
@@ -134,7 +136,7 @@ begin
         reset         => readout_reset,
         links_in      => aggregated_stubs,
         packet_start  => packet_start,
-        header_in     => header_in,
+        payload_header => payload_header,
         lff           => gbe_backpressure,
         output_srst   => srst,
         --- Output Ports ---
@@ -163,6 +165,7 @@ begin
     status_registers(0)(0) <= gbe_backpressure;
     status_registers(1)    <= super_id;
     packet_start           <= header_start_array(to_integer(unsigned(control_registers(0)(2 downto 0))))(0);
+    debug_readout_reset    <= readout_reset;
 
 
     --==============================--
diff --git a/common/firmware/hdl/PayloadHeaderGenerator.vhd b/common/firmware/hdl/PayloadHeaderGenerator.vhd
new file mode 100644
index 00000000..f4c17c98
--- /dev/null
+++ b/common/firmware/hdl/PayloadHeaderGenerator.vhd
@@ -0,0 +1,107 @@
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.NUMERIC_STD.ALL;
+use work.emp_data_types.all;
+use work.dtc_link_maps.all;
+use work.dtc_constants.all;
+use work.dtc_data_types.all;
+use IEEE.std_logic_misc.all;
+use work.mprocessor_constants.all;
+
+
+entity PayloadHeaderGenerator is
+    port ( 
+        --- Input Ports ---
+        clk_p : in std_logic;
+        reset : in std_logic;
+        readout_reset : in std_logic;
+        header_start : in std_logic;
+        module_header_in : in tCICHeaderArray(cNumberOfFEModules * cNumberOfCICs - 1 downto 0) := (others => ('0', (others => '0'), (others => '0'), (others => '0')));
+        user_bits : in std_logic_vector(31 downto 0);
+        --- Ouput Ports ---
+        header_out : out tPayloadHeaderArray := (others => (others => '0'))
+    );
+end PayloadHeaderGenerator;
+
+architecture Behavioral of PayloadHeaderGenerator is
+
+    type tBCIDShiftRegister    is array(1 downto 0)       of std_logic_vector(12 - 1 downto 0);
+    type tInputDataCountArray  is array(integer range <>) of std_logic_vector(5 downto 0);
+    
+    signal bcid_sr                                                        : tBCIDShiftRegister                                 := (others => (others => '0'));
+    signal super_id                                                       : unsigned(32 - 1 downto 0)                          := (others => '0');
+
+    signal packet_stub_count, packet_stub_count_previous                  : unsigned(7 downto 0)                               := (others => '0');
+    signal packet_stub_counter_pointer                                    : integer                                            := 0;
+    signal packet_stub_count_done                                         : std_logic                                          := '0';
+    
+    signal header_word : std_logic_vector(127 downto 0) := (others => '0');
+
+begin
+
+    --==============================--
+    pBufferHeader: process(clk_p)
+    --==============================--
+        variable bcid             : std_logic_vector(12 - 1 downto 0)                                     := (others => '0');
+    begin
+        if rising_edge(clk_p) then
+            if reset = '1' then
+                super_id <= (others => '0');
+                header_word <= (others => '0');
+            else
+                if header_start = '1' then
+                    bcid      := std_logic_vector(module_header_in(0).bcid);
+                    bcid_sr   <= bcid_sr(bcid_sr'high - 1 downto 0) & bcid;
+                    if unsigned(bcid_sr(bcid_sr'high)) > unsigned(bcid_sr(bcid_sr'high - 1)) then
+                        super_id <= super_id + 1;
+                    end if;
+                end if;
+                
+                header_word <= (others => '0');
+                header_word(31 downto 0) <= std_logic_vector(super_id);
+                header_word(63 downto 32) <= user_bits;
+                header_word(75 downto 64) <= bcid_sr(bcid_sr'high);
+            end if;
+        end if;
+    end process pBufferHeader;
+    
+
+    --==============================--
+    genOutput : for i in 0 to 2 - 1 generate
+    --==============================--
+                        
+        signal packet_stub_count, packet_stub_count_previous                  : unsigned(7 downto 0)                               := (others => '0');
+        signal packet_stub_counter_pointer                                    : integer                                            := 0;
+        signal packet_stub_count_done                                         : std_logic                                          := '0';
+
+    begin
+        --==============================--
+        pCountStubs : process(clk_p)
+        --==============================--
+        begin
+            if rising_edge(clk_p) then
+                if readout_reset = '1' then
+                    packet_stub_count <= (others => '0');
+                    packet_stub_count_previous <= packet_stub_count;
+                    packet_stub_counter_pointer <= 0;
+                    packet_stub_count_done <= '0';
+                else
+                    if packet_stub_count_done = '0' then
+                        if packet_stub_counter_pointer = (6 - 1) * cNumberOfCICs then
+                            packet_stub_count_done <= '1';
+                        end if;
+                        packet_stub_count <= packet_stub_count + unsigned(module_header_in((6*i) + packet_stub_counter_pointer).stub_count) + unsigned(module_header_in((6*i) + packet_stub_counter_pointer + 1).stub_count);
+                        packet_stub_counter_pointer <= packet_stub_counter_pointer + cNumberOfCICs;
+                    end if;
+                end if;
+                
+                header_out(i)(75 downto 0 ) <= header_word(75 downto 0);
+                header_out(i)(83 downto 76) <= std_logic_vector(packet_stub_count_previous);
+            end if;
+        end process pCountStubs;
+
+        header_out(i)(75 downto 0) <= header_word(75 downto 0);
+    end generate ; -- genOutput
+    
+
+end Behavioral;
diff --git a/common/firmware/hdl/mprocessor_constants.vhd b/common/firmware/hdl/mprocessor_constants.vhd
index 367eb099..00f1e166 100644
--- a/common/firmware/hdl/mprocessor_constants.vhd
+++ b/common/firmware/hdl/mprocessor_constants.vhd
@@ -7,6 +7,7 @@ use work.dtc_link_maps.all;
 package mprocessor_constants is
 
     type tHeaderStartArray is array(cNumberOfFEModules - 1 downto 0) of std_logic_vector(1 downto 0);
+    type tPayloadHeaderArray is array(2 - 1 downto 0) of std_logic_vector(127 downto 0);
 
     function convertSLVtoHeaderStartArray (input_vector : in std_logic_vector(2*cNumberOfFEModules - 1 downto 0)) return tHeaderStartArray;
     
diff --git a/top/firmware/hdl/emp_payload.vhd b/top/firmware/hdl/emp_payload.vhd
index 413cdb06..e034ed59 100644
--- a/top/firmware/hdl/emp_payload.vhd
+++ b/top/firmware/hdl/emp_payload.vhd
@@ -84,6 +84,8 @@ architecture rtl of emp_payload is
 
     signal orbit_counter                : unsigned(31 downto 0)                    := to_unsigned(0   , 32);
     signal bunch_counter                : unsigned(11 downto 0)                    := to_unsigned(3564, 12);
+    signal readout_reset                : std_logic_vector(cNumberOfMProcessors - 1 downto 0) := (others => '0');
+    signal payload_headers              : tPayloadHeaderArray                                 := (others => (others => '0'));
 
 
     -- Daqpath
@@ -385,8 +387,8 @@ begin
             --- Input Ports ---
             clk_p              => clk_p,
             links_in           => stubs(cNumberofInputLinks*i + (cNumberofInputLinks - 1) downto cNumberofInputLinks*i),
-            header_in          => header_array,
             header_start_array => convertSLVtoHeaderStartArray(header_start_array_buffered),
+            payload_header     => payload_headers(i),
             gbe_backpressure   => gbe_backpressure(i),
             srst               => srst,
             --- Output Ports ---
@@ -395,10 +397,28 @@ begin
             ipb_clk            => clk,
             ipb_rst            => rst,
             ipb_in             => ipb_to_channel,
-            ipb_out            => ipb_from_channel
+            ipb_out            => ipb_from_channel,
+            --- Debug Ports ---
+            debug_readout_reset => readout_reset(i)
         );
     end generate genMProcessors;
 
+    --==============================--
+    PayloadHeadeGeneratorInstance : entity work.PayloadHeaderGenerator
+    --==============================--
+    port map ( 
+        --- Input Ports ---
+        clk_p => clk_p,
+        reset => srst,
+        readout_reset => readout_reset(0),
+        header_start => header_start_array_buffered(0),
+        module_header_in => header_array,
+        user_bits => x"d451d007",
+        --- Ouput Ports ---
+        header_out => payload_headers
+    );
+    
+
 
     gbe_q <= eth_link_out;
     q(5) <= eth_link_out(0);
-- 
GitLab