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;