From 454c626fb664d9a14687d866812892559b007564 Mon Sep 17 00:00:00 2001
From: Kirika Uchida <kirika.uchida@gmail.com>
Date: Mon, 4 Sep 2023 20:22:14 +0200
Subject: [PATCH] gbe is connected to ecal data

---
 common/firmware/hdl/EcalDataProcessor.vhd | 68 +++++++++++++++++++----
 top/firmware/hdl/emp_payload.vhd          |  2 +
 top/firmware/hdl/link_maps.vhd            |  2 +-
 3 files changed, 60 insertions(+), 12 deletions(-)

diff --git a/common/firmware/hdl/EcalDataProcessor.vhd b/common/firmware/hdl/EcalDataProcessor.vhd
index a4f73633..bb6e1d4a 100644
--- a/common/firmware/hdl/EcalDataProcessor.vhd
+++ b/common/firmware/hdl/EcalDataProcessor.vhd
@@ -16,6 +16,7 @@ port (
         clk_p            : in  std_logic;
         clk40            : in  std_logic;
         data_in          : in tDaqEcalLinkDataArray;
+        gbe_backpressure : in std_logic;
         --- Output Ports ---
         data_out         : out ldata(cNumberOfEcalOutputLinks - 1 downto 0);
        --- IPBus Ports ---
@@ -72,6 +73,11 @@ architecture rtl of EcalDataProcessor is
   signal raddr_valid_i     : std_logic; 
   
   signal trig_lat_offset   : std_logic_vector(8 downto 0);
+
+  signal data_out_s        :  lword;
+
+  type ostate_type is (wait_start, wait_last, wait_bpoff); -- This state machine does not allow a single frame packet. The packet length >= 2.
+  signal ostate            : ostate_type;
    
 begin
 
@@ -194,6 +200,46 @@ begin
     doutb => trig_ram_doutb
   ); 
   
+  bp: process(clk_p)
+  begin
+        if reset = '1' then
+          data_out(0).data  <= (others => '0');
+          data_out(0).valid <= '0';
+          data_out(0).start <= '0';
+          data_out(0).strobe <= '0';
+          ostate <= wait_start;
+        elsif rising_edge(clk_p) then
+
+          data_out(0).data  <= data_out_s.data;
+          data_out(0).valid <= '0';
+          data_out(0).start <= '0';
+          data_out(0).strobe <= '0';
+          case ostate is
+            when wait_start =>
+              if data_out_s.start = '1' then
+                data_out(0).start <= data_out_s.start;
+                data_out(0).valid <= data_out_s.valid;
+                ostate <= wait_last;
+              end if;
+            when wait_last =>
+                data_out(0).valid <= data_out_s.valid;
+                if data_out_s.last = '1' then
+                  data_out(0).last <= data_out_s.last;
+                  data_out(0).strobe <= data_out_s.strobe;
+                  if gbe_backpressure = '0' then 
+                    ostate <= wait_start; 
+                  else
+                    ostate <= wait_bpoff;
+                  end if;
+                end if;
+            when wait_bpoff =>
+              if gbe_backpressure = '0' then
+                ostate <= wait_start;
+              end if;
+          end case;
+
+        end if;
+  end process;
 
   ram_rw: process(clk_p)
     variable data_ready : boolean := false;
@@ -285,24 +331,24 @@ begin
             end if;
           end if;  
  
-          data_out(0).data  <= (others => '0');
-          data_out(0).valid <= '0';
-          data_out(0).start <= '0';
-          data_out(0).strobe <= '0';
+          data_out_s.data  <= (others => '0');
+          data_out_s.valid <= '0';
+          data_out_s.start <= '0';
+          data_out_s.strobe <= '0';
           if trig_ram_enb = '1' and trig_ram_enb_p(1) = '1' then
  
             data_ram_addrb <= std_logic_vector(to_unsigned(raddr,9));
             trig_ram_addrb <= std_logic_vector(to_unsigned(raddr,9)(8 downto 3));
             
-            data_out(0).data  <= data_ram_doutb(63 downto 0);
+            data_out_s.data  <= data_ram_doutb(63 downto 0);
             if data_ram_doutb(bit_start) = '1' then
-              data_out(0).data(63 downto 32) <= trig;
+              data_out_s.data(63 downto 32) <= trig;
             end if;
- 
-            data_out(0).valid <= trig_ram_doutb(0) and data_ram_doutb(bit_valid);           
-            data_out(0).start <= trig_ram_doutb(31) and data_ram_doutb(bit_start);
-            data_out(0).last  <= trig_ram_doutb(30) and data_ram_doutb(bit_last);
-            data_out(0).strobe <= trig_ram_doutb(30) and data_ram_doutb(bit_last);         
+
+            data_out_s.valid <= trig_ram_doutb(0) and data_ram_doutb(bit_valid);           
+            data_out_s.start <= trig_ram_doutb(31) and data_ram_doutb(bit_start) and gbe_backpressure;
+            data_out_s.last  <= trig_ram_doutb(30) and data_ram_doutb(bit_last);
+            data_out_s.strobe <= trig_ram_doutb(30) and data_ram_doutb(bit_last);         
           end if;
           
           -- data ram write address counters
diff --git a/top/firmware/hdl/emp_payload.vhd b/top/firmware/hdl/emp_payload.vhd
index 92b26903..2f015b65 100644
--- a/top/firmware/hdl/emp_payload.vhd
+++ b/top/firmware/hdl/emp_payload.vhd
@@ -360,6 +360,7 @@ begin
         clk_p            => clk_p,
         clk40            => clk40,
         data_in          => ecal_link_data,
+				backpressure        => backpressure(2),
         --- Output Ports ---
         data_out         => ecal_data,
         --- IPBus Ports ---
@@ -374,6 +375,7 @@ begin
     q(cECALOutputLink).last   <= ecal_data(0).last;
     q(cECALOutputLink).data   <= ecal_data(0).data;
     q(cECALOutputLink).strobe <= ecal_data(0).strobe;
+		gbe_q(2) <= ecal_data(0);
 
     --==============================--
     -- Link Aggregation and Combination
diff --git a/top/firmware/hdl/link_maps.vhd b/top/firmware/hdl/link_maps.vhd
index 8134113f..215bf5a3 100644
--- a/top/firmware/hdl/link_maps.vhd
+++ b/top/firmware/hdl/link_maps.vhd
@@ -30,7 +30,7 @@ package dtc_link_maps is
     constant cECALInputLinkMap     : tECALInputLinkMap := (12, 13, 14, 15);
     -- type tECALOutputLinkMap is array(0 to cNumberOfEcalOutputLinks - 1) of integer;
     -- constant cECALOutputLinkMap     : tECALOutputLinkMap := (28);
-    constant cECALOutputLink       : integer := 0;
+    constant cECALOutputLink       : integer := 7;
     
     type tDTCOutputLinkMap is array(0 to cNumberOfOutputLinks - 1) of integer;
     constant cDTCOutputLinkMap    : tDTCOutputLinkMap := (28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39);
-- 
GitLab