Add input FIFO with TB
This commit is contained in:
parent
a57e5cca13
commit
5151e1685d
323
rtl/flacdec_double_mem_fifo.vhd
Normal file
323
rtl/flacdec_double_mem_fifo.vhd
Normal file
@ -0,0 +1,323 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- Title : FIFO based on two single ported memory instances
|
||||
-- Project : Shimatta VHDL FLAC decoder
|
||||
-------------------------------------------------------------------------------
|
||||
-- File : flacdec_double_mem_fifo.vhd
|
||||
-- Author : Mario Huettel <mario.huettel@linux.com>
|
||||
-- Company :
|
||||
-- Created : 2023-10-06
|
||||
-- Last update: 2023-10-07
|
||||
-- Platform :
|
||||
-- Standard : VHDL'93/02
|
||||
-------------------------------------------------------------------------------
|
||||
-- Description: This is a FIFO implementation based on two single ported memory
|
||||
-- instances, which will allow continuous read/write with minimal arbitration
|
||||
-- overhead. The memory instances have to be connected externally.
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright (c) 2023
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity flacdec_double_mem_fifo is
|
||||
|
||||
generic (
|
||||
ADDRESS_WIDTH : natural range 2 to 32 := 7; -- Adress width of the whole FIFO memory. Defining the FIFO size
|
||||
DATA_WIDTH : positive := 8); -- Data width in bits
|
||||
|
||||
port (
|
||||
clk : in std_logic; -- Clock
|
||||
rst_n : in std_logic; -- Async. low-active reset
|
||||
----------------------------------------------------------------------
|
||||
-- MEMORY 0 Connections
|
||||
----------------------------------------------------------------------
|
||||
mem0_address : out std_logic_vector(ADDRESS_WIDTH - 2 downto 0);
|
||||
mem0_write_enable : out std_logic;
|
||||
mem0_read_enable : out std_logic;
|
||||
mem0_write_data : out std_logic_vector(DATA_WIDTH - 1 downto 0);
|
||||
mem0_read_data : in std_logic_vector(DATA_WIDTH - 1 downto 0);
|
||||
----------------------------------------------------------------------
|
||||
-- MEMORY 1 Connections
|
||||
----------------------------------------------------------------------
|
||||
mem1_address : out std_logic_vector(ADDRESS_WIDTH - 2 downto 0);
|
||||
mem1_write_enable : out std_logic;
|
||||
mem1_read_enable : out std_logic;
|
||||
mem1_write_data : out std_logic_vector(DATA_WIDTH - 1 downto 0);
|
||||
mem1_read_data : in std_logic_vector(DATA_WIDTH - 1 downto 0);
|
||||
----------------------------------------------------------------------
|
||||
-- Input AXI Stream
|
||||
----------------------------------------------------------------------
|
||||
in_tdata : in std_logic_vector(DATA_WIDTH - 1 downto 0);
|
||||
in_tvalid : in std_logic;
|
||||
in_tready : out std_logic;
|
||||
----------------------------------------------------------------------
|
||||
-- Output AXI stream
|
||||
----------------------------------------------------------------------
|
||||
out_tdata : out std_logic_vector(DATA_WIDTH -1 downto 0);
|
||||
out_tvalid : out std_logic;
|
||||
out_tready : in std_logic;
|
||||
----------------------------------------------------------------------
|
||||
-- Control and status
|
||||
----------------------------------------------------------------------
|
||||
clear : in std_logic;
|
||||
flush_output : in std_logic;
|
||||
fill_level : out std_logic_vector(ADDRESS_WIDTH downto 0);
|
||||
empty : out std_logic;
|
||||
full : out std_logic;
|
||||
half_empty : out std_logic);
|
||||
|
||||
end entity flacdec_double_mem_fifo;
|
||||
|
||||
architecture RTL of flacdec_double_mem_fifo is
|
||||
|
||||
constant FIFO_SIZE : natural := 2**ADDRESS_WIDTH;
|
||||
|
||||
signal accepted_input_reg : std_logic_vector(DATA_WIDTH - 1 downto 0);
|
||||
signal accepted_input_valid_reg : std_logic;
|
||||
signal in_tready_s : std_logic;
|
||||
|
||||
signal out_tvalid_reg : std_logic;
|
||||
signal out_tdata_buffer_reg : std_logic_vector(DATA_WIDTH - 1 downto 0);
|
||||
signal out_tdata_buffer_valid_reg : std_logic;
|
||||
signal fifo_read_out_data_s : std_logic_vector(DATA_WIDTH - 1 downto 0);
|
||||
signal out_ready_for_data_s : std_logic;
|
||||
|
||||
signal write_pointer_reg : unsigned(ADDRESS_WIDTH downto 0);
|
||||
signal read_pointer_reg : unsigned(ADDRESS_WIDTH downto 0);
|
||||
|
||||
signal write_address_s : std_logic_vector(ADDRESS_WIDTH - 1 downto 0);
|
||||
signal read_address_s : std_logic_vector(ADDRESS_WIDTH - 1 downto 0);
|
||||
|
||||
signal write_enable : std_logic;
|
||||
signal read_enable : std_logic;
|
||||
signal mem0_read_enable_s : std_logic;
|
||||
signal mem1_read_enable_s : std_logic;
|
||||
signal write_dest_mem : std_logic;
|
||||
signal read_source_mem : std_logic;
|
||||
signal read_data_valid_reg : std_logic_vector(1 downto 0);
|
||||
|
||||
signal fifo_full_s : std_logic;
|
||||
signal fifo_empty_s : std_logic;
|
||||
signal fifo_half_empty_s : std_logic;
|
||||
signal fifo_fill_level_s : integer range 0 to FIFO_SIZE;
|
||||
begin -- architecture RTL
|
||||
|
||||
full <= fifo_full_s;
|
||||
empty <= fifo_empty_s;
|
||||
half_empty <= fifo_half_empty_s;
|
||||
fill_level <= std_logic_vector(to_unsigned(fifo_fill_level_s, fill_level'length));
|
||||
|
||||
in_tready <= in_tready_s;
|
||||
|
||||
out_tvalid <= out_tvalid_reg;
|
||||
|
||||
mem0_read_enable <= mem0_read_enable_s;
|
||||
mem1_read_enable <= mem1_read_enable_s;
|
||||
|
||||
mem0_address <= write_address_s(write_address_s'high downto 1) when mem0_read_enable_s = '0' else read_address_s(read_address_s'high downto 1);
|
||||
mem1_address <= write_address_s(write_address_s'high downto 1) when mem1_read_enable_s = '0' else read_address_s(read_address_s'high downto 1);
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Writing end implementation
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
write_address_s <= std_logic_vector(write_pointer_reg(write_pointer_reg'high - 1 downto 0));
|
||||
|
||||
-- Let LSB decide which memory to write to
|
||||
write_dest_mem <= write_pointer_reg(0);
|
||||
mem0_write_enable <= write_enable when write_dest_mem = '0' else '0';
|
||||
mem1_write_enable <= write_enable when write_dest_mem = '1' else '0';
|
||||
|
||||
mem0_write_data <= accepted_input_reg;
|
||||
mem1_write_data <= accepted_input_reg;
|
||||
|
||||
write_enable_proc : process(accepted_input_valid_reg, write_dest_mem, mem0_read_enable_s, mem1_read_enable_s, fifo_full_s) is
|
||||
begin
|
||||
write_enable <= '0';
|
||||
|
||||
-- Perform write if write destination does not collide with current
|
||||
-- read (This basically implements the arbitration between read and
|
||||
-- write, giving priority to the read path).
|
||||
if (write_dest_mem = '0' and mem0_read_enable_s = '0') or (write_dest_mem = '1' and mem1_read_enable_s = '0') then
|
||||
-- Write if data is available and the FIFO may take new data
|
||||
if accepted_input_valid_reg = '1' and fifo_full_s = '0' then
|
||||
write_enable <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process write_enable_proc;
|
||||
|
||||
-- Write pointer increment upon write action
|
||||
write_pointer_proc : process(clk, rst_n) is
|
||||
begin
|
||||
if rst_n = '0' then
|
||||
write_pointer_reg <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
if clear = '1' then
|
||||
write_pointer_reg <= (others => '0');
|
||||
elsif write_enable = '1' then
|
||||
-- Overflow expected
|
||||
write_pointer_reg <= write_pointer_reg + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process write_pointer_proc;
|
||||
|
||||
-----------------------------------------------------------------
|
||||
-- AXI input
|
||||
----------------------------------------------------------------
|
||||
|
||||
-- Generate the ready signal for the input stream
|
||||
axi_input_ready_proc : process(accepted_input_valid_reg, write_enable, clear) is
|
||||
begin
|
||||
in_tready_s <= '0';
|
||||
|
||||
if accepted_input_valid_reg = '0' then
|
||||
in_tready_s <= '1';
|
||||
end if;
|
||||
|
||||
if write_enable = '1' then
|
||||
in_tready_s <= '1';
|
||||
end if;
|
||||
|
||||
if clear = '1' then
|
||||
in_tready_s <= '0';
|
||||
end if;
|
||||
end process axi_input_ready_proc;
|
||||
|
||||
-- Accept the input datum into a FF buffer
|
||||
axi_input_proc : process(clk, rst_n) is
|
||||
begin
|
||||
if rst_n = '0' then
|
||||
accepted_input_reg <= (others => '0');
|
||||
accepted_input_valid_reg <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
if write_enable = '1' or clear = '1' then
|
||||
-- Reset input buffer once datum is written to memory
|
||||
accepted_input_valid_reg <= '0';
|
||||
end if;
|
||||
if in_tvalid = '1' and in_tready_s = '1' then
|
||||
-- Accept datum in buffer
|
||||
accepted_input_valid_reg <= '1';
|
||||
accepted_input_reg <= in_tdata;
|
||||
end if;
|
||||
end if;
|
||||
end process axi_input_proc;
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- FIFO status calculations
|
||||
------------------------------------------------------------------------
|
||||
fill_level_proc : process(read_pointer_reg, write_pointer_reg) is
|
||||
variable wrapped_around : boolean;
|
||||
variable read_addr : integer range 0 to FIFO_SIZE - 1;
|
||||
variable write_addr : integer range 0 to FIFO_SIZE - 1;
|
||||
begin
|
||||
wrapped_around := (read_pointer_reg(read_pointer_reg'high) /= write_pointer_reg(write_pointer_reg'high));
|
||||
write_addr := to_integer(write_pointer_reg(write_pointer_reg'high - 1 downto 0));
|
||||
read_addr := to_integer(read_pointer_reg(read_pointer_reg'high -1 downto 0));
|
||||
|
||||
if not wrapped_around then
|
||||
fifo_fill_level_s <= write_addr - read_addr;
|
||||
else
|
||||
fifo_fill_level_s <= FIFO_SIZE - read_addr + write_addr;
|
||||
end if;
|
||||
end process fill_level_proc;
|
||||
|
||||
fifo_full_s <= '1' when write_address_s = read_address_s and read_pointer_reg(read_pointer_reg'high) /= write_pointer_reg(write_pointer_reg'high) else '0';
|
||||
fifo_empty_s <= '1' when write_pointer_reg = read_pointer_reg else '0';
|
||||
fifo_half_empty_s <= '1' when fifo_fill_level_s <= FIFO_SIZE / 2 else '0';
|
||||
|
||||
-----------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- READ end implementation
|
||||
-----------------------------------------------------------------------------------------------------------------------------------------------
|
||||
read_address_s <= std_logic_vector(read_pointer_reg(read_pointer_reg'high - 1 downto 0));
|
||||
read_source_mem <= read_address_s(0);
|
||||
|
||||
mem0_read_enable_s <= read_enable when read_source_mem = '0' else '0';
|
||||
mem1_read_enable_s <= read_enable when read_source_mem = '1' else '0';
|
||||
|
||||
read_data_valid_proc : process(clk, rst_n) is
|
||||
begin
|
||||
if rst_n = '0' then
|
||||
read_data_valid_reg <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
-- Delay read enables by one cycle, generating a valid signal
|
||||
read_data_valid_reg <= mem1_read_enable_s & mem0_read_enable_s;
|
||||
end if;
|
||||
end process read_data_valid_proc;
|
||||
|
||||
-- Generate the read_enable signal
|
||||
-- Read from fifo if it is not empty and the output is able to accept a new
|
||||
-- datum. If clear is set, no read is requested.
|
||||
read_enable_proc : process(fifo_empty_s, out_ready_for_data_s, clear) is
|
||||
begin
|
||||
read_enable <= '0';
|
||||
if fifo_empty_s = '0' and clear = '0' then
|
||||
if out_ready_for_data_s = '1' then
|
||||
read_enable <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process read_enable_proc;
|
||||
|
||||
read_pointer_proc : process(clk, rst_n) is
|
||||
begin
|
||||
if rst_n = '0' then
|
||||
read_pointer_reg <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
if clear = '1' then
|
||||
read_pointer_reg <= (others => '0');
|
||||
elsif read_enable = '1' then
|
||||
-- Overflow expected
|
||||
read_pointer_reg <= read_pointer_reg + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process read_pointer_proc;
|
||||
|
||||
--------------------
|
||||
-- Output AXI stream
|
||||
---------------------
|
||||
|
||||
-- Read data mux
|
||||
fifo_read_out_data_s <= mem0_read_data when read_data_valid_reg(0) = '1' else mem1_read_data;
|
||||
|
||||
-- Determine if output flops can be loaded with new data
|
||||
out_ready_for_data_s <= (not out_tvalid_reg) or out_tready;
|
||||
|
||||
axi_output_proc : process(clk, rst_n) is
|
||||
begin
|
||||
if rst_n = '0' then
|
||||
out_tvalid_reg <= '0';
|
||||
out_tdata <= (others => '0');
|
||||
out_tdata_buffer_valid_reg <= '0';
|
||||
out_tdata_buffer_reg <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
if out_tready = '1' then
|
||||
out_tvalid_reg <= '0';
|
||||
end if;
|
||||
|
||||
if flush_output = '1' then
|
||||
-- Flush the output. This breaks the stream protocol!
|
||||
out_tvalid_reg <= '0';
|
||||
out_tdata_buffer_valid_reg <= '0';
|
||||
else -- Output is not flushed
|
||||
if out_ready_for_data_s = '1' then
|
||||
if out_tdata_buffer_valid_reg = '1' then
|
||||
out_tdata <= out_tdata_buffer_reg;
|
||||
out_tvalid_reg <= '1';
|
||||
out_tdata_buffer_valid_reg <= '0';
|
||||
elsif read_data_valid_reg /= "00" then
|
||||
out_tdata <= fifo_read_out_data_s;
|
||||
out_tvalid_reg <= '1';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Fill buffer register, if output is not ready for data or
|
||||
-- filled with old buffer data
|
||||
if read_data_valid_reg /= "00" and ((out_ready_for_data_s = '1' and out_tdata_buffer_valid_reg = '1') or out_ready_for_data_s = '0') then
|
||||
out_tdata_buffer_reg <= fifo_read_out_data_s;
|
||||
out_tdata_buffer_valid_reg <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process axi_output_proc;
|
||||
|
||||
end architecture RTL;
|
120
rtl/flacdec_input_fifo.vhd
Normal file
120
rtl/flacdec_input_fifo.vhd
Normal file
@ -0,0 +1,120 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- Title : Input FIFO for FLAC data
|
||||
-- Project : Shimatta VHDL FLAC decoder
|
||||
-------------------------------------------------------------------------------
|
||||
-- File : flacdec_input_fifo.vhd
|
||||
-- Author : Mario Huettel <mario.huettel@linux.com>
|
||||
-- Company :
|
||||
-- Created : 2023-10-07
|
||||
-- Last update: 2023-10-07
|
||||
-- Platform :
|
||||
-- Standard : VHDL'93/02
|
||||
-------------------------------------------------------------------------------
|
||||
-- Description: 128 byte input FIFO of FLAC core
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright (c) 2023
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity flacdec_input_fifo is
|
||||
|
||||
port (
|
||||
clk : in std_logic; -- CLock
|
||||
rst_n : in std_logic; -- async. low-active reset
|
||||
------------------------------------------------
|
||||
-- Input AXI stream
|
||||
------------------------------------------------
|
||||
in_tdata : in std_logic_vector(7 downto 0);
|
||||
in_tvalid : in std_logic;
|
||||
in_tready : out std_logic;
|
||||
------------------------------------------------
|
||||
-- Output AXI Stream
|
||||
------------------------------------------------
|
||||
out_tdata : out std_logic_vector(7 downto 0);
|
||||
out_tvalid : out std_logic;
|
||||
out_tready : in std_logic;
|
||||
------------------------------------------------
|
||||
-- Control and status signals
|
||||
------------------------------------------------
|
||||
clear : in std_logic;
|
||||
half_empty : out std_logic;
|
||||
empty : out std_logic;
|
||||
full : out std_logic;
|
||||
flush_output : in std_logic);
|
||||
|
||||
end entity flacdec_input_fifo;
|
||||
|
||||
architecture RTL of flacdec_input_fifo is
|
||||
constant ADDRESS_WIDTH : natural := 7;
|
||||
constant DATA_WIDTH : natural := 8;
|
||||
|
||||
signal mem0_address : std_logic_vector(ADDRESS_WIDTH - 2 downto 0);
|
||||
signal mem0_write_enable : std_logic;
|
||||
signal mem0_read_enable : std_logic;
|
||||
signal mem0_write_data : std_logic_vector(DATA_WIDTH - 1 downto 0);
|
||||
signal mem0_read_data : std_logic_vector(DATA_WIDTH - 1 downto 0);
|
||||
signal mem1_address : std_logic_vector(ADDRESS_WIDTH - 2 downto 0);
|
||||
signal mem1_write_enable : std_logic;
|
||||
signal mem1_read_enable : std_logic;
|
||||
signal mem1_write_data : std_logic_vector(DATA_WIDTH - 1 downto 0);
|
||||
signal mem1_read_data : std_logic_vector(DATA_WIDTH - 1 downto 0);
|
||||
|
||||
begin -- architecture RTL
|
||||
|
||||
-- FIFO logic core
|
||||
flacdec_double_mem_fifo_1 : entity work.flacdec_double_mem_fifo
|
||||
generic map (
|
||||
ADDRESS_WIDTH => ADDRESS_WIDTH,
|
||||
DATA_WIDTH => DATA_WIDTH)
|
||||
port map (
|
||||
clk => clk,
|
||||
rst_n => rst_n,
|
||||
mem0_address => mem0_address,
|
||||
mem0_write_enable => mem0_write_enable,
|
||||
mem0_read_enable => mem0_read_enable,
|
||||
mem0_write_data => mem0_write_data,
|
||||
mem0_read_data => mem0_read_data,
|
||||
mem1_address => mem1_address,
|
||||
mem1_write_enable => mem1_write_enable,
|
||||
mem1_read_enable => mem1_read_enable,
|
||||
mem1_write_data => mem1_write_data,
|
||||
mem1_read_data => mem1_read_data,
|
||||
in_tdata => in_tdata,
|
||||
in_tvalid => in_tvalid,
|
||||
in_tready => in_tready,
|
||||
out_tdata => out_tdata,
|
||||
out_tvalid => out_tvalid,
|
||||
out_tready => out_tready,
|
||||
clear => clear,
|
||||
flush_output => flush_output,
|
||||
fill_level => open,
|
||||
empty => empty,
|
||||
full => full,
|
||||
half_empty => half_empty);
|
||||
|
||||
---------------------------------------------------------------
|
||||
-- Memory instances
|
||||
---------------------------------------------------------------
|
||||
|
||||
flacdec_64x08_memory_i0 : entity work.flacdec_64x08_memory
|
||||
port map (
|
||||
clk => clk,
|
||||
address => mem0_address,
|
||||
write_enable => mem0_write_enable,
|
||||
read_enable => mem0_read_enable,
|
||||
write_data => mem0_write_data,
|
||||
read_data => mem0_read_data);
|
||||
|
||||
flacdec_64x08_memory_i1 : entity work.flacdec_64x08_memory
|
||||
port map (
|
||||
clk => clk,
|
||||
address => mem1_address,
|
||||
write_enable => mem1_write_enable,
|
||||
read_enable => mem1_read_enable,
|
||||
write_data => mem1_write_data,
|
||||
read_data => mem1_read_data);
|
||||
|
||||
end architecture RTL;
|
58
rtl/mem/flacdec_64x08_memory.vhd
Normal file
58
rtl/mem/flacdec_64x08_memory.vhd
Normal file
@ -0,0 +1,58 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- Title : 64x08 byte single port memory
|
||||
-- Project : Shimatta VHDL FLAC Decoder
|
||||
-------------------------------------------------------------------------------
|
||||
-- File : flacdec_64x08_memory.vhd
|
||||
-- Author : Mario Huettel <mario.huettel@linux.com>
|
||||
-- Company : Shimatta
|
||||
-- Created : 2023-10-06
|
||||
-- Last update: 2023-10-06
|
||||
-- Platform :
|
||||
-- Standard : VHDL'93/02
|
||||
-------------------------------------------------------------------------------
|
||||
-- Description: This is a 64 byte single ported RAM implementation. This file
|
||||
-- should be able to infer a BRAM on FPGA targets.
|
||||
-- Swap this implementation on an ASIC flow in order to instantiate a fitting
|
||||
-- memory instance.
|
||||
-- Two instances of this memory are used in the input FIFO of the Flac decoder
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright (c) 2023
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity flacdec_64x08_memory is
|
||||
|
||||
port (
|
||||
clk : in std_logic; -- Clock
|
||||
address : in std_logic_vector(5 downto 0); -- RAM data address
|
||||
write_enable : in std_logic; -- Write enable
|
||||
read_enable : in std_logic; -- Enable readout
|
||||
write_data : in std_logic_vector(7 downto 0); -- Write data
|
||||
read_data : out std_logic_vector(7 downto 0)); -- Read data
|
||||
|
||||
end entity flacdec_64x08_memory;
|
||||
|
||||
architecture RTL of flacdec_64x08_memory is
|
||||
type memory_arr_t is array(natural range <>) of std_logic_vector(7 downto 0);
|
||||
|
||||
signal mem : memory_arr_t(0 to 63); -- Memory array
|
||||
signal addr_s : integer range 0 to 63; -- Memory access address
|
||||
begin -- architecture RTL
|
||||
|
||||
addr_s <= to_integer(unsigned(address));
|
||||
|
||||
memory_proc : process is
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
if write_enable = '1' then
|
||||
mem(addr_s) <= write_data;
|
||||
end if;
|
||||
if read_enable = '1' then
|
||||
read_data <= mem(addr_s);
|
||||
end if;
|
||||
end process memory_proc;
|
||||
|
||||
end architecture RTL;
|
@ -1,143 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- Title : FIFO for 8 bit data
|
||||
-- Project : VHDL FLAC Decoder
|
||||
-------------------------------------------------------------------------------
|
||||
-- File : flacdec_byte_fifo.vhd
|
||||
-- Author : Mario Huettel <mario.huettel@linux.com>
|
||||
-- Company :
|
||||
-- Created : 2023-10-05
|
||||
-- Last update: 2023-10-05
|
||||
-- Platform :
|
||||
-- Standard : VHDL'93/02
|
||||
-------------------------------------------------------------------------------
|
||||
-- Description: This is a generic FIFO implementation for 8 bit Data. This
|
||||
-- implementation should be able to map to a dual ported BRAM in an FPGA. If an
|
||||
-- ASIC Design is used, decide weather to use a RAM instance or let the
|
||||
-- synthesis generate a FIFO out of Flip Flops.
|
||||
-- The FIFO is 64 bytes large.
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright (c) 2023 Mario Huettel
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity flacdec_byte_fifo is
|
||||
|
||||
port (
|
||||
clk : in std_logic; -- Clock
|
||||
rst_n : in std_logic; -- async. low-active reset
|
||||
data_in : in std_logic_vector(7 downto 0);
|
||||
data_in_wstrb : in std_logic; -- Write strobe to push data into the FIFO
|
||||
data_out : out std_logic_vector(7 downto 0); -- Output data. 1 cycle delayed after read strobe.
|
||||
data_rstrb : in std_logic;
|
||||
fifo_full : out std_logic; -- FIFO is full
|
||||
fifo_empty : out std_logic; -- FIFO is empty
|
||||
fifo_32_free : out std_logic); -- FIFO has at least 32 bytes free
|
||||
|
||||
end entity flacdec_byte_fifo;
|
||||
|
||||
architecture RTL of flacdec_byte_fifo is
|
||||
|
||||
type fifo_mem_t is array(natural range <>) of std_logic_vector(data_in'range);
|
||||
|
||||
signal mem : fifo_mem_t(0 to 63);
|
||||
signal read_ptr : unsigned(6 downto 0);
|
||||
signal write_ptr : unsigned(6 downto 0);
|
||||
|
||||
signal write_strb_s : std_logic;
|
||||
signal read_strb_s : std_logic;
|
||||
|
||||
signal write_addr : unsigned(5 downto 0);
|
||||
signal read_addr : unsigned(5 downto 0);
|
||||
signal fifo_fill_level : integer range 0 to 64;
|
||||
signal wrapped_around : std_logic;
|
||||
|
||||
signal fifo_full_s : std_logic;
|
||||
signal fifo_empty_s : std_logic;
|
||||
begin -- architecture RTL
|
||||
|
||||
fifo_full <= fifo_full_s;
|
||||
fifo_empty <= fifo_empty_s;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- FIFO memory implementation
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
-- FIFO memory process. Should allow BRAM infer.
|
||||
fifo_mem_proc : process is
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
if write_strb_s = '1' then
|
||||
mem(to_integer(write_addr)) <= data_in;
|
||||
end if;
|
||||
|
||||
if read_strb_s = '1' then
|
||||
data_out <= mem(to_integer(read_addr));
|
||||
end if;
|
||||
end process fifo_mem_proc;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- FIFO fill level and address logic
|
||||
--------------------------------------------------------------------------
|
||||
-- Addresses to memory are the pointers except for the MSB, which is used
|
||||
-- for wrap around detection
|
||||
read_addr <= read_ptr(read_ptr'high - 1 downto read_ptr'low);
|
||||
write_addr <= write_ptr(write_ptr'high - 1 downto write_ptr'low);
|
||||
|
||||
wrapped_around <= '1' when read_ptr(read_ptr'high) /= write_ptr(write_ptr'high) else '0';
|
||||
|
||||
fill_level_proc : process(wrapped_around, read_addr, write_addr) is
|
||||
begin
|
||||
fifo_fill_level <= 0;
|
||||
if wrapped_around = '0' then
|
||||
fifo_fill_level <= to_integer(write_addr - read_addr);
|
||||
else
|
||||
fifo_fill_level <= to_integer(64 - read_addr + write_addr);
|
||||
end if;
|
||||
end process fill_level_proc;
|
||||
|
||||
fifo_full_s <= '1' when read_addr = write_addr and wrapped_around = '1' else '0';
|
||||
fifo_empty_s <= '1' when read_addr = write_addr and wrapped_around = '0' else '0';
|
||||
fifo_32_free <= '1' when fifo_fill_level >= 32 else '0';
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- FIFO write pointer
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
write_strb_s <= data_in_wstrb and (not fifo_full_s);
|
||||
|
||||
write_ptr_proc : process(clk, rst_n) is
|
||||
begin
|
||||
if rst_n = '0' then
|
||||
write_ptr <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
if write_strb_s = '1' then
|
||||
-- Wrap around expected
|
||||
write_ptr <= write_ptr + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process write_ptr_proc;
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- FIFO read pointer
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
read_strb_s <= data_rstrb and (not fifo_empty_s);
|
||||
|
||||
read_ptr_proc : process(clk, rst_n) is
|
||||
begin
|
||||
if rst_n = '0' then
|
||||
read_ptr <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
if read_strb_s = '1' then
|
||||
-- Wrap around expected
|
||||
read_ptr <= read_ptr + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process read_ptr_proc;
|
||||
|
||||
|
||||
end architecture RTL;
|
||||
|
4
verif/.gitignore
vendored
4
verif/.gitignore
vendored
@ -9,6 +9,10 @@ __pycache__/
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
*.o
|
||||
|
||||
# Simulation waveforms
|
||||
*.ghw
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
|
188
verif/input_fifo_tb/poetry.lock
generated
Normal file
188
verif/input_fifo_tb/poetry.lock
generated
Normal file
@ -0,0 +1,188 @@
|
||||
# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "cocotb"
|
||||
version = "1.8.1"
|
||||
description = "cocotb is a coroutine based cosimulation library for writing VHDL and Verilog testbenches in Python."
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "cocotb-1.8.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06ae2b2d899095ee4fd4f9604e0fd3706102ef681659f8dc68e4faf6d990d89f"},
|
||||
{file = "cocotb-1.8.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8d642e1106750a519c015c651ec94a5d9008da0a29d39b2d073206bd60ce452"},
|
||||
{file = "cocotb-1.8.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de9d329e747048ae8d9c08794cc2ee48850b13c387d647227ff76ac2df184fcb"},
|
||||
{file = "cocotb-1.8.1-cp310-cp310-win32.whl", hash = "sha256:87cb47d81d6c55f64662512dda8088e5f430740a42feaa67f7b8e10bd249c02c"},
|
||||
{file = "cocotb-1.8.1-cp310-cp310-win_amd64.whl", hash = "sha256:8b0643be8b1dee02453233a40ad94919f5781bcb08893689c99b9c7ab08695f3"},
|
||||
{file = "cocotb-1.8.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:708cb6fcb2ee00fe80bd45a03f2a202980d2b563dcb064c2f3c904c84e87e2b1"},
|
||||
{file = "cocotb-1.8.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a6d3d824c746410da8f294c34dcca820f1350c1639cafb4b6394844a07f7371"},
|
||||
{file = "cocotb-1.8.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3a9e442211691a3602dd8cce288e9b66f2bab220bc01d1b17e5f30db4a9622c"},
|
||||
{file = "cocotb-1.8.1-cp311-cp311-win32.whl", hash = "sha256:7d47c3aa3432575eb26f6783ef7832a6db873265fd40a89ade22599e59a784f6"},
|
||||
{file = "cocotb-1.8.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ffebe392a4f0cb757ccea51d4902db9abc537e57b9151c5ecc8b4f898ec7817"},
|
||||
{file = "cocotb-1.8.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9d70978a5c587fc26c66c3f0e8a5bc0545a70397cbfd15b342685fed38959fc1"},
|
||||
{file = "cocotb-1.8.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5692e56925de8d71ce8d379bd80a2e103fe0fba1e0c4c3b539b10eafe22fb6c1"},
|
||||
{file = "cocotb-1.8.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4cbfb462315b12f157381c388f3ab5a074c0293e54852f8851152bf295bf6807"},
|
||||
{file = "cocotb-1.8.1-cp312-cp312-win32.whl", hash = "sha256:ac5fa8f47613c1487156d20fb09d4679566572922971ea922ec5acec38629fa9"},
|
||||
{file = "cocotb-1.8.1-cp312-cp312-win_amd64.whl", hash = "sha256:b9e7a09d0f76115f02d9c957110d5970e759c2bc8d1d5a448716ed3a67a66367"},
|
||||
{file = "cocotb-1.8.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:34da6f570c584434e34fe98f1b03cd394c2e43302c85a5510c6aebc5bffd679a"},
|
||||
{file = "cocotb-1.8.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4f8f7401f107e04fb5f1c1bbb6a4434d11fff4bfe6871bea8a822b3ec91e7885"},
|
||||
{file = "cocotb-1.8.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2343642030caf03b707eb7ee665de3adcffab08c5884b40c363ae042e1aad3d4"},
|
||||
{file = "cocotb-1.8.1-cp36-cp36m-win32.whl", hash = "sha256:ab136393aa5776a9a6f25d94af62dd947791482d325516072288668741be934b"},
|
||||
{file = "cocotb-1.8.1-cp36-cp36m-win_amd64.whl", hash = "sha256:1d3af65372ed044f27b69039325bf018738685e59be928fb4efde0c0e86b1ba0"},
|
||||
{file = "cocotb-1.8.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e8d9525a92312d8271fc612c98ce027d285c3f93925f63908c4e9af72a9ba5eb"},
|
||||
{file = "cocotb-1.8.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfa07a47e6b0654ed65e06b37b93316cc3afb7d9b52fe5c07579edd10bdb6281"},
|
||||
{file = "cocotb-1.8.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:298f4e3c0eafda1964112d050cf08827f5aa3c3759960bef1cdce1c57ce645d4"},
|
||||
{file = "cocotb-1.8.1-cp37-cp37m-win32.whl", hash = "sha256:174209743e2743a4c1adb885bb212bb40447464a54388cae360225cb4353499b"},
|
||||
{file = "cocotb-1.8.1-cp37-cp37m-win_amd64.whl", hash = "sha256:71a6a2e39596fe6f2094cc3d4fc35621a6c1e74ca70dc868973a71c6f77f3bdb"},
|
||||
{file = "cocotb-1.8.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f3a6f6f0fa5914c491d22d5796f15b5d0b152f76c071fecb3665af60b471bbe7"},
|
||||
{file = "cocotb-1.8.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1196ba5f341c4e6752e4db71e99932499980a907ec264387d75c6f37d3e09ab6"},
|
||||
{file = "cocotb-1.8.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b1ba54da9217b2231d58a380b19f5bc749f6b1d1b21460bc0951d0c1317a2f5d"},
|
||||
{file = "cocotb-1.8.1-cp38-cp38-win32.whl", hash = "sha256:032569407d22b55a1d7acb07b1be12e2010e332c49d2c04404707d10d892cc27"},
|
||||
{file = "cocotb-1.8.1-cp38-cp38-win_amd64.whl", hash = "sha256:b70d8c803c7215bd54249e53b2591b484346420168dd1cafdb2e0d27e214db11"},
|
||||
{file = "cocotb-1.8.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cbe760f6a0869140a7fa2124c295e2a4299300f0f839017e6b43ab4490bbc522"},
|
||||
{file = "cocotb-1.8.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2a05df85a5259654d2c10cc0ac8ad877b6ca986fb559a911a9207bcdbc887fd"},
|
||||
{file = "cocotb-1.8.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:59cb5e35533b28301e1ff1858aabe1d6bac4305536d5fc40edb188dfda42e0ae"},
|
||||
{file = "cocotb-1.8.1-cp39-cp39-win32.whl", hash = "sha256:2824f26d15713056de44507017f88189419cf7b68252cedbdbed272ee753917f"},
|
||||
{file = "cocotb-1.8.1-cp39-cp39-win_amd64.whl", hash = "sha256:797044b85d5efc56bad7ff789f1811990e67de22fbec614ac37009a9aa608ce5"},
|
||||
{file = "cocotb-1.8.1.tar.gz", hash = "sha256:1499dbe0d4d10676bc9b234861e1df171a7f02aca6b696b5fadf01fe61e3a4f6"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
find-libpython = "*"
|
||||
|
||||
[package.extras]
|
||||
bus = ["cocotb-bus"]
|
||||
|
||||
[[package]]
|
||||
name = "cocotb-bus"
|
||||
version = "0.2.1"
|
||||
description = ""
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
{file = "cocotb-bus-0.2.1.tar.gz", hash = "sha256:a197aa4b0e0ad28469c8877b41b3fb2ec0206da9f491b9276d1578ce6dd8aa8d"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
cocotb = ">=1.5.0.dev,<2.0"
|
||||
|
||||
[[package]]
|
||||
name = "cocotb-coverage"
|
||||
version = "1.1.0"
|
||||
description = "Functional Coverage and Constrained Randomization Extensions for Cocotb"
|
||||
optional = false
|
||||
python-versions = ">=3.3"
|
||||
files = [
|
||||
{file = "cocotb-coverage-1.1.0.tar.gz", hash = "sha256:6aed5f96bcddec3b8632e5be1559d83f355863affbc2a19a5766bbbb41f161e4"},
|
||||
{file = "cocotb_coverage-1.1.0-py3-none-any.whl", hash = "sha256:66f45db27d9835b4a5f92efbc556e36b539e532f1fe07ef5a3036017aca9d1ba"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
cocotb = "*"
|
||||
python-constraint = "*"
|
||||
pyyaml = "*"
|
||||
|
||||
[[package]]
|
||||
name = "cocotbext-axi"
|
||||
version = "0.1.24"
|
||||
description = "AXI, AXI lite, and AXI stream modules for cocotb"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "cocotbext-axi-0.1.24.tar.gz", hash = "sha256:3ed62dcaf9448833176826507c5bc5c346431c4846a731e409d87c862d960593"},
|
||||
{file = "cocotbext_axi-0.1.24-py3-none-any.whl", hash = "sha256:533ba6c7503c6302bdb9ef86e43a549ad5da876eafb1adce23d39751c54cced4"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
cocotb = ">=1.6.0"
|
||||
cocotb-bus = "*"
|
||||
|
||||
[package.extras]
|
||||
test = ["cocotb-test", "pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "find-libpython"
|
||||
version = "0.3.0"
|
||||
description = "Finds the libpython associated with your environment, wherever it may be hiding"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "find_libpython-0.3.0-py3-none-any.whl", hash = "sha256:93fa14c8d007a7f9e6b650a486e249b49f01fd8d45b83ecf080a78b1a7011214"},
|
||||
{file = "find_libpython-0.3.0.tar.gz", hash = "sha256:6e7fe5d9af7fad6dc066cb5515a0e9c90a71f1feb2bb2f8e4cdbb4f83276e9e5"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "python-constraint"
|
||||
version = "1.4.0"
|
||||
description = "python-constraint is a module implementing support for handling CSPs (Constraint Solving Problems) over finite domain"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "python-constraint-1.4.0.tar.bz2", hash = "sha256:501d6f17afe0032dfc6ea6c0f8acc12e44f992733f00e8538961031ef27ccb8e"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
dev = ["check-manifest", "nose"]
|
||||
test = ["coverage", "nose"]
|
||||
|
||||
[[package]]
|
||||
name = "pyyaml"
|
||||
version = "6.0.1"
|
||||
description = "YAML parser and emitter for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"},
|
||||
{file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"},
|
||||
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"},
|
||||
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"},
|
||||
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"},
|
||||
{file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"},
|
||||
{file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"},
|
||||
{file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
|
||||
]
|
||||
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.11"
|
||||
content-hash = "6891ff82be122556d540c217ca1e66b41cf7af93b77485f951064028e5edadcb"
|
17
verif/input_fifo_tb/pyproject.toml
Normal file
17
verif/input_fifo_tb/pyproject.toml
Normal file
@ -0,0 +1,17 @@
|
||||
[tool.poetry]
|
||||
name = "input-fifo-tb"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = ["Mario Huettel <mario.huettel@linux.com>"]
|
||||
readme = "README.md"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.11"
|
||||
cocotb = "^1.8.1"
|
||||
cocotbext-axi = "^0.1.24"
|
||||
cocotb-coverage = "^1.1.0"
|
||||
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
33
verif/input_fifo_tb/results.xml
Normal file
33
verif/input_fifo_tb/results.xml
Normal file
@ -0,0 +1,33 @@
|
||||
<testsuites name="results">
|
||||
<testsuite name="all" package="all">
|
||||
<property name="random_seed" value="1696789703" />
|
||||
<testcase name="test_fifo_fill" classname="tb.tests" file="/home/mhu/projects/fpga/vhdl-flac-decode/verif/input_fifo_tb/tb/tests.py" lineno="26" time="0.018865585327148438" sim_time_ns="2750.000001" ratio_time="145768.07203763907" />
|
||||
<testcase name="stress_test_001" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="0.009937286376953125" sim_time_ns="2070.000001" ratio_time="208306.36478393243" />
|
||||
<testcase name="stress_test_002" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="0.013479232788085938" sim_time_ns="2070.0000010000003" ratio_time="153569.57132082753" />
|
||||
<testcase name="stress_test_003" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="0.01352071762084961" sim_time_ns="2070.0000009999994" ratio_time="153098.38272252338" />
|
||||
<testcase name="stress_test_004" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="0.01389002799987793" sim_time_ns="2270.0000010000003" ratio_time="163426.59647769967" />
|
||||
<testcase name="stress_test_005" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="0.017490386962890625" sim_time_ns="2390.0000010000003" ratio_time="136646.4907878177" />
|
||||
<testcase name="stress_test_006" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="0.01611948013305664" sim_time_ns="2390.0000010000003" ratio_time="148267.80896604504" />
|
||||
<testcase name="stress_test_007" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="0.013995170593261719" sim_time_ns="2070.0000009999985" ratio_time="147908.16497775636" />
|
||||
<testcase name="stress_test_008" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="0.020600318908691406" sim_time_ns="2070.0000010000003" ratio_time="100483.88135033454" />
|
||||
<testcase name="stress_test_009" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="0.011068105697631836" sim_time_ns="2070.0000010000003" ratio_time="187023.87360132489" />
|
||||
<testcase name="stress_test_010" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="0.010287284851074219" sim_time_ns="2190.0000010000003" ratio_time="212884.16066084884" />
|
||||
<testcase name="stress_test_011" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="0.01676630973815918" sim_time_ns="2610.0000010000003" ratio_time="155669.31792150938" />
|
||||
<testcase name="stress_test_012" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="0.014882326126098633" sim_time_ns="2210.0000010000003" ratio_time="148498.29134737197" />
|
||||
<testcase name="stress_test_013" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="0.018981456756591797" sim_time_ns="3110.0000010000003" ratio_time="163844.11591170277" />
|
||||
<testcase name="stress_test_014" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="0.01958465576171875" sim_time_ns="2990.0000009999967" ratio_time="152670.54153917864" />
|
||||
<testcase name="stress_test_015" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="0.01961994171142578" sim_time_ns="2990.0000010000003" ratio_time="152395.96758122667" />
|
||||
<testcase name="stress_test_016" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="0.010677099227905273" sim_time_ns="2230.0000010000003" ratio_time="208858.22575964776" />
|
||||
<testcase name="stress_test_017" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="0.015899181365966797" sim_time_ns="2430.0000010000003" ratio_time="152838.057826145" />
|
||||
<testcase name="stress_test_018" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="0.015126705169677734" sim_time_ns="2270.0000010000003" ratio_time="150065.72651064378" />
|
||||
<testcase name="stress_test_019" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="13.715387344360352" sim_time_ns="1229370.000001" ratio_time="89634.36242334827" />
|
||||
<testcase name="stress_test_020" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="51.89472937583923" sim_time_ns="7365570.000000999" ratio_time="141932.9108869042" />
|
||||
<testcase name="stress_test_021" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="17.472015380859375" sim_time_ns="1755330.0000010002" ratio_time="100465.22749310119" />
|
||||
<testcase name="stress_test_022" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="76.48135256767273" sim_time_ns="12274790.000001" ratio_time="160493.8927974625" />
|
||||
<testcase name="stress_test_023" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="83.74765825271606" sim_time_ns="12274790.000000998" ratio_time="146568.75494907235" />
|
||||
<testcase name="stress_test_024" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="83.08736419677734" sim_time_ns="12274790.000000998" ratio_time="147733.53467959803" />
|
||||
<testcase name="stress_test_025" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="15.489974975585938" sim_time_ns="1418150.0000010058" ratio_time="91552.76249549664" />
|
||||
<testcase name="stress_test_026" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="45.35286903381348" sim_time_ns="7365590.000000998" ratio_time="162406.2635267788" />
|
||||
<testcase name="stress_test_027" classname="tb.tests" file="/home/mhu/.cache/pypoetry/virtualenvs/input-fifo-tb-X8E_jJha-py3.11/lib/python3.11/site-packages/cocotb/regression.py" lineno="731" time="19.35894203186035" sim_time_ns="1755330.0000009984" ratio_time="90672.82690924588" />
|
||||
</testsuite>
|
||||
</testsuites>
|
37
verif/input_fifo_tb/run.sh
Executable file
37
verif/input_fifo_tb/run.sh
Executable file
@ -0,0 +1,37 @@
|
||||
#!/bin/bash
|
||||
|
||||
SOURCE=${BASH_SOURCE[0]}
|
||||
while [ -L "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
|
||||
DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )
|
||||
SOURCE=$(readlink "$SOURCE")
|
||||
[[ $SOURCE != /* ]] && SOURCE=$DIR/$SOURCE # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
||||
done
|
||||
SCRIPT_DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )
|
||||
|
||||
projdir=`readlink -f -n "$SCRIPT_DIR/../../"`
|
||||
|
||||
workdir=`mktemp -d`
|
||||
|
||||
echo "Using tempdir: $workdir"
|
||||
|
||||
toplevel="flacdec_input_fifo"
|
||||
filelist=("rtl/flacdec_double_mem_fifo.vhd" "rtl/mem/flacdec_64x08_memory.vhd" "rtl/flacdec_input_fifo.vhd")
|
||||
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
for file in ${filelist[@]}; do
|
||||
echo "Importing $file"
|
||||
ghdl -i --workdir="$workdir" "$projdir/$file"
|
||||
done
|
||||
|
||||
echo "Building design..."
|
||||
ghdl -m --workdir="$workdir" $toplevel
|
||||
|
||||
export LIBPYTHON_LOC=`cocotb-config --libpython`
|
||||
export MODULE=tb.tests
|
||||
|
||||
ghdl -r --workdir="$workdir" "$toplevel" --vpi=$(cocotb-config --lib-name-path vpi ghdl)
|
||||
|
||||
|
||||
cd "$projdir"
|
||||
rm -rf "$rundir"
|
0
verif/input_fifo_tb/tb/__init__.py
Normal file
0
verif/input_fifo_tb/tb/__init__.py
Normal file
91
verif/input_fifo_tb/tb/tests.py
Normal file
91
verif/input_fifo_tb/tb/tests.py
Normal file
@ -0,0 +1,91 @@
|
||||
import cocotb
|
||||
from cocotb.triggers import RisingEdge, FallingEdge, Edge
|
||||
from cocotb.triggers import Timer
|
||||
from cocotbext.axi import (AxiStreamBus, AxiStreamSource, AxiStreamSink, AxiStreamMonitor, AxiStreamFrame)
|
||||
from random import randint, randrange
|
||||
from cocotb.regression import TestFactory
|
||||
from itertools import cycle
|
||||
|
||||
async def reset_target(dut):
|
||||
dut.rst_n.value = 0
|
||||
dut.out_tready.value = 0
|
||||
dut.flush_output.value = 0
|
||||
dut.clear.value = 0
|
||||
await Timer(10, units='ns')
|
||||
await RisingEdge(dut.clk)
|
||||
dut.rst_n.value = 1
|
||||
|
||||
async def clock_driver(dut):
|
||||
while True:
|
||||
dut.clk.value = 0
|
||||
await Timer(10, units='ns')
|
||||
dut.clk.value = 1
|
||||
await Timer(10, units='ns')
|
||||
|
||||
|
||||
@cocotb.test()
|
||||
async def test_fifo_fill(dut):
|
||||
axi_in = AxiStreamSource(AxiStreamBus.from_prefix(dut, 'in'), dut.clk, dut.rst_n, reset_active_level=False)
|
||||
cocotb.start_soon(clock_driver(dut))
|
||||
await reset_target(dut)
|
||||
|
||||
frame = bytearray([randint(0, 2**8-1) for _ in range(128+2)])
|
||||
|
||||
await axi_in.send(frame)
|
||||
|
||||
await axi_in.wait()
|
||||
await RisingEdge(dut.clk)
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
assert dut.in_tready.value == 1, 'FIFO full + pipeline full'
|
||||
assert dut.full.value == 1, 'FIFO full?'
|
||||
|
||||
await axi_in.send(bytearray([randint(0, 255)]))
|
||||
await axi_in.wait()
|
||||
await RisingEdge(dut.clk)
|
||||
await RisingEdge(dut.clk)
|
||||
assert dut.in_tready.value == 0, 'FIFO full + pipeline full'
|
||||
assert dut.full.value == 1, 'FIFO full'
|
||||
assert dut.empty.value == 0, 'FIFO empty'
|
||||
|
||||
async def stress_test(dut, tx_pause=None, rx_pause=None, count=512):
|
||||
axi_in = AxiStreamSource(AxiStreamBus.from_prefix(dut, 'in'), dut.clk, dut.rst_n, reset_active_level=False)
|
||||
axi_out = AxiStreamSink(AxiStreamBus.from_prefix(dut, "out"), dut.clk, dut.rst_n, reset_active_level=False)
|
||||
cocotb.start_soon(clock_driver(dut))
|
||||
await reset_target(dut)
|
||||
|
||||
if tx_pause:
|
||||
axi_in.set_pause_generator(tx_pause)
|
||||
if rx_pause:
|
||||
axi_out.set_pause_generator(rx_pause)
|
||||
|
||||
frame = bytearray([randint(0, 255) for _ in range(count)])
|
||||
await axi_in.send(frame)
|
||||
await axi_in.wait()
|
||||
|
||||
for _ in range(count*100):
|
||||
await RisingEdge(dut.clk)
|
||||
if dut.flacdec_double_mem_fifo_1.fill_level.value == 0:
|
||||
break
|
||||
else:
|
||||
assert False, 'Timeout'
|
||||
for _ in range(100):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
|
||||
rx_data = await axi_out.read(axi_out.count())
|
||||
|
||||
assert len(rx_data) == len(frame), 'RX TX data count mismatch'
|
||||
|
||||
for tx, rx in zip(frame, rx_data):
|
||||
assert tx == rx, 'TX, RX data mismatch'
|
||||
|
||||
stress_test_fac = TestFactory(stress_test)
|
||||
stress_test_fac.add_option('count', [1, 5, randint(1000, 2**16)])
|
||||
def generate_random_wait_seq(percent=50, length=20):
|
||||
seq = [1 if randint(0, 100) >= percent else 0 for _ in range(length)]
|
||||
return seq
|
||||
|
||||
stress_test_fac.add_option('tx_pause', [None, cycle(generate_random_wait_seq(10, 30)), cycle(generate_random_wait_seq(80, 30))])
|
||||
stress_test_fac.add_option('rx_pause', [None, cycle(generate_random_wait_seq(10, 30)), cycle(generate_random_wait_seq(80, 30))])
|
||||
stress_test_fac.generate_tests()
|
Loading…
Reference in New Issue
Block a user