URL
https://opencores.org/ocsvn/funbase_ip_library/funbase_ip_library/trunk
Subversion Repositories funbase_ip_library
[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.storage/] [fifos/] [synch_fifos/] [1.0/] [vhd/] [fifo_casev5.vhd] - Rev 145
Compare with Previous | Blame | View Log
------------------------------------------------------------------------------- -- File : fifo_casev5.vhdl -- Description : Fifo buffer for hibi interface -- Author : Ari Kulmala -- Date : 10.06.2003 -- Modified : 18.06.2003 - Re-wrote the way output control signals are -- assigned -- -- -- Detailed description: -- -Input and Output always from the same register -- -> input-buffer is shifted whenever write occurs -- -> when read, a mux chooses which value to load to the output next -- (the oldest) -- -- !NOTE! isn't tested as one-length FIFO. doesn't probably work. (vector -- length (1 downto 2) ... -- -- !NOTE! -- * Output is zero when empty. ------------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; entity fifo is generic ( width : integer := 0; depth : integer := 0); port ( Clk : in std_logic; Rst_n : in std_logic; -- Active low Data_In : in std_logic_vector (width-1 downto 0); Write_Enable : in std_logic; One_Place_Left : out std_logic; Full : out std_logic; Data_Out : out std_logic_vector (width-1 downto 0); Read_Enable : in std_logic; Empty : out std_logic; One_Data_Left : out std_logic ); end fifo; architecture behavioral of fifo is -- range is this so that one can use data_amount directly to indexing type reg is array (depth downto 2) of std_logic_vector (width-1 downto 0); signal input_buffer : reg; -- Registers signal Full_reg : std_logic; signal Empty_reg : std_logic; signal One_Data_Left_reg : std_logic; signal One_Place_Left_reg : std_logic; signal Data_amount : integer range 0 to depth; signal WR : std_logic_vector ( 1 downto 0); begin -- behavioral -- Continuous assignments -- Assigns register values to outputs Full <= Full_reg; Empty <= Empty_reg; One_Data_Left <= One_Data_Left_reg; One_Place_Left <= One_Place_Left_reg; -- Concurrent assignment WR <= Write_Enable & Read_Enable; process (Clk, rst_n) begin -- process if rst_n = '0' then -- asynchronous reset (active low) for i in depth downto 2 loop input_buffer(i) <= (others => '0'); end loop; -- i Data_out <= (others => '0'); Data_Amount <= 0; Empty_reg <= '1'; One_Data_Left_reg <= '0'; One_Place_Left_reg <= '0'; Full_reg <= '0'; elsif Clk'event and Clk = '1' then -- rising clock edge case WR is when "01" => -- Read data if Data_amount = 0 then -- empty Data_amount <= Data_amount; Empty_reg <= '1'; One_Data_Left_reg <= '0'; elsif Data_amount = 1 then -- 1 data Data_out <= (others => '0'); Data_amount <= Data_amount-1; Empty_reg <= '1'; One_Data_Left_reg <= '0'; elsif Data_amount = 2 then Data_out <= input_buffer(Data_amount); Data_amount <= Data_amount-1; Empty_reg <= '0'; One_Data_Left_reg <= '1'; else Data_out <= input_buffer(Data_amount); Data_amount <= Data_amount-1; One_Data_Left_reg <= '0'; Empty_reg <= '0'; end if; -- Fifo's getting emptier if Data_amount = depth-1 then One_Place_Left_reg <= '0'; Full_reg <= '0'; elsif Data_amount = depth then One_Place_Left_reg <= '1'; Full_reg <= '0'; else One_Place_Left_reg <= '0'; Full_reg <= '0'; end if; when "10" => -- Write Data if Data_amount = 0 then Data_out <= Data_In; Data_amount <= Data_amount+1; elsif Data_amount = depth then input_buffer <= input_buffer; else for i in depth-1 downto 2 loop input_buffer(i+1) <= input_buffer(i); end loop; -- i input_buffer(2) <= Data_In; Data_amount <= Data_amount+1; end if; -- define the values for output control signals if Data_amount = 0 then Empty_reg <= '0'; One_Data_Left_reg <= '1'; Full_reg <= '0'; One_Place_Left_reg <= '0'; elsif Data_amount = 1 then Empty_reg <= '0'; One_Data_Left_reg <= '0'; Full_reg <= '0'; One_Place_Left_reg <= '0'; elsif Data_amount = depth-2 then Empty_reg <= '0'; One_Data_Left_reg <= '0'; Full_reg <= '0'; One_Place_Left_reg <= '1'; elsif Data_amount = depth-1 then Empty_reg <= '0'; One_Data_Left_reg <= '0'; Full_reg <= '1'; One_Place_Left_reg <= '0'; else Empty_reg <= Empty_reg; One_Data_Left_reg <= One_Data_Left_reg; Full_reg <= Full_reg; One_Place_Left_reg <= One_Place_Left_reg; end if; when "11" => -- Read and Write concurrently if Data_amount = 0 then -- can only write Data_out <= Data_in; Empty_reg <= '0'; One_Data_Left_reg <= '1'; Full_reg <= '0'; One_Place_Left_reg <= '0'; Data_amount <= Data_amount+1; elsif Data_amount = 1 then Data_out <= Data_In; Empty_reg <= '0'; One_Data_Left_reg <= '1'; Full_reg <= '0'; One_Place_Left_reg <= '0'; elsif Data_amount = depth then -- cannot write if full, just read Data_out <= input_buffer (Data_amount); Data_amount <= Data_amount-1; Empty_reg <= '0'; One_Data_Left_reg <= '0'; Full_reg <= '0'; One_Place_Left_reg <= '1'; else Data_out <= input_buffer (Data_amount); for i in depth-1 downto 2 loop input_buffer(i+1) <= input_buffer(i); end loop; -- i input_buffer(2) <= Data_In; Empty_reg <= Empty_reg; One_Data_Left_reg <= One_Data_Left_reg; Full_reg <= Full_reg; One_Place_Left_reg <= One_Place_Left_reg; end if; when others => -- Do nothing, write and read low input_buffer <= input_buffer; Data_amount <= Data_amount; Empty_reg <= Empty_reg; One_Data_Left_reg <= One_Data_Left_reg; Full_reg <= Full_reg; One_Place_Left_reg <= One_Place_Left_reg; end case; end if; --synchronous end process; end behavioral;