166 lines
4.8 KiB
VHDL
166 lines
4.8 KiB
VHDL
library Common;
|
|
use Common.CommonLib.all;
|
|
|
|
architecture RTL of FIFO_bram is
|
|
|
|
subtype register_type is std_ulogic_vector(dataIn'high downto 0);
|
|
type memory_type is array (0 to depth-1) of register_type;
|
|
|
|
signal writeCounter: unsigned(requiredBitNb(depth-1)-1 downto 0);
|
|
signal readCounter: unsigned(writeCounter'range);
|
|
signal memoryArray: memory_type;
|
|
|
|
type fifoStateType is (
|
|
sEmpty, sFull,
|
|
sRead, sWrite, sWriteFirst,
|
|
sReadWrite, sWait
|
|
);
|
|
signal fifoState: fifoStateType;
|
|
signal emptyCondition, fullCondition, empty_int: std_ulogic;
|
|
|
|
begin
|
|
------------------------------------------------------------------------------
|
|
-- read and write counters
|
|
updateWriteCounter: process(reset, clock)
|
|
begin
|
|
if reset = '1' then
|
|
writeCounter <= (others => '0');
|
|
elsif rising_edge(clock) then
|
|
if (write = '1') and (fullCondition = '0') then
|
|
writeCounter <= writeCounter + 1;
|
|
end if;
|
|
end if;
|
|
end process updateWriteCounter;
|
|
|
|
updateReadCounter: process(reset, clock)
|
|
begin
|
|
if reset = '1' then
|
|
readCounter <= (others => '0');
|
|
elsif rising_edge(clock) then
|
|
if (read = '1') and (empty_int = '0') then
|
|
readCounter <= readCounter + 1;
|
|
end if;
|
|
end if;
|
|
end process updateReadCounter;
|
|
|
|
------------------------------------------------------------------------------
|
|
-- memory access
|
|
writeMem: process(clock)
|
|
begin
|
|
if rising_edge(clock) then
|
|
if (write = '1') and (fullCondition = '0') then
|
|
memoryArray(to_integer(writeCounter)) <= dataIn;
|
|
end if;
|
|
end if;
|
|
end process writeMem;
|
|
|
|
readMem: process(reset, clock)
|
|
begin
|
|
if reset = '1' then
|
|
dataOut <= (others => '0');
|
|
elsif rising_edge(clock) then
|
|
if (read = '0') or (empty_int = '1') then
|
|
dataOut <= memoryArray(to_integer(readCounter));
|
|
else
|
|
dataOut <= memoryArray(to_integer(readCounter+1));
|
|
end if;
|
|
end if;
|
|
end process readMem;
|
|
|
|
------------------------------------------------------------------------------
|
|
-- controls
|
|
emptyCondition <= '1' when
|
|
( (fifoState = sRead) and (writeCounter = readCounter) ) or
|
|
(fifoState = sEmpty)
|
|
else '0';
|
|
|
|
fullCondition <= '1' when
|
|
( (fifoState = sWrite) and (writeCounter = readCounter) ) or
|
|
(fifoState = sFull)
|
|
else '0';
|
|
|
|
|
|
fifoControl: process(reset, clock)
|
|
begin
|
|
if reset = '1' then
|
|
fifoState <= sEmpty;
|
|
elsif rising_edge(clock) then
|
|
case fifoState is
|
|
when sEmpty =>
|
|
if write = '1' then
|
|
fifoState <= sWriteFirst;
|
|
end if;
|
|
when sFull =>
|
|
if (read = '1') then
|
|
fifoState <= sRead;
|
|
end if;
|
|
when sRead =>
|
|
if (read = '1') and (write = '1') then
|
|
fifoState <= sReadWrite;
|
|
elsif write = '1' then
|
|
fifoState <= sWrite;
|
|
elsif emptyCondition = '1' then
|
|
fifoState <= sEmpty;
|
|
elsif read = '1' then
|
|
fifoState <= sRead;
|
|
else
|
|
fifoState <= sWait;
|
|
end if;
|
|
when sWriteFirst =>
|
|
if (read = '1') and (write = '1') then
|
|
fifoState <= sReadWrite;
|
|
elsif write = '1' then
|
|
fifoState <= sWrite;
|
|
elsif read = '1' then
|
|
fifoState <= sRead;
|
|
else
|
|
fifoState <= sWait;
|
|
end if;
|
|
when sWrite =>
|
|
if (read = '1') and (write = '1') then
|
|
fifoState <= sReadWrite;
|
|
elsif read = '1' then
|
|
fifoState <= sRead;
|
|
elsif fullCondition = '1' then
|
|
fifoState <= sFull;
|
|
elsif write = '1' then
|
|
fifoState <= sWrite;
|
|
else
|
|
fifoState <= sWait;
|
|
end if;
|
|
when sReadWrite =>
|
|
if (read = '0') and (write = '0') then
|
|
fifoState <= sWait;
|
|
elsif (read = '1') and (write = '0') then
|
|
fifoState <= sRead;
|
|
elsif (write = '1') and (read = '0') then
|
|
fifoState <= sWrite;
|
|
end if;
|
|
when sWait =>
|
|
if (read = '1') and (write = '1') then
|
|
fifoState <= sReadWrite;
|
|
elsif read = '1' then
|
|
fifoState <= sRead;
|
|
elsif write = '1' then
|
|
fifoState <= sWrite;
|
|
end if;
|
|
when others => null;
|
|
end case;
|
|
end if;
|
|
end process fifoControl;
|
|
|
|
|
|
full <= '1' when
|
|
(fifoState = sFull) or
|
|
(fullCondition = '1')
|
|
else '0';
|
|
|
|
empty_int <= '1' when
|
|
(fifoState = sEmpty) or
|
|
(fifoState = sWriteFirst) or
|
|
( (emptyCondition = '1') and (fifoState = sRead) )
|
|
else '0';
|
|
empty <= empty_int;
|
|
|
|
end RTL;
|