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;