1 -------------------------------------------------------------------------------
2 -- Filename: fifo_rbu.vhd
3 --
4 -- Description:
5 -- A small-to-medium depth FIFO with optional capability to back up and reread data.
6 -- For data storage, the SRL elements native to the target FGPA family are used.
7 -- If the FIFO depth exceeds the available depth of the SRL elements, then SRLs are
8 -- cascaded and MUXFN elements are used to select the output of the appropriate SRL stage.
9 --
10 -- Features:
11 -- Width and depth are arbitrary, but each doubling of depth, starting from the native SRL depth,
12 -- adds a level of MUXFN. Generally, in performance-oriented applications,
13 -- the fifo depth may need to be limited to not exceed the SRL cascade depth supported
14 -- by local fast interconnect or the number of MUXFN levels. However, deeper fifos will correctly build.
15 --
16 -- Commands: read, write, and reread n.
17 --
18 -- Flags: empty and full.
19 --
20 -- The reread n command (executed by applying a non-zero value, n,
21 -- to signal Num_To_Reread for one clock period) allows n previously read elements
22 -- to be restored to the FIFO, limited, however, to the number of elements that
23 -- have not been overwritten.
24 --
25 -- (It is the user's responsibility to assure that the elements being restored
26 -- are actually in the FIFO storage; once the depth of the FIFO has been written,
27 -- the maximum number that can be restored is equal to the vacancy.)
28 -- The reread capability does not cost extra LUTs or FFs.
29 --
30 -- Commands may be asserted simultaneously. However, if read and reread n are asserted
31 -- simultaneously, only the read is carried out.
32 --
33 -- Overflow and underflow are detected and latched until Reset.
34 --
35 -- The state of the FIFO is undefined during status of underflow or overflow.
36 --
37 -- Underflow can occur only by reading the FIFO when empty.
38 --
39 -- Overflow can occur either from a write, a reread n, or a combination of both
40 -- that would result in more elements occupying the FIFO that its C_DEPTH.
41 --
42 -- Any of the signals FIFO_Full, Underflow, or Overflow
43 -- left unconnected can be expected to be trimmed.
44 --
45 -- The Addr output is always one less than the current occupancy
46 -- when the FIFO is non-empty, and is all ones when FIFO is empty.
47 -- Therefore, the value <FIFO_Empty, Addr> as a signed value,
48 -- is one less than the current occupancy.
49 --
50 -- <'1', "1111" > => -1 + 1 => 0 : FIFO is empty.
51 --
52 -- <'0', "0000" > => 0 + 1 => 1 : FIFO has 1 data
53 -- <'0', "1111" > => 15 + 1 => 16 : FIFO has 16 data
54 --
55 -- <'0', "0000" > => 0 + 1 => 1 : FIFO has 1 data
56 -- <'1', "1111" > => -1 + 1 => 0 : FIFO is empty.
57 --
58 -- This information can be used to generate additional flags, if needed.
59 --
60 ----------------------------------------------------------------------------------
61 library IEEE;
62 use IEEE.STD_LOGIC_1164.all;
63
64 -- Uncomment the following library declaration if using
65 -- arithmetic functions with Signed or Unsigned values
66 use IEEE.NUMERIC_STD.all;
67
68 -- Uncomment the following library declaration if instantiating
69 -- any Xilinx primitives in this code.
70 --library UNISIM;
71 --use UNISIM.VComponents.all;
72
73 use work.my_func_pack.all;
74 use work.my_comp_pack.all;
75
76 entity fifo_rbu is
77 generic (
78 C_DWIDTH : natural := 8;
79 C_DEPTH : positive := 16 );
80 port (
81 Clk : in std_logic;
82 Reset : in std_logic;
83 FIFO_Write : in std_logic;
84 Data_In : in std_logic_vector(0 to C_DWIDTH-1);
85 FIFO_Read : in std_logic;
86 Data_Out : out std_logic_vector(0 to C_DWIDTH-1);
87 FIFO_Full : out std_logic;
88 FIFO_Empty : out std_logic;
89 Addr : out std_logic_vector(0 to clog2(C_DEPTH)-1);
90 Num_To_Reread : in std_logic_vector(0 to clog2(C_DEPTH)-1);
91 Underflow : out std_logic;
92 Overflow : out std_logic
93 );
94 end fifo_rbu;
95
96 architecture Behavioral of fifo_rbu is
97
98 constant ADDR_BITS : integer := clog2(C_DEPTH);
99
100 -- An extra bit will be carried as the empty flag.
101 signal addr_i : std_logic_vector(ADDR_BITS downto 0);
102 signal addr_i_p1 : std_logic_vector(ADDR_BITS downto 0);
103 signal num_to_reread_zeroext : std_logic_vector(ADDR_BITS downto 0);
104 signal fifo_empty_i : std_logic;
105 signal overflow_i : std_logic;
106 signal underflow_i : std_logic;
107 signal fifo_full_p1 : std_logic;
108
109 begin
110
111 fifo_empty_i <= addr_i(ADDR_BITS);
112 Addr(0 to ADDR_BITS-1) <= addr_i(ADDR_BITS-1 downto 0);
113 FIFO_Empty <= fifo_empty_i;
114
115 num_to_reread_zeroext <= '0' & Num_To_Reread;
116
117 ----------------------------------------------------------------------------
118 -- The FIFO address counter. Addresses the next element to be read.
119 -- All ones when the FIFO is empty.
120 ----------------------------------------------------------------------------
121 CNTR_INCR_DECR_ADDN_F_I : inc_dec_addn_cntr
122 generic map (
123 C_SIZE => ADDR_BITS + 1)
124 port map (
125 Clk => Clk,
126 Reset => Reset,
127 Incr => FIFO_Write,
128 Decr => FIFO_Read,
129 N_to_add => num_to_reread_zeroext,
130 Cnt => addr_i,
131 Cnt_p1 => addr_i_p1
132 );
133
134 ----------------------------------------------------------------------------
135 -- The dynamic shift register that holds the FIFO elements.
136 ----------------------------------------------------------------------------
137 DYNSHREG_F_I : dynamic_shift_reg
138 generic map (
139 C_DEPTH => C_DEPTH,
140 C_DWIDTH => C_DWIDTH
141 )
142 port map (
143 Clk => Clk,
144 CE => FIFO_Write,
145 A => addr_i(ADDR_BITS-1 downto 0),
146 D => Data_In,
147 Q => Data_Out
148 );
149
150 ----------------------------------------------------------------------------
151 -- Full flag.
152 ----------------------------------------------------------------------------
153 fifo_full_p1 <= '1' when ( addr_i_p1 = std_logic_vector(TO_UNSIGNED(C_DEPTH-1, ADDR_BITS+1) ) ) else '0';
154
155 FULL_PROCESS : process (Clk)
156 begin
157 if Clk'event and Clk = '1' then
158 if Reset = '1' then
159 FIFO_Full <= '0';
160 else
161 FIFO_Full <= fifo_full_p1;
162 end if;
163 end if;
164 end process;
165
166
167 ----------------------------------------------------------------------------
168 -- Underflow detection.
169 ----------------------------------------------------------------------------
170 UNDERFLOW_PROCESS : process (Clk)
171 begin
172 if Clk'event and Clk = '1' then
173 if Reset = '1' then
174 underflow_i <= '0';
175 elsif underflow_i = '1' then
176 underflow_i <= '1'; -- Underflow sticks until reset
177 else
178 underflow_i <= fifo_empty_i and FIFO_Read;
179 end if;
180 end if;
181 end process;
182
183 Underflow <= underflow_i;
184
185
186 ----------------------------------------------------------------------------
187 -- Overflow detection.
188 -- The only case of non-erroneous operation for which addr_i (including
189 -- the high-order bit used as the empty flag) taken as an unsigned value
190 -- may be greater than or equal to C_DEPTH is when the FIFO is empty.
191 -- No overflow is possible when FIFO_Read, since Num_To_Reread is
192 -- overriden in this case and the number elements can at most remain
193 -- unchanged (that being when there is a simultaneous FIFO_Write).
194 -- However, when there is no FIFO_Read and there is either a
195 -- FIFO_Write or a restoration of one or more read elements, or both, then
196 -- addr_i, extended by the carry-out bit, becoming greater than
197 -- or equal to C_DEPTH indicates an overflow.
198 ----------------------------------------------------------------------------
199 OVERFLOW_PROCESS : process (Clk)
200 begin
201 if Clk'event and Clk = '1' then
202 if Reset = '1' then
203 overflow_i <= '0';
204 elsif overflow_i = '1' then
205 overflow_i <= '1'; -- Overflow sticks until Reset
206 elsif FIFO_Read = '0' and (FIFO_Write = '1' or bitwise_or(Num_To_Reread) = '1') and UNSIGNED(addr_i_p1) >= C_DEPTH then
207 overflow_i <= '1';
208 else
209 overflow_i <= '0';
210 end if;
211 end if;
212 end process;
213
214 Overflow <= overflow_i;
215
216
217 end Behavioral;