---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 16:04:58 09/24/2009 -- Design Name: -- Module Name: FIFO - beh -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.all; -- clk and reset needed for FIFO. rd indicates read an element, wr indicates write -- an element. w_data/r_data are words in and out of FIFO respectively. empty and -- full are indicators entity FIFO is Generic( NUM_DATA_BITS: natural := 8; NUM_ADDR_BITS: natural := 4); Port ( clk : in std_logic; reset : in std_logic; rd, wr : in std_logic; w_data : in std_logic_vector(NUM_DATA_BITS-1 downto 0); empty, full : out std_logic; r_data : out std_logic_vector(NUM_DATA_BITS-1 downto 0) ); end FIFO; ---------------------------------------------------------------------------------- architecture beh of FIFO is type reg_file_type is array (2**NUM_ADDR_BITS-1 downto 0) of std_logic_vector(NUM_DATA_BITS-1 downto 0); signal array_reg : reg_file_type; signal w_ptr_reg, w_ptr_next, w_ptr_succ : std_logic_vector(NUM_ADDR_BITS-1 downto 0); signal r_ptr_reg, r_ptr_next, r_ptr_succ : std_logic_vector(NUM_ADDR_BITS-1 downto 0); signal full_reg, empty_reg, full_next, empty_next : std_logic; signal wr_op : std_logic_vector(1 downto 0); signal wr_en : std_logic; begin ---------------------------------- -- register file ---------------------------------- process (clk, reset) begin if ( reset = '1' ) then array_reg <= (others => (others => '0')); elsif ( clk'event and clk = '1' ) then if ( wr_en = '1' ) then array_reg(to_integer(unsigned(w_ptr_reg))) <= w_data; end if; end if; end process; -- read port r_data <= array_reg(to_integer(unsigned(r_ptr_reg))); -- write enabled ONLY when FIFO is not full wr_en <= wr and (not full_reg); ---------------------------------- -- FIFO sequential logic ---------------------------------- process (clk, reset) begin if (reset = '1') then w_ptr_reg <= (others => '0'); r_ptr_reg <= (others => '0'); full_reg <= '0'; empty_reg <= '0'; elsif (clk'event and clk = '1') then w_ptr_reg <= w_ptr_next; r_ptr_reg <= r_ptr_next; full_reg <= full_next; empty_reg <= empty_next; end if; end process; -- successive pointer values w_ptr_succ <= std_logic_vector(unsigned(w_ptr_reg)+1); r_ptr_succ <= std_logic_vector(unsigned(r_ptr_reg)+1); ---------------------------------- -- FIFO next state logic ---------------------------------- wr_op <= wr & rd; process (w_ptr_reg, w_ptr_succ, r_ptr_reg, r_ptr_succ, wr_op, empty_reg, full_reg) begin -- defaults w_ptr_next <= w_ptr_reg; r_ptr_next <= r_ptr_reg; full_next <= full_reg; empty_next <= empty_reg; -- case out requested operation case wr_op is -- no op when "00" => -- read when "01" => if ( empty_reg /= '1' ) then r_ptr_next <= r_ptr_succ; full_next <= '0'; if ( r_ptr_succ = w_ptr_reg ) then empty_next <= '1'; end if; end if; -- write when "10" => if ( full_reg /= '1' ) then w_ptr_next <= w_ptr_succ; empty_next <= '0'; if ( w_ptr_succ = r_ptr_reg ) then full_next <= '1'; end if; end if; -- write/read when others => w_ptr_next <= w_ptr_succ; r_ptr_next <= r_ptr_succ; end case; end process; -- output state full <= full_reg; empty <= empty_reg; end beh;