Add asynchronous FIFO with AXI-like interface
Implements an asynchronous FIFO with independent read/write clocks and Gray code pointers for clock domain crossing. Refactors internal logic to use components like PipelineRegister and GrayCounter for improved synchronization and readability. Includes a testbench to validate functionality with data integrity checks. Relates to version 1.1.2 updates.
This commit is contained in:
120
tests/AsyncFIFO_tb.vhd
Normal file
120
tests/AsyncFIFO_tb.vhd
Normal file
@@ -0,0 +1,120 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.all;
|
||||
|
||||
entity AsyncFIFO_tb is
|
||||
-- The testbench does not require any ports
|
||||
end entity AsyncFIFO_tb;
|
||||
|
||||
architecture behavior of AsyncFIFO_tb is
|
||||
signal WriteCLK, ReadCLK, WriteRST, ReadRST, WriteCE, ReadCE : std_logic := '0';
|
||||
signal DataIn, DataOut : std_logic_vector(31 downto 0) := (others => '0');
|
||||
signal ReadReady, ReadValid : std_logic := '0';
|
||||
signal WriteReady, WriteValid : std_logic := '0';
|
||||
constant WriteClkPeriod : time := 50 ns;
|
||||
constant ReadClkPeriod : time := 5 ns;
|
||||
constant TotalValues : integer := 128; -- Total number of values to write/read
|
||||
signal TestEnd : boolean := false;
|
||||
type TestDataArray is array(0 to 15) of std_logic_vector(31 downto 0);
|
||||
constant TestData : TestDataArray := (
|
||||
x"FAAAAAAA", x"BBBBBBBB", x"CCCCCCCC", x"DDDDDDDD",
|
||||
x"EEEEEEEE", x"FFFFFFFF", x"11111111", x"22222222",
|
||||
x"33333333", x"44444444", x"55555555", x"66666666",
|
||||
x"77777777", x"88888888", x"99999999", x"AAAAAAAF"
|
||||
);
|
||||
begin
|
||||
|
||||
AsyncFIFO_inst : entity work.AsyncFIFO
|
||||
generic map(
|
||||
G_Width => 32,
|
||||
G_Depth => 4,
|
||||
G_RamTypeFifo => "Block"
|
||||
)
|
||||
port map
|
||||
(
|
||||
I_Write_CLK => WriteCLK,
|
||||
I_Write_CE => WriteCE,
|
||||
I_Write_Data => DataIn,
|
||||
I_Write_Valid => WriteValid,
|
||||
O_Write_Ready => WriteReady,
|
||||
I_Read_CLK => ReadCLK,
|
||||
I_Read_CE => ReadCE,
|
||||
O_Read_Data => DataOut,
|
||||
I_Read_Ready => ReadReady,
|
||||
O_Read_Valid => ReadValid
|
||||
);
|
||||
|
||||
WriteClkProcess : process
|
||||
begin
|
||||
while TestEnd /= true loop
|
||||
WriteCLK <= '0';
|
||||
wait for WriteClkPeriod/2;
|
||||
WriteCLK <= '1';
|
||||
wait for WriteClkPeriod/2;
|
||||
end loop;
|
||||
end process;
|
||||
|
||||
ReadClkProcess : process
|
||||
begin
|
||||
while TestEnd /= true loop
|
||||
ReadCLK <= '0';
|
||||
wait for ReadClkPeriod/2;
|
||||
ReadCLK <= '1';
|
||||
wait for ReadClkPeriod/2;
|
||||
end loop;
|
||||
end process;
|
||||
|
||||
WriteProcess : process
|
||||
variable writeCount : integer := 0; -- Variable f�r die Anzahl der geschriebenen Werte
|
||||
begin
|
||||
WriteRST <= '1';
|
||||
wait for WriteClkPeriod * 2;
|
||||
WriteRST <= '0';
|
||||
WriteCE <= '1';
|
||||
while writeCount < TotalValues loop
|
||||
wait until rising_edge(WriteCLK);
|
||||
if WriteReady = '1' then
|
||||
DataIn <= TestData(writeCount mod 16) after WriteClkPeriod/2;
|
||||
WriteValid <= '1' after WriteClkPeriod/2;
|
||||
wait until rising_edge(WriteCLK);
|
||||
WriteValid <= '0' after WriteClkPeriod/2;
|
||||
writeCount := writeCount + 1; -- Nur erh�hen, wenn tats�chlich geschrieben wurde
|
||||
end if;
|
||||
end loop;
|
||||
wait;
|
||||
end process WriteProcess;
|
||||
|
||||
ReadProcess : process
|
||||
variable readCount : integer := 0; -- Variable f�r die Anzahl der gelesenen Werte
|
||||
begin
|
||||
ReadRST <= '1';
|
||||
wait for ReadClkPeriod * 2;
|
||||
ReadRST <= '0';
|
||||
ReadCE <= '1';
|
||||
while readCount < TotalValues loop
|
||||
wait until rising_edge(ReadCLK);
|
||||
if ReadValid = '1' then
|
||||
ReadReady <= '1' after ReadClkPeriod/2;
|
||||
wait until rising_edge(ReadCLK);
|
||||
ReadReady <= '0' after ReadClkPeriod/2;
|
||||
wait until rising_edge(ReadCLK); -- Warten auf Datenstabilisierung
|
||||
-- Assert to check the data correctness
|
||||
if DataOut = TestData(readCount mod 16) then
|
||||
report "Data Match!"
|
||||
severity note;
|
||||
else
|
||||
assert FALSE
|
||||
report "Data Mismatch. Expected " & integer'image(to_integer(unsigned(TestData(readCount mod 16)))) &
|
||||
" but got " & integer'image(to_integer(unsigned(DataOut)))
|
||||
severity error;
|
||||
end if;
|
||||
readCount := readCount + 1; -- Nur erh�hen, wenn tats�chlich gelesen wurde
|
||||
end if;
|
||||
end loop;
|
||||
-- Simulation beenden
|
||||
TestEnd <= true;
|
||||
wait;
|
||||
end process ReadProcess;
|
||||
|
||||
end architecture behavior;
|
Reference in New Issue
Block a user