From 91dd9bea38d25db2b8c9f5371817ea237a66f816 Mon Sep 17 00:00:00 2001
From: Hannes Sakulin <Hannes.Sakulin@cern.ch>
Date: Thu, 15 Nov 2018 15:32:13 +0100
Subject: [PATCH] make aligner work with orbit gaps of 1bx or shorter (part 3)

---
 .../firmware/hdl/infra/bx_aware_aligner.vhd   | 136 ++++++------------
 .../firmware/sim/tb_align_fill_autorelign.vhd |   2 +-
 2 files changed, 44 insertions(+), 94 deletions(-)

diff --git a/scouting-board/firmware/hdl/infra/bx_aware_aligner.vhd b/scouting-board/firmware/hdl/infra/bx_aware_aligner.vhd
index fb1d3dc..08729fb 100644
--- a/scouting-board/firmware/hdl/infra/bx_aware_aligner.vhd
+++ b/scouting-board/firmware/hdl/infra/bx_aware_aligner.vhd
@@ -163,10 +163,6 @@ begin
             all_streams_not_valid_d <= '1';  -- set this to 1 so that we don't detect an orgbit gap start if the reset is released in the orbit gap  
         else
             if (clk_wr'event and clk_wr = '1') then
-                --                 rst_d <= rst; 
-                --                 if rst='1' and rst_d = '0' then
-                --                      ResetState <= WAIT_ORBIT_END;              
-                --                 end if;
 
                 not_valid := true;
                 for i in NSTREAMS - 1 downto 0 loop
@@ -189,8 +185,6 @@ begin
                             ResetState      <= R1;
                             waiting_orbit_end <= '0';
                         end if;
---                    when B1   => ResetState      <= B2;
---                    when B2   => ResetState      <= R1; reset_all_fifos <= '1';
                     when R1 => ResetState <= R2;
                     when R2 => ResetState <= R3;
                     when R3 => ResetState <= A1; reset_all_fifos <= '0';
@@ -214,62 +208,6 @@ begin
         end if;
     end process reset_logic;
 
-
-    --
-    -- FIFO reset logic at end of orbit
-    --
-    -- generates an automatic four clocks long reset pulse when all streams had no valid for 
-    -- NCLOCKS_GAP clocks.
-    --
---     detect_orbit_end : process (clk_wr) is
---        variable i : integer;
---        variable j : integer;
---        variable not_valid : boolean;
---        variable whole_window_not_valid : boolean;
---     begin
---         if clk_wr'event and clk_wr='1' then
---               not_valid := true;
---               for i in NSTREAMS - 1 downto 0 loop
---                    if enable(i) = '1' AND d(i).valid = '1' then
---                        not_valid := false;
---                    end if;
---               end loop;
---               if (not_valid) then 
---                    all_streams_not_valid(NCLOCKS_GAP-1) <= '1';
---               else
---                    all_streams_not_valid(NCLOCKS_GAP-1) <= '0';
---               end if;             
-
---               for j in NCLOCKS_GAP -2 downto 0 loop
---                     all_streams_not_valid(j) <=  all_streams_not_valid(j+1); 
---               end loop;
-
---                whole_window_not_valid := all_streams_not_valid = (NCLOCKS_GAP - 1 downto 0 => '1');
-
---                if whole_window_not_valid then
---                    whole_window_not_valid_d1 <= '1';
---                else
---                    whole_window_not_valid_d1 <= '0';
---                end if;
-
---                    whole_window_not_valid_d4 <= whole_window_not_valid_d3;
---                    whole_window_not_valid_d3 <= whole_window_not_valid_d2;
---                    whole_window_not_valid_d2 <= whole_window_not_valid_d1;
-
---                if (whole_window_not_valid AND 
---                            (whole_window_not_valid_d1 = '0' OR
---                             whole_window_not_valid_d2 = '0' OR
---                             whole_window_not_valid_d3 = '0' OR
---                             whole_window_not_valid_d4 = '0')) then
---                    reset_all_fifos <= '1';
---                else 
---                    reset_all_fifos <= '0';                
---                end if;
-
---         end if;    
---     end process detect_orbit_end; 
-
-
      sync_reset_read_sm_to_clk_axi : entity work.synchroniser
         port map(
             clk => clk_rd,
@@ -302,16 +240,18 @@ begin
         else
             if clk_rd'event and clk_rd = '1' then
 
+                    all_last := true;
+                    for i in q_fifo'range loop
+                      if q_fifo(i)(32)='0' then
+                          all_last := false;
+                      end if;   
+                    end loop; 
+
                     LastState <= State;
-                    q_ctrl <= ctrl_i;
 
                     case State is
 
                         when GAP =>
-                            ctrl_i.valid    <= '0';
-                            ctrl_i.strobe   <= '0';
-                            ctrl_i.bx_start <= '0';
-                            ctrl_i.last     <= '0';
                             if (all_fifos_contain_bx = '1') then
                                 State      <= D6;
                                 fifo_rd_en <= '1';
@@ -320,23 +260,15 @@ begin
                             end if;
 
                         when IDLE =>
-                            ctrl_i.valid  <= '1';
-                            ctrl_i.strobe <= '0';
-                            ctrl_i.last   <= '0';
-
                             if (all_fifos_contain_bx = '1') then
                                 State      <= D6;
                                 fifo_rd_en <= '1';
                             end if;
 
                         when D6 =>
-                            ctrl_i.bx_start <= '1';
-                            ctrl_i.valid    <= '1';
-                            ctrl_i.strobe   <= '1';
                             State           <= D5;
 
                         when D5 =>
-                            ctrl_i.bx_start <= '0';
                             State           <= D4;
 
                         when D4 =>
@@ -361,25 +293,10 @@ begin
                                 State <= D6;
                                 fifo_rd_en <= '1';
                             else
-                                all_last := true;
-                                for i in q_fifo'range loop
-                                  if q_fifo(i)(32)='0' then
-                                      all_last := false;
-                                  end if;   
-                                end loop; 
-                                if all_last then -- fifo_almost_empty = (NSTREAMS - 1 downto 0 => '1') then
+                                if all_last then 
                                     State       <= GAP;
-                                    q_ctrl.last <= '1';
-                                    ctrl_i.valid <= '0';
-                                    ctrl_i.strobe <= '0';
-                                    ctrl_i.bx_start <= '0';
-                                    ctrl_i.last <= '0';
                                 else
                                     State         <= IDLE;
-                                    ctrl_i.valid  <= '1';
-                                    ctrl_i.strobe <= '0';
-                                    ctrl_i.bx_start <= '0';
-                                    ctrl_i.last <= '0';
                                 end if;
                           end if;
                        
@@ -389,8 +306,41 @@ begin
                     --
                     -- Multiplexer and last flip flop
                     --
-
-                        
+                    case LastState is
+                        when D6 =>         q_ctrl.valid     <= '1';                        
+                                           q_ctrl.strobe    <= '1';  
+                                           q_ctrl.bx_start  <= '1';  
+                                           q_ctrl.last      <= '0';
+                        when D5 to D2 =>   q_ctrl.valid     <= '1';
+                                           q_ctrl.strobe    <= '1';
+                                           q_ctrl.bx_start  <= '0';
+                                           q_ctrl.last      <= '0';
+                        when D1 =>         q_ctrl.valid     <= '1';
+                                           q_ctrl.strobe    <= '1';
+                                           q_ctrl.bx_start  <= '0';
+                                           if (all_last) then
+                                              q_ctrl.last      <= '1';
+                                           else    
+                                              q_ctrl.last      <= '0';
+                                           end if;
+                        when START_GAP_OR_IDLE =>
+                                           if (State = GAP) then
+                                             q_ctrl.valid <= '0';
+                                           else
+                                             q_ctrl.valid <= '1';
+                                           end if;
+                                           q_ctrl.strobe   <= '0';
+                                           q_ctrl.bx_start <= '0';
+                                           q_ctrl.last <= '0';
+                        when GAP =>        q_ctrl.valid     <= '0';
+                                           q_ctrl.strobe    <= '0';
+                                           q_ctrl.bx_start  <= '0';
+                                           q_ctrl.last      <= '0';
+                        when IDLE =>       q_ctrl.valid     <= '1';
+                                           q_ctrl.strobe    <= '0';
+                                           q_ctrl.bx_start  <= '0';
+                                           q_ctrl.last      <= '0';
+                     end case;    
 
                     if LastState = GAP or (LastState = START_GAP_OR_IDLE and State = GAP) then
                         q <= (others => AWORD_NULL);
diff --git a/scouting-board/firmware/sim/tb_align_fill_autorelign.vhd b/scouting-board/firmware/sim/tb_align_fill_autorelign.vhd
index bd32646..8ed6aa6 100644
--- a/scouting-board/firmware/sim/tb_align_fill_autorelign.vhd
+++ b/scouting-board/firmware/sim/tb_align_fill_autorelign.vhd
@@ -167,7 +167,7 @@ begin
       clk <= '1';
       wait for t_hold;
        
-      ReadFrame(f, frame);
+      ReadFrame(f, NSTREAMS, frame);
       d <= frame;
 
 --       for j in 0 to NSTREAMS -1 loop
-- 
GitLab