A small-to-medium depth FIFO with optional capability to back up and reread data

  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;
posted @ 2012-05-10 13:56  IAmAProgrammer  阅读(295)  评论(0编辑  收藏  举报