70 lines
No EOL
2.6 KiB
VHDL
Executable file
70 lines
No EOL
2.6 KiB
VHDL
Executable file
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
|
|
--------------------------------------------------------
|
|
entity fifo is
|
|
generic (
|
|
WIDTH : positive := 32;
|
|
DEPTH : positive := 8;
|
|
F_PTR_SIZE : positive := 4
|
|
);
|
|
port(
|
|
arstN, clk, wr_req, rd_req : in std_logic;
|
|
full, empty : out std_logic;
|
|
data_in : in std_logic_vector(WIDTH-1 downto 0);
|
|
data_out : out std_logic_vector(WIDTH-1 downto 0)
|
|
);
|
|
end fifo;
|
|
|
|
--------------------------------------------------------
|
|
architecture impl of fifo is
|
|
constant one : unsigned(DEPTH-1 downto 0) := to_unsigned(1, DEPTH);
|
|
type T_FIFO is array (0 to DEPTH-1) of std_logic_vector(WIDTH-1 downto 0);
|
|
|
|
signal wr_ptr, rd_ptr : unsigned(F_PTR_SIZE-1 downto 0);
|
|
signal wr_ptr_nxt, rd_ptr_nxt : unsigned(F_PTR_SIZE-1 downto 0);
|
|
signal data_out_nxt : std_logic_vector(WIDTH-1 downto 0);
|
|
signal s_full, s_empty : std_logic;
|
|
signal s_full_nxt, s_empty_nxt : std_logic;
|
|
signal fifo, fifo_nxt : T_FIFO;
|
|
signal fifo_sel : std_logic_vector(DEPTH-1 downto 0);
|
|
|
|
begin
|
|
update_registers: process(arstN, clk)
|
|
begin
|
|
if arstN = '0' then
|
|
wr_ptr <= (others => '0');
|
|
rd_ptr <= (others => '0');
|
|
fifo <= (others => (others => '0'));
|
|
data_out <= (others => '0');
|
|
elsif clk'event and clk='1' then
|
|
fifo <= fifo_nxt;
|
|
wr_ptr <= wr_ptr_nxt;
|
|
rd_ptr <= rd_ptr_nxt;
|
|
data_out <= data_out_nxt;
|
|
s_full <= s_full_nxt;
|
|
s_empty <= s_empty_nxt;
|
|
end if;
|
|
end process;
|
|
|
|
g_write_mux: for i in 0 to DEPTH-1 generate
|
|
fifo_nxt(i) <= data_in when fifo_sel(i) = '1' else fifo(i);
|
|
end generate;
|
|
|
|
fifo_sel <= std_logic_vector(shift_left(one, to_integer(wr_ptr(F_PTR_SIZE-2 downto 0))))
|
|
when wr_req = '1' and s_full = '0' else (others => '0');
|
|
|
|
data_out_nxt <= fifo(to_integer(rd_ptr(F_PTR_SIZE-2 downto 0)));
|
|
|
|
s_full_nxt <= '1' when
|
|
rd_ptr_nxt(F_PTR_SIZE-2 downto 0) = wr_ptr_nxt(F_PTR_SIZE-2 downto 0) and
|
|
rd_ptr_nxt(F_PTR_SIZE-1) /= wr_ptr_nxt(F_PTR_SIZE-1) else '0';
|
|
s_empty_nxt <= '1' when rd_ptr_nxt = wr_ptr_nxt else '0';
|
|
|
|
rd_ptr_nxt <= rd_ptr + 1 when rd_req = '1' and s_empty = '0' else rd_ptr;
|
|
wr_ptr_nxt <= wr_ptr + 1 when wr_req = '1' and s_full = '0' else wr_ptr;
|
|
|
|
full <= s_full;
|
|
empty <= s_empty;
|
|
end impl; |