fpga: Add generic FIFO core
This commit is contained in:
parent
e81166a82c
commit
db5a14a2f0
106
fpga/hdl/generics/fifo.vhd
Normal file
106
fpga/hdl/generics/fifo.vhd
Normal file
@ -0,0 +1,106 @@
|
||||
-- -------------------------------------------------------------------------- --
|
||||
-- TRASHERNET SoC - A Trashy Ethernet SoC for FPGAs --
|
||||
-- -------------------------------------------------------------------------- --
|
||||
-- TODO
|
||||
-- -------------------------------------------------------------------------- --
|
||||
-- Author : Markus Koch <markus@notsyncing.net>
|
||||
-- Contributors : None
|
||||
-- License : Mozilla Public License (MPL) Version 2
|
||||
-- -------------------------------------------------------------------------- --
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.all;
|
||||
|
||||
entity fifo is
|
||||
generic(
|
||||
SIZE : integer := 15 -- Entries in the FIFO (of size data), SIZE=(n^2)-1 recommended
|
||||
);
|
||||
port(
|
||||
-- generic ports
|
||||
clk : in std_logic; -- System clock
|
||||
rst_a : in std_logic; -- Asynchronous reset
|
||||
clr : in std_logic; -- Remove all entries
|
||||
|
||||
-- FIFO in
|
||||
data_in : in std_logic_vector; -- Data input into FIFO
|
||||
write : in std_logic; -- Data is latched when `data_in_valid and not full`
|
||||
full : out std_logic; -- FIFO is full
|
||||
|
||||
-- FIFO out
|
||||
data_out : out std_logic_vector; -- Data output from FIFO
|
||||
empty : out std_logic; -- FIFO is empty. '0' means "data is available".
|
||||
read : in std_logic; -- Acknowledge that `data_out` was read. The word is removed and next one shifted from FIFO when `read and not empty`.
|
||||
|
||||
-- FIFO meta
|
||||
usage : out integer range 0 to SIZE -- Usage counter
|
||||
);
|
||||
end fifo;
|
||||
|
||||
architecture rtl of fifo is
|
||||
constant MEMORY_WIDTH : integer := data_in'length;
|
||||
subtype pointer_t is integer range 0 to SIZE - 1;
|
||||
type memory_t is array (pointer_t) of std_logic_vector(MEMORY_WIDTH - 1 downto 0);
|
||||
|
||||
signal memory : memory_t;
|
||||
signal read_pointer : pointer_t;
|
||||
signal write_pointer : pointer_t;
|
||||
signal read_pointer_last : pointer_t;
|
||||
|
||||
begin
|
||||
fifo_p : process(rst_a, clk) is
|
||||
variable succesful_read : std_logic;
|
||||
variable succesful_write : std_logic;
|
||||
variable write_pointer_next : pointer_t;
|
||||
variable read_pointer_next : pointer_t;
|
||||
begin
|
||||
if rst_a then
|
||||
read_pointer <= 0;
|
||||
write_pointer <= 0;
|
||||
read_pointer_last <= SIZE - 1;
|
||||
usage <= 0;
|
||||
|
||||
elsif rising_edge(clk) then
|
||||
succesful_read := read and not empty;
|
||||
succesful_write := write and (not full or succesful_read);
|
||||
|
||||
write_pointer_next := write_pointer;
|
||||
read_pointer_next := read_pointer;
|
||||
|
||||
if succesful_read then
|
||||
read_pointer_next := (read_pointer_next + 1) mod SIZE;
|
||||
read_pointer_last <= read_pointer;
|
||||
end if;
|
||||
|
||||
if succesful_write then
|
||||
memory(write_pointer) <= data_in;
|
||||
write_pointer_next := (write_pointer_next + 1) mod SIZE;
|
||||
end if;
|
||||
|
||||
if succesful_write xor succesful_read then
|
||||
if succesful_write then
|
||||
usage <= usage + 1;
|
||||
else
|
||||
usage <= usage - 1;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
read_pointer <= read_pointer_next;
|
||||
write_pointer <= write_pointer_next;
|
||||
|
||||
if clr then
|
||||
read_pointer <= 0;
|
||||
write_pointer <= 0;
|
||||
read_pointer_last <= SIZE - 1;
|
||||
usage <= 0;
|
||||
end if;
|
||||
end if;
|
||||
end process fifo_p;
|
||||
|
||||
full <= '1' when read_pointer_last = write_pointer else '0';
|
||||
empty <= '1' when (read_pointer = write_pointer) else '0';
|
||||
|
||||
data_out <= memory(read_pointer);
|
||||
|
||||
end rtl;
|
Loading…
Reference in New Issue
Block a user