12 use IEEE.STD_LOGIC_1164.
ALL;
13 USE IEEE.NUMERIC_STD.
ALL;
58 type FIFO_Memory is array (0 to 2**BUFWIDTH - 1) of STD_LOGIC_VECTOR(DATA_WIDTH downto 0);
59 signal Memory : FIFO_Memory;
60 attribute ram_style : string;
61 attribute ram_style of Memory : signal is "block";
63 signal fifo_fill_level_sig, write_ptr, read_ptr, new_read_ptr, read_addr, read_reg, npacket_sig : unsigned(BUFWIDTH-1 downto 0);
64 signal mem_out_reg, mem_out_data: STD_LOGIC_VECTOR(DATA_WIDTH downto 0);
65 signal in_data_reg: STD_LOGIC_VECTOR(DATA_WIDTH-1 downto 0);
66 signal rst_reg, in_valid_reg, in_last_reg, out_valid_sig, error_sig, input_error_sig, reset_ptr, running_sig, input_ok_sig: STD_LOGIC;
67 signal packet_change_sig: STD_LOGIC_VECTOR(1 downto 0);
73 when out_valid_sig = '1' else (others => '0')
78 when out_valid_sig = '1' else '0'
89 input_reg:
process (
clk)
91 if rising_edge(clk) then
113 end process input_reg;
115 input_block:
process (
clk)
117 if rising_edge(clk) then
118 if (in_valid_reg = '1') and (input_ok_sig = '1') then
120 Memory(to_integer(write_ptr)) <= (in_last_reg or input_error_sig) & in_data_reg
127 end process input_block;
130 input_error_block:
process (
clk)
131 variable Watchdog : unsigned(MAXWIDTH downto 0);
132 variable input_error, input_ok : STD_LOGIC;
134 if rising_edge(clk) then
135 if rst_reg = '1' then
136 Watchdog := (Others => '0');
141 if (in_valid_reg = '1') and (in_last_reg = '1') then
143 elsif (input_error_sig = '1') then
149 Watchdog := (Others => '0');
151 Watchdog := Watchdog + 1;
153 if (Watchdog(MAXWIDTH) = '1') and (input_ok = '1') then
158 input_error_sig <= input_error
163 input_ok_sig <= input_ok
169 end process input_error_block;
171 output_block:
process (
clk)
173 if rising_edge(clk) then
174 mem_out_reg <= Memory(to_integer(read_ptr))
180 end process output_block;
182 output_reg:
process (
clk)
184 if rising_edge(clk) then
185 mem_out_data <= mem_out_reg
191 end process output_reg;
194 fifo_proc :
process (
clk)
195 variable Watchdog : unsigned(MAXWIDTH downto 0);
196 variable error, packet_up, packet_down, Running : STD_LOGIC;
197 variable packet_change: STD_LOGIC_VECTOR(1 downto 0);
198 variable valid, reset_buf: std_logic_vector(2 downto 0);
200 if rising_edge(clk) then
203 if rst_reg = '1' then
204 Watchdog := (Others => '0');
206 reset_buf := (Others => '0');
210 if (in_valid_reg = '1') and (input_ok_sig = '1') then
211 if (in_last_reg = '1') or (input_error_sig = '1') then
216 if (Running = '1') then
218 if ((error = '1') or (mem_out_data(DATA_WIDTH) = '1')) and (out_valid_sig = '1') then
221 reset_buf := (Others => '1');
222 elsif (out_valid_sig = '1') then
223 Watchdog := Watchdog + 1;
225 elsif (npacket_sig /= 0) and (reset_buf(2) = '0') and (out_pause = '0') then
227 Watchdog := (Others => '0');
229 reset_buf := reset_buf(1 downto 0) & '0';
234 If (Running = '1') then
235 valid := valid(1 downto 0) & not out_pause;
237 If (fifo_fill_level_sig = 0) or (Watchdog(MAXWIDTH) = '1') then
241 valid := (Others => '0');
244 if (Running = '0') and (error = '1') then
245 packet_change := "11";
247 elsif (packet_up = packet_down) then
248 packet_change := "00";
250 packet_change := packet_up & packet_down;
253 running_sig <= Running
263 reset_ptr <= reset_buf(0)
268 out_valid_sig <= valid(2)
273 packet_change_sig <= packet_change
279 end process fifo_proc;
281 write_pointer_proc :
process(
clk)
282 variable Head, NextHead : unsigned(BUFWIDTH downto 0);
284 if rising_edge(clk) then
285 if (packet_change_sig = "11") then
286 NextHead := (Others => '0');
288 Head := "0" & write_ptr;
289 if (in_valid_reg = '1') and (input_ok_sig = '1') then
290 NextHead := Head + 1;
295 write_ptr <= NextHead(BUFWIDTH-1 downto 0)
301 end process write_pointer_proc;
303 read_pointer_proc :
process(
clk)
304 variable Tail, NextTail, ThisAddr, NextAddr : unsigned(BUFWIDTH downto 0);
306 if rising_edge(clk) then
307 if (packet_change_sig = "11") then
308 NextTail := (Others => '0');
310 if (reset_ptr = '1') then
311 Tail := "0" & new_read_ptr;
313 Tail := "0" & read_ptr;
315 if ((running_sig = '1') and (out_pause = '0')) then
316 NextTail := Tail + 1;
320 ThisAddr := "0" & read_addr;
321 NextAddr := ThisAddr + 1;
323 read_ptr <= NextTail(BUFWIDTH-1 downto 0)
333 read_addr <= read_reg
338 new_read_ptr <= NextAddr(BUFWIDTH-1 downto 0)
344 end process read_pointer_proc;
346 packet_count_proc :
process(
clk)
347 variable npacket : unsigned(BUFWIDTH-1 downto 0);
348 constant zeros
: unsigned(BUFWIDTH-1 downto 0) := (Others => '0');
350 if rising_edge(clk) then
351 Case packet_change_sig is
353 npacket := (Others => '0');
355 npacket := npacket + 1;
357 if (npacket /= zeros) then
358 npacket := npacket - 1;
363 npacket_sig <= npacket
369 end process packet_count_proc;
371 fill_level_proc :
process(
clk)
372 variable FillLevel, Head, Tail : unsigned(BUFWIDTH downto 0);
374 if rising_edge(clk) then
375 if rst_reg = '1' then
376 FillLevel := (Others => '0');
377 Tail := (Others => '0');
379 Head := "1" & write_ptr;
380 if (running_sig = '1') then
381 Tail := "0" & read_addr;
382 elsif (reset_ptr = '1') then
383 Tail := "0" & new_read_ptr;
385 FillLevel := Head - Tail;
387 fifo_fill_level_sig <= FillLevel(BUFWIDTH-1 downto 0)
393 end process fill_level_proc;
Optimised RAM-based single clock packet FIFO.
Optimised RAM-based single clock packet FIFO.
out out_data STD_LOGIC_VECTOR( DATA_WIDTH- 1 downto 0)
AXI stream output.
in in_data STD_LOGIC_VECTOR( DATA_WIDTH- 1 downto 0)
AXI stream input.
MAXWIDTH positive := 5
Parameter for maximum packet size (2**MAXWIDTH - 1) on input or output before trigger reset mechanism...
out out_error STD_LOGIC
AXI stream output error (asserted on last)
in rst_clk STD_LOGIC
Synchronous reset.
out packet_count STD_LOGIC_VECTOR( 15 downto 0)
Number of packets stored in the FIFO.
DATA_WIDTH positive := 64
Width of data for RAM.
in out_pause STD_LOGIC
AXI stream output pause request.
out out_valid STD_LOGIC
AXI stream output valid.
in in_last STD_LOGIC
AXI stream input last.
in in_valid STD_LOGIC
AXI stream input valid.
out fifo_fill_level STD_LOGIC_VECTOR( 15 downto 0)
Number of words stored in the FIFO.
BUFWIDTH positive := 10
Width of address bus for RAM, i.e. array (0 to 2**BUFWIDTH - 1)
out out_last STD_LOGIC
AXI stream output last.
out in_error STD_LOGIC
AXI stream input error.