blob: 92e72a970c5d3ac57dee88f3188aac9e37d85a83 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
-- A simple type-generic stream-style synchronous FIFO
-- may not be 100% valid VHDL code, contact ktbarrett on gitter
-- non-generic version does synthesize correctly
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity generic_SFIFO is
generic (
type T;
MIN_DEPTH : natural);
port (
clk : in std_ulogic;
rst : in std_ulogic;
data_in : in T;
valid_in : in std_ulogic;
ready_out : out std_ulogic; -- If true, can accept data
data_out : out T;
valid_out : out std_ulogic;
ready_in : in std_ulogic); -- To consume data
end entity generic_SFIFO;
architecture rtl of generic_SFIFO is
function clog2 (n: natural) return natural is
variable i : natural;
variable test : natural;
begin
test := 1;
i := 0;
while (test < n) loop
i := i + 1;
test := test * 2;
end loop;
return i;
end function clog2;
constant ptr_size : natural := clog2(MIN_DEPTH);
constant depth : natural := 2 ** ptr_size;
signal rd_ptr : unsigned(ptr_size downto 0);
signal wr_ptr : unsigned(ptr_size downto 0);
type ram_type is array(0 to depth - 1) of T;
signal ram : ram_type;
begin
fifo_proc : process (clk) is
variable next_wr_ptr : wr_ptr'subtype;
variable next_rd_ptr : rd_ptr'subtype;
begin
if (rising_edge(clk)) then
if (rst /= '0') then
rd_ptr <= (others => '0');
wr_ptr <= (others => '0');
ready_out <= '0';
valid_out <= '0';
else
next_wr_ptr := wr_ptr;
next_rd_ptr := rd_ptr;
if ((valid_in='1') and (ready_out='1')) then
ram(to_integer(wr_ptr(wr_ptr'left - 1 downto 0))) <= data_in;
next_wr_ptr := wr_ptr + 1;
end if;
if ((valid_out='1') and (ready_in='1')) then
next_rd_ptr := rd_ptr + 1;
end if;
ready_out <= '0' when
(next_wr_ptr(next_wr_ptr'left) /= next_rd_ptr(next_rd_ptr'left)) and
(next_wr_ptr(next_wr_ptr'left - 1 downto 0) = next_rd_ptr(next_rd_ptr'left - 1 downto 0)) else
'1';
valid_out <= '0' when
(wr_ptr(wr_ptr'left) = next_rd_ptr(next_rd_ptr'left)) and
(wr_ptr(wr_ptr'left - 1 downto 0) = next_rd_ptr(next_rd_ptr'left - 1 downto 0)) else
'1';
wr_ptr <= next_wr_ptr;
rd_ptr <= next_rd_ptr;
data_out <= ram(to_integer(next_rd_ptr(next_rd_ptr'left - 1 downto 0)));
end if;
end if;
end process fifo_proc;
end architecture rtl;
|