the code. comments are in italian, sorry. i am working with the design of my colleagues from Italy.
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_signed.ALL;
USE ieee.numeric_std.all;
entity fifo_sync is
generic(
NUMBIT : integer; -- numero di bit dimensione
FIFO_FULL_PROTECTION : integer; -- margine in scrittura
FIFO_WIDTH : integer -- profondità dati
);
port(
clk : in std_logic;
reset : in std_logic;
data : in std_logic_vector (0 to FIFO_WIDTH-1);
rdreq : in std_logic;
wrreq : in std_logic;
q : out std_logic_vector(0 to FIFO_WIDTH-1);
empty : out std_logic;
full : out std_logic;
flush : in std_logic);
end fifo_sync;
architecture Behavioral of fifo_sync is
-- Impiegati per realizzare una FIFO di dimensione di potenza di 2
type lut_type is array (integer range 0 to 8) of integer range 0 to 256;
constant lut_square : lut_type :=(0, 2, 4, 8, 16, 32, 64, 128, 256);
-- Numero words FIFO
constant NUMWORDS : integer := lut_square(NUMBIT);
-- Dati accessibili con controllo FIFO FULL PROTECTION
constant numwords_ffp : integer := (NUMWORDS - FIFO_FULL_PROTECTION)-1;
type fifo_type is array (0 to NUMWORDS-1) of std_logic_vector(0 to FIFO_WIDTH-1);
signal fifo_sig : fifo_type;
-- Indirizzi per lettura e scrittura
signal addr_wr : std_logic_vector(0 to NUMBIT-1);
signal addr_rd : std_logic_vector(0 to NUMBIT-1);
-- Numero di dati presenti in FIFO
signal data_count : std_logic_vector(0 to NUMBIT-1);
-- Segnali FIFO FULL e EMPTY
signal full_sig : std_logic;
signal empty_sig : std_logic;
-- Abilitazione scrittura e lettura
signal wr_en : std_logic;
signal rd_en : std_logic;
-- knw 2/14/11
attribute ramstyle : string;
attribute ramstyle of fifo_sig : signal is "logic";
begin
full <= full_sig;
empty <= empty_sig;
-- Abilito la scrittura solo se la fifo non è piena
wr_en <= wrreq and (not full_sig);
-- Abilito la lettura solo se la fifo non è vuota
rd_en <= rdreq and (not empty_sig);
-- Gestione scrittura e lettura FIFO
PROC_FIFO: process ( clk, reset )
begin
if (reset = '1') then
for x in 0 to (NUMWORDS-1) loop
fifo_sig(x) <= (others => '0');
end loop;
elsif (clk'event and clk = '1')then
if(wr_en = '1')then
fifo_sig(TO_INTEGER(unsigned(addr_wr)))<= data;
end if;
q <= fifo_sig(TO_INTEGER(unsigned(addr_rd)));
end if;
end process PROC_FIFO;
-- Calcolo degli indirizzi per lettura, scrittura e numero di dati in FIFO
-- ad un accesso in scrittura incremento il conteggio dei dati presenti "data_count"
-- e incremento l'indirizzo per scrivere nella prossima locazione, in lettura
-- decremento il conteggio dei dati e incremento l'indirizzo per leggere la locazione
-- successiva
PROC_CNT_DATA: process ( clk, reset )
begin
if (reset = '1')then
data_count <= (others => '0');
addr_rd <= (others => '0');
addr_wr <= (others => '0');
elsif (clk'event and clk = '1')then
if (flush = '1') then
data_count <= (others => '0');
addr_rd <= (others => '0');
addr_wr <= (others => '0');
elsif ((wr_en = '1') and (rd_en = '1')) then
data_count <= data_count; -- incremento e decremento -> conteggio invariato
addr_rd <= addr_rd + 1;
addr_wr <= addr_wr + 1;
elsif (rd_en = '1') then
data_count <= data_count - 1;
addr_rd <= addr_rd + 1;
elsif (wr_en = '1') then -- empty
data_count <= data_count + 1;
addr_wr <= addr_wr + 1;
end if;
end if;
end process PROC_CNT_DATA;
-- Gestione dei segnali full e empty
process ( clk, reset )
begin
if (reset = '1')then
full_sig <= '0';
empty_sig <= '1';
elsif (clk'event and clk = '1')then
if(TO_INTEGER(unsigned(data_count)) = 0)then
empty_sig <= '1';
full_sig <= '0';
elsif(TO_INTEGER(unsigned(data_count)) >= numwords_ffp )then
full_sig <= '1';
empty_sig <= '0';
else
full_sig <= '0';
empty_sig <= '0';
end if;
end if;
end process;
end Behavioral;