signal_processing/tests/hardware/test_data_channel.vhd

437 lines
16 KiB
VHDL
Raw Normal View History

2023-10-31 06:47:27 +00:00
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.float_pkg.all;
library work;
use work.avalon_slave.all;
use work.test_utility.all;
library std;
use std.textio.all;
package test_data_channel_pkg is
procedure is_empty( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response;
variable res : out boolean );
procedure assert_empty( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response );
procedure assert_not_empty( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response );
procedure assert_full( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response );
procedure assert_not_full( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response );
procedure assert_level( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response;
variable level : in std_logic_vector );
procedure assert_config( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response;
variable config : in std_logic_vector );
procedure write_config( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
variable config : in std_logic_vector );
procedure write_and_assert_config( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response;
variable config : in std_logic_vector );
procedure write_clear( signal clk : in std_logic;
signal req : out work.avalon_slave.Request );
procedure write_sw_sink( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
variable data : in std_logic_vector );
procedure read_sw_source( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response;
variable data : out std_logic_vector );
procedure assert_read_sw_source_eq( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response;
variable expected : in std_logic_vector );
procedure write_hw_sink( signal clk : in std_logic;
signal write : out std_logic;
signal writedata : out std_logic_vector;
variable data : in std_logic_vector );
procedure assert_read_hw_source_eq( signal clk : in std_logic;
signal read : out std_logic;
signal readdata : in std_logic_vector;
variable expected : in std_logic_vector );
procedure write_content( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response );
procedure check_and_write_content( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response;
constant expected : real_array );
end package test_data_channel_pkg;
package body test_data_channel_pkg is
procedure is_empty( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response;
variable res : out boolean ) is
variable address : std_logic_vector( 3 downto 0 );
variable data : std_logic_vector( 31 downto 0 );
constant EMPTY : std_logic_vector( 31 downto 0 ) := x"00000001";
begin
wait until falling_edge( clk );
address := std_logic_vector( to_unsigned( 1, address'length ) );
work.test_avalon_slave.read( clk => clk,
address => address,
req => req,
rsp => rsp,
data => data );
res := data = EMPTY;
end procedure is_empty;
procedure assert_empty( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response ) is
variable address : std_logic_vector( 3 downto 0 );
variable expected_readdata : std_logic_vector( 31 downto 0 ) := x"00000001";
begin
wait until falling_edge( clk );
address := std_logic_vector( to_unsigned( 1, address'length ) );
expected_readdata := x"00000001";
work.test_avalon_slave.assert_readdata_eq( clk => clk,
address => address,
req => req,
rsp => rsp,
expected => expected_readdata,
message => TEST_FAIL & " assert_empty" );
end procedure assert_empty;
procedure assert_not_empty( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response ) is
variable address : std_logic_vector( 3 downto 0 );
variable expected_readdata : std_logic_vector( 31 downto 0 ) := x"00000001";
begin
wait until falling_edge( clk );
address := std_logic_vector( to_unsigned( 1, address'length ) );
expected_readdata := x"00000000";
work.test_avalon_slave.assert_readdata_eq( clk => clk,
address => address,
req => req,
rsp => rsp,
expected => expected_readdata,
message => TEST_FAIL & " assert_not_empty" );
end procedure assert_not_empty;
procedure assert_full( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response ) is
variable address : std_logic_vector( 3 downto 0 );
variable expected_readdata : std_logic_vector( 31 downto 0 ) := x"00000001";
begin
wait until falling_edge( clk );
address := std_logic_vector( to_unsigned( 2, address'length ) );
expected_readdata := x"00000001";
work.test_avalon_slave.assert_readdata_eq( clk => clk,
address => address,
req => req,
rsp => rsp,
expected => expected_readdata,
message => TEST_FAIL & " assert_full" );
end procedure assert_full;
procedure assert_not_full( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response ) is
variable address : std_logic_vector( 3 downto 0 );
variable expected_readdata : std_logic_vector( 31 downto 0 ) := x"00000001";
begin
wait until falling_edge( clk );
address := std_logic_vector( to_unsigned( 2, address'length ) );
expected_readdata := x"00000000";
work.test_avalon_slave.assert_readdata_eq( clk => clk,
address => address,
req => req,
rsp => rsp,
expected => expected_readdata,
message => TEST_FAIL & " assert_not_full" );
end procedure assert_not_full;
procedure assert_level( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response;
variable level : in std_logic_vector ) is
variable address : std_logic_vector( 3 downto 0 );
begin
wait until falling_edge( clk );
address := std_logic_vector( to_unsigned( 3, address'length ) );
work.test_avalon_slave.assert_readdata_eq( clk => clk,
address => address,
req => req,
rsp => rsp,
expected => level,
message => TEST_FAIL & " assert_level" );
end procedure assert_level;
procedure assert_config( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response;
variable config : in std_logic_vector ) is
variable address : std_logic_vector( 3 downto 0 );
begin
wait until falling_edge( clk );
address := std_logic_vector( to_unsigned( 0, address'length ) );
work.test_avalon_slave.assert_readdata_eq( clk => clk,
address => address,
req => req,
rsp => rsp,
expected => config,
message => TEST_FAIL & " assert_config" );
end procedure assert_config;
procedure write_config( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
variable config : in std_logic_vector ) is
variable address : std_logic_vector( 3 downto 0 );
begin
wait until falling_edge( clk );
address := std_logic_vector( to_unsigned( 0, address'length ) );
work.test_avalon_slave.write( clk => clk,
address => address,
req => req,
data => config );
end procedure write_config;
procedure write_and_assert_config( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response;
variable config : in std_logic_vector ) is
variable address : std_logic_vector( 3 downto 0 );
begin
write_config( clk => clk, req => req, config => config );
assert_config( clk => clk, req => req, rsp => rsp, config => config );
end procedure write_and_assert_config;
procedure write_clear( signal clk : in std_logic;
signal req : out work.avalon_slave.Request ) is
variable address : std_logic_vector( 3 downto 0 );
variable clear : std_logic_vector( 31 downto 0 ) := x"00000001";
begin
wait until falling_edge( clk );
address := std_logic_vector( to_unsigned( 6, address'length ) );
work.test_avalon_slave.write( clk => clk,
address => address,
req => req,
data => clear );
end procedure write_clear;
procedure write_sw_sink( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
variable data : in std_logic_vector ) is
variable address : std_logic_vector( 3 downto 0 );
begin
wait until falling_edge( clk );
address := std_logic_vector( to_unsigned( 4, address'length ) );
work.test_avalon_slave.write( clk => clk,
address => address,
req => req,
data => data );
end procedure write_sw_sink;
procedure read_sw_source( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response;
variable data : out std_logic_vector ) is
variable address : std_logic_vector( 3 downto 0 );
begin
wait until falling_edge( clk );
address := std_logic_vector( to_unsigned( 5, address'length ) );
work.test_avalon_slave.read( clk => clk,
address => address,
req => req,
rsp => rsp,
data => data );
end procedure read_sw_source;
procedure assert_read_sw_source_eq( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response;
variable expected : in std_logic_vector ) is
variable address : std_logic_vector( 3 downto 0 );
begin
wait until falling_edge( clk );
address := std_logic_vector( to_unsigned( 5, address'length ) );
work.test_avalon_slave.assert_readdata_eq( clk => clk,
address => address,
req => req,
rsp => rsp,
expected => expected,
message => TEST_FAIL & " assert_readdata_eq" );
end procedure assert_read_sw_source_eq;
procedure write_hw_sink( signal clk : in std_logic;
signal write : out std_logic;
signal writedata : out std_logic_vector;
variable data : in std_logic_vector ) is
begin
wait until falling_edge( clk );
write <= '1';
writedata <= data;
wait until falling_edge( clk );
write <= '0';
end procedure write_hw_sink;
procedure assert_read_hw_source_eq( signal clk : in std_logic;
signal read : out std_logic;
signal readdata : in std_logic_vector;
variable expected : in std_logic_vector ) is
begin
wait until falling_edge( clk );
assert( readdata = expected )
report TEST_FAIL & " assert_read_hw_source_eq" & LF &
" expected: " & to_string( expected ) & LF &
" actual: " & to_string( readdata ) & LF
severity error;
wait until falling_edge( clk );
read <= '1';
wait until falling_edge( clk );
read <= '0';
end procedure assert_read_hw_source_eq;
procedure write_content( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response ) is
variable index : integer := 0;
variable empty : boolean;
variable value : std_logic_vector( 31 downto 0 );
variable float_value : float32;
variable real_value : real;
file data_file : text;
begin
std.textio.write( std.textio.OUTPUT, " write_content ... " );
file_open( data_file, "data.py", write_mode );
std.textio.write( data_file, "float_data = [" );
while true loop
is_empty( clk => clk, req => req, rsp => rsp, res => empty );
if ( empty ) then
exit;
end if;
read_sw_source( clk => clk, req => req, rsp => rsp,
data => value );
float_value := to_float( value );
real_value := to_real( float_value );
std.textio.write( data_file, to_string( real_value ) & "," );
index := index + 1;
end loop;
while index < 1024 loop
std.textio.write( data_file, "0.0 ," );
index := index + 1;
end loop;
std.textio.write( data_file, "]" & LF );
file_close( data_file );
std.textio.write( std.textio.OUTPUT, TEST_OK );
end procedure write_content;
procedure check_and_write_content( signal clk : in std_logic;
signal req : out work.avalon_slave.Request;
signal rsp : in work.avalon_slave.Response;
constant expected : real_array ) is
variable expected_readdata : std_logic_vector( 31 downto 0 );
variable index : integer := 0;
variable empty : boolean;
variable value : std_logic_vector( 31 downto 0 );
variable float_value : float32;
variable real_value : real;
variable expected_value : real;
variable abs_err : real := 0.5e-1;
file data_file : text;
begin
std.textio.write( std.textio.OUTPUT, " check_and_write_content ... " );
assert_full( clk => clk, req => req, rsp => rsp );
expected_readdata := std_logic_vector( to_unsigned( 0, expected_readdata'length ) );
assert_level( clk => clk, req => req, rsp => rsp,
level => expected_readdata );
file_open( data_file, "data.py", write_mode );
std.textio.write( data_file, "float_data = [" );
while true loop
is_empty( clk => clk, req => req, rsp => rsp, res => empty );
if ( empty ) then
exit;
end if;
read_sw_source( clk => clk, req => req, rsp => rsp,
data => value );
float_value := to_float( value );
real_value := to_real( float_value );
std.textio.write( data_file, to_string( real_value ) & "," );
expected_value := expected( index );
assert_element_near( real_value, expected_value, abs_err, index );
index := index + 1;
end loop;
std.textio.write( data_file, "]" & LF );
file_close( data_file );
std.textio.write( std.textio.OUTPUT, TEST_OK );
end procedure check_and_write_content;
end package body test_data_channel_pkg;