Sei sulla pagina 1di 3

library IEEE;

USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;

entity coda_circolare is
Port(
clock : in std_logic;
Din : in std_logic_vector (7 downto 0);
Dout: out std_logic_vector (7 downto 0);
enable_in : in std_logic; --enable_in è come se fosse un
enable generale di scrittura, quindi è un ingresso
enable_out : in std_logic; --enable_out è come se fosse
un enable generale di lettura, quindi è un ingresso
full : out std_logic := '0'; --full è un flag di stato che
indica quando la coda è piena e quindi non è più possibile la scrittura,
inizializzato a 0 perchè la coda non è piena (vuota) all'inizio;
empty : out std_logic := '1'; --empty è un flag di stato che
indica quando la coda è vuota e quindi non è più possibile la lettura,
inizializzato a 1 perchè la coda non è piena (vuota) all'inizio;
error : out std_logic := '0';
);
end coda_circolare;

architecture Behavioral of coda_circolare is


begin

type buffer_memory is array (0 to 15) of std_logic_vector (7 downto 0);


--definisco un tipo "buffer_memory" che è un array di 16 locazioni di memoria da 8
bit ciascuna
signal coda_circolare : buffer_memory := (others => (others => '0')); --
definisco il segnale "coda_circolare" che è del tipo sopra definito e che
rappresenta il buffer da cui vado a leggere/scrivere
signal write_index : natural range 0 to 15 := 0; --è l'indice di
scrittura nella coda, definito da 0 fino a 15 dato che la coda può memorizzare 16
elementi
signal read_index : natural range 0 to 15 := 0; --è l'indice di lettura
dalla coda, definito da 0 fino a 15 dato che la coda può memorizzare 16 elementi
signal flag_loop : boolean := false; --è un segnale che uso come
flag per far discriminare i casi full ed empty

scrittura_lettura : process (clock) --processo che gestisce la


scrittura e la lettura
begin
if (rising_edge(clock)) then

--GESTIONE SCRITTURA NELLA CODA


if (enable_in = '1') then
if ((sync = false) or (write_index !=
read_index)) then --se la scrittura è abilitata e se gli indici sono diversi,
non c'è errore e posso memorizzare;

--però la prima volta, essendo i


due indici uguali perchè entrambi inizializzati a 0, entro nell'if grazie
all'operazione or con la variabile booleana sync inizializzata a false
coda_circolare (write_index) <= Din;
--memorizzo Din nella locazione di memoria indicata dall'indice;
if (write_index = 15) then
--dopo la memorizzazione, posso incremetare write_index e quando arriva
a 15 (cioè ha memorizzato 16 dati) riparte da 0
write_index = 0;
flag_loop = true;
else
write_index = write_index +
1;
end if;
end if;
end if;

--GESTIONE LETTURA DALLA CODA


if (enable_out = '1') then
if ((sync = true) or write_index !=
read_index) then --se la lettura è abilitata e se gli indici sono diversi,
non c'è errore e posso leggere;

--però la prima volta, non posso


subito leggere perchè i due indici sono uguali in quanto entrambi inizializzati a
0, e perchè la variabile sync è ancora falsa; solo dopo che è avvenuta la prima
scrittura, il write_index si è incrementato e pertanto sarà diverso dal read_index,
per cui entro nell'if per fare la lettura
Dout <= coda_circolare (read_index);
--effettuo la lettura dalla locazione di memoria indicata dall'indice

if (read_index = 15) then


--dopo la lettura, posso incremetare read_index e quando arriva a 15
(cioè ha letto 16 dati) riparte da 0
read_index = 0;
flag_loop = false;
else
read_index = read_index + 1;
end if;
end if;
end if;
end if;
end process;

flag_full_empty : process (clock) --processo che gestisce i segnali


full e empty
begin
if (rising_edge (clock)) then
if (write_index = read_index) then --
entro se i due indici sono diventati uguali
if (flag_loop = true) then
--se i due indici sono diventati uguali quando il flag_loop = true significa
che è stato riempita tutta la coda, quindi full = 1;
full <= '1';
else
empty <= '1';
--altrimenti se i due indici sono diventati uguali quando il flag_loop =
false significa che la coda è vuota
end if;
else
empty <= '0':
full <= '0';
end if;
end if;
end process;

error <= '1' when ((full = 1 and enable_in = 1) or (empty = 1 end enable_out = 1))
else '0';

end Behavioral;