eFEX firmware  1.7.3
ATLAS l1-calo - electron and tau feature extraction firmware for eFEX boards

Back to eFEX documentation
packet_fifo.vhd
Go to the documentation of this file.
1 
8 
9 library IEEE;
10 use IEEE.STD_LOGIC_1164.ALL;
11 USE IEEE.NUMERIC_STD.ALL;
12 
14 entity packet_fifo is
15  Generic (
17  DATA_WIDTH: positive := 64;
19  constant BUFWIDTH: positive := 4
20  );
21  Port (
23  clk : in STD_LOGIC;
25  rst_clk : in STD_LOGIC;
27  in_data : in STD_LOGIC_VECTOR(DATA_WIDTH-1 downto 0);
29  in_valid : in STD_LOGIC;
31  in_last : in STD_LOGIC;
33  in_pause : out STD_LOGIC;
35  out_ready : in STD_LOGIC;
37  out_data : out STD_LOGIC_VECTOR(DATA_WIDTH-1 downto 0);
39  out_valid : out STD_LOGIC;
41  out_last : out STD_LOGIC;
43  out_error : out STD_LOGIC
44  );
45 end packet_fifo;
46 
48 architecture Behavioral of packet_fifo is
49 signal write_ptr, read_ptr: unsigned(BUFWIDTH-1 downto 0);
50 signal fifo_filled_sig, fifo_empty_sig, running_sig, packet_ready_sig: STD_LOGIC;
51 signal packet_change_sig: STD_LOGIC_VECTOR(1 downto 0);
52 begin
53 
54  in_pause <= fifo_filled_sig;
55  out_valid <= running_sig;
56 
57  -- Memory Pointer Process
58  fifo_proc : process (clk)
59  type FIFO_Memory is array(0 to 2**BUFWIDTH - 1) of STD_LOGIC_VECTOR(DATA_WIDTH downto 0);
60  variable Memory : FIFO_Memory;
61  variable DataOut: STD_LOGIC_VECTOR(DATA_WIDTH-1 downto 0);
62  variable last, packet_up, packet_down, error : STD_LOGIC;
63  variable Head, Tail : natural range 0 to 2**BUFWIDTH - 1;
64  variable Watchdog : unsigned(BUFWIDTH downto 0);
65  variable Fatal, Running : STD_LOGIC;
66  variable packet_change: STD_LOGIC_VECTOR(1 downto 0);
67  begin
68  if rising_edge(clk) then
69  packet_down := '0';
70  packet_up := '0';
71  if rst_clk = '1' then
72  Head := 0;
73  Tail := 0;
74  Watchdog := (Others => '0');
75  Running := '0';
76  Fatal := '0';
77  else
78  if ((out_ready = '1') and (Running = '1')) then
79  -- Update Tail pointer as needed
80  if (Tail = 2**BUFWIDTH - 1) then
81  Tail := 0;
82  else
83  Tail := Tail + 1;
84  end if;
85 
86  -- And stop running if out_last was sent
87  if (last = '1') then
88  Running := '0';
89  packet_down := '1';
90  if Fatal = '1' then
91  Tail := Head;
92  Fatal := '0';
93  end if;
94  end if;
95  Watchdog := Watchdog + 1;
96  end if;
97 
98  if (in_valid = '1') then
99  -- Write Data to Memory
100  Memory(Head) := in_last & in_data;
101  if (in_last = '1') then
102  packet_up := '1';
103  end if;
104 
105  -- Increment Head pointer as needed
106  if (Head = 2**BUFWIDTH - 1) then
107  Head := 0;
108  else
109  Head := Head + 1;
110  end if;
111  Watchdog := (Others => '0');
112  end if;
113 
114  end if;
115 
116  -- Start running when FIFO is half full or contains a full packet
117  if (fifo_filled_sig = '1') or (packet_ready_sig = '1') then
118  Running := '1';
119  end if;
120 
121  If Running = '1' then
122  -- Die gracefully if the FIFO runs dry...
123  If (fifo_empty_sig = '1') or (Watchdog(BUFWIDTH) = '1') then
124  Fatal := '1';
125  end if;
126  If Fatal = '1' then
127  DataOut := (Others => '0');
128  last := '1';
129  error := '1';
130  else
131  -- Update data to be output
132  DataOut := Memory(Tail)(DATA_WIDTH-1 downto 0);
133  last := Memory(Tail)(DATA_WIDTH);
134  error := '0';
135  end if;
136  else
137  DataOut := (Others => '0');
138  last := '0';
139  error := '0';
140  end if;
141 
142  if (Fatal = '1') then
143  packet_change := "11";
144  elsif (packet_up = packet_down) then
145  packet_change := "00";
146  else
147  packet_change := packet_up & packet_down;
148  end if;
149 
150  write_ptr <= to_unsigned(Head, BUFWIDTH)
151 -- pragma translate_off
152  after 2 ns
153 -- pragma translate_on
154  ;
155  read_ptr <= to_unsigned(Tail, BUFWIDTH)
156 -- pragma translate_off
157  after 2 ns
158 -- pragma translate_on
159  ;
160  running_sig <= Running
161 -- pragma translate_off
162  after 2 ns
163 -- pragma translate_on
164  ;
165  out_data <= DataOut
166 -- pragma translate_off
167  after 2 ns
168 -- pragma translate_on
169  ;
170  out_error <= error
171 -- pragma translate_off
172  after 2 ns
173 -- pragma translate_on
174  ;
175  out_last <= last
176 -- pragma translate_off
177  after 2 ns
178 -- pragma translate_on
179  ;
180  packet_change_sig <= packet_change
181 -- pragma translate_off
182  after 2 ns
183 -- pragma translate_on
184  ;
185 
186  end if;
187  end process fifo_proc;
188 
189  packet_count_proc : process(clk)
190  variable npacket: unsigned(BUFWIDTH-1 downto 0);
191  constant zeros: unsigned(BUFWIDTH-1 downto 0) := (Others => '0');
192  variable packet_ready: std_logic;
193  begin
194  if rising_edge(clk) then
195  if (rst_clk = '1') then
196  npacket := (Others => '0');
197  else
198  Case packet_change_sig is
199  When "11" =>
200  npacket := (Others => '0');
201  When "10" =>
202  npacket := npacket + 1;
203  When "01" =>
204  if (npacket /= zeros) then
205  npacket := npacket - 1;
206  end if;
207  When Others =>
208  null;
209  End Case;
210  end if;
211  if (npacket /= zeros) and (running_sig = '0') then
212  packet_ready := '1';
213  else
214  packet_ready := '0';
215  end if;
216  packet_ready_sig <= packet_ready
217 -- pragma translate_off
218  after 2 ns
219 -- pragma translate_on
220  ;
221  end if;
222  end process packet_count_proc;
223 
224  fill_level_proc : process(clk)
225  variable FillLevel, Head, Tail: unsigned(BUFWIDTH downto 0);
226  variable Empty: std_logic;
227  begin
228  if rising_edge(clk) then
229  if rst_clk = '1' then
230  FillLevel := (Others => '0');
231  Empty := '0';
232  else
233  if (write_ptr = read_ptr) then
234  Empty := '1';
235  else
236  Empty := '0';
237  end if;
238  Head := "1" & write_ptr;
239  Tail := "0" & read_ptr;
240  FillLevel := Head - Tail;
241  end if;
242  fifo_filled_sig <= FillLevel(BUFWIDTH-1)
243 -- pragma translate_off
244  after 2 ns
245 -- pragma translate_on
246  ;
247  fifo_empty_sig <= Empty
248 -- pragma translate_off
249  after 2 ns
250 -- pragma translate_on
251  ;
252  end if;
253  end process fill_level_proc;
254 
255 end Behavioral;
Optimised RAM-based single clock packet FIFO.
Definition: packet_fifo.vhd:48
Optimised RAM-based single clock packet FIFO.
Definition: packet_fifo.vhd:14
out out_data STD_LOGIC_VECTOR( DATA_WIDTH- 1 downto 0)
AXI stream output.
Definition: packet_fifo.vhd:37
in in_data STD_LOGIC_VECTOR( DATA_WIDTH- 1 downto 0)
AXI stream input.
Definition: packet_fifo.vhd:27
out in_pause STD_LOGIC
AXI stream input pause request.
Definition: packet_fifo.vhd:33
out out_error STD_LOGIC
AXI stream output error (asserted on last)
Definition: packet_fifo.vhd:44
in rst_clk STD_LOGIC
Synchronous reset.
Definition: packet_fifo.vhd:25
in clk STD_LOGIC
Clock.
Definition: packet_fifo.vhd:23
DATA_WIDTH positive := 64
Width of data for RAM.
Definition: packet_fifo.vhd:17
out out_valid STD_LOGIC
AXI stream output valid.
Definition: packet_fifo.vhd:39
in in_last STD_LOGIC
AXI stream input last.
Definition: packet_fifo.vhd:31
in in_valid STD_LOGIC
AXI stream input valid.
Definition: packet_fifo.vhd:29
in out_ready STD_LOGIC
AXI stream output ready.
Definition: packet_fifo.vhd:35
out out_last STD_LOGIC
AXI stream output last.
Definition: packet_fifo.vhd:41
BUFWIDTH positive := 4
Width of address bus for buffer, i.e. array (0 to 2**BUFWIDTH - 1)
Definition: packet_fifo.vhd:20