Skip to content

Commit

Permalink
Fix issues with disconnected tstrb.
Browse files Browse the repository at this point in the history
  • Loading branch information
LarsAsplund committed Aug 15, 2024
1 parent 08d4fa3 commit 4df4223
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 22 deletions.
4 changes: 2 additions & 2 deletions vunit/vhdl/verification_components/src/axi_stream_master.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ entity axi_stream_master is
tready : in std_logic := '1';
tdata : out std_logic_vector(data_length(master)-1 downto 0) := (others => '0');
tlast : out std_logic := '0';
tkeep : out std_logic_vector(data_length(master)/8-1 downto 0) := (others => '0');
tstrb : out std_logic_vector(data_length(master)/8-1 downto 0) := (others => '0');
tkeep : out std_logic_vector(data_length(master)/8-1 downto 0) := (others => '1');
tstrb : out std_logic_vector(data_length(master)/8-1 downto 0) := (others => '1');
tid : out std_logic_vector(id_length(master)-1 downto 0) := (others => '0');
tdest : out std_logic_vector(dest_length(master)-1 downto 0) := (others => '0');
tuser : out std_logic_vector(user_length(master)-1 downto 0) := (others => '0')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ begin
debug(monitor.p_logger, "tdata: " & to_nibble_string(tdata) & " (" & to_integer_string(tdata) & ")" & ", tlast: " & to_string(tlast));
end if;

tstrb_resolved := tstrb when tstrb /= (tstrb'range => 'U') else tkeep;
tstrb_resolved := tkeep when is_u(tstrb) else tstrb;
axi_stream_transaction := (
tdata => tdata,
tlast => tlast = '1',
Expand Down
18 changes: 16 additions & 2 deletions vunit/vhdl/verification_components/src/axi_stream_pkg.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,8 @@ package axi_stream_pkg is
max_stall_cycles : natural
) return stall_config_t;

function is_u(value : std_ulogic_vector) return boolean;

end package;

package body axi_stream_pkg is
Expand Down Expand Up @@ -607,8 +609,8 @@ package body axi_stream_pkg is
) is
variable msg : msg_t := new_msg(push_axi_stream_msg);
variable normalized_data : std_logic_vector(data_length(axi_stream)-1 downto 0) := (others => '0');
variable normalized_keep : std_logic_vector(data_length(axi_stream)/8-1 downto 0) := (others => '0');
variable normalized_strb : std_logic_vector(data_length(axi_stream)/8-1 downto 0) := (others => '0');
variable normalized_keep : std_logic_vector(data_length(axi_stream)/8-1 downto 0) := (others => '1');
variable normalized_strb : std_logic_vector(data_length(axi_stream)/8-1 downto 0) := (others => '1');
variable normalized_id : std_logic_vector(id_length(axi_stream)-1 downto 0) := (others => '0');
variable normalized_dest : std_logic_vector(dest_length(axi_stream)-1 downto 0) := (others => '0');
variable normalized_user : std_logic_vector(user_length(axi_stream)-1 downto 0) := (others => '0');
Expand All @@ -618,6 +620,7 @@ package body axi_stream_pkg is
push_std_ulogic(msg, tlast);
normalized_keep(tkeep'length-1 downto 0) := tkeep;
push_std_ulogic_vector(msg, normalized_keep);
normalized_strb := normalized_keep;
normalized_strb(tstrb'length-1 downto 0) := tstrb;
push_std_ulogic_vector(msg, normalized_strb);
normalized_id(tid'length-1 downto 0) := tid;
Expand Down Expand Up @@ -810,4 +813,15 @@ package body axi_stream_pkg is
return stall_config;
end;

function is_u(value : std_ulogic_vector) return boolean is
begin
for idx in value'range loop
if value(idx) /= 'U' then
return false;
end if;
end loop;

return true;
end;

end package body;
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ architecture a of axi_stream_protocol_checker is
return ret;
end function;
begin
tstrb_resolved <= tstrb when tstrb /= (tstrb'range => 'U') else tkeep;
tstrb_resolved <= tkeep when is_u(tstrb) else tstrb;
handshake_is_not_x <= '1' when not is_x(tvalid) and not is_x(tready) else '0';

-- AXI4STREAM_ERRM_TDATA_STABLE TDATA remains stable when TVALID is asserted,
Expand Down
63 changes: 49 additions & 14 deletions vunit/vhdl/verification_components/test/tb_axi_stream.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,17 @@ architecture a of tb_axi_stream is

constant n_monitors : natural := 3;

signal aclk : std_logic := '0';
signal aclk : std_logic := '0';
signal areset_n : std_logic := '1';
signal tvalid : std_logic;
signal tready : std_logic;
signal tdata : std_logic_vector(data_length(slave_axi_stream)-1 downto 0);
signal tlast : std_logic;
signal tkeep : std_logic_vector(data_length(slave_axi_stream)/8-1 downto 0);
signal tstrb : std_logic_vector(data_length(slave_axi_stream)/8-1 downto 0);
signal tid : std_logic_vector(id_length(slave_axi_stream)-1 downto 0);
signal tdest : std_logic_vector(dest_length(slave_axi_stream)-1 downto 0);
signal tuser : std_logic_vector(user_length(slave_axi_stream)-1 downto 0);
signal tvalid : std_logic;
signal tready : std_logic;
signal tdata : std_logic_vector(data_length(slave_axi_stream)-1 downto 0);
signal tlast : std_logic;
signal tkeep, tkeep_from_master : std_logic_vector(data_length(slave_axi_stream)/8-1 downto 0);
signal tstrb, tstrb_from_master : std_logic_vector(data_length(slave_axi_stream)/8-1 downto 0);
signal tid : std_logic_vector(id_length(slave_axi_stream)-1 downto 0);
signal tdest : std_logic_vector(dest_length(slave_axi_stream)-1 downto 0);
signal tuser : std_logic_vector(user_length(slave_axi_stream)-1 downto 0);

signal not_valid : std_logic;
signal not_valid_data : std_logic;
Expand All @@ -89,6 +89,8 @@ architecture a of tb_axi_stream is
signal not_valid_dest : std_logic;
signal not_valid_user : std_logic;

signal connected_tkeep : boolean := true;
signal connected_tstrb : boolean := true;
-----------------------------------------------------------------------------
-- signals used for the statistics for stall evaluation
type axis_stall_stats_fields_t is record
Expand Down Expand Up @@ -230,6 +232,36 @@ begin
check_equal(axi_stream_transaction.tuser, std_logic_vector'(x"33"), result("pop stream user"));
end loop;

elsif run("test disconnecting tstrb and tkeep") then
for iter in 1 to 2 loop
connected_tstrb <= false;
connected_tkeep <= iter = 1;
if iter = 1 then
push_axi_stream(net, master_axi_stream, x"99", tlast => '1', tkeep => "1", tid => x"11", tdest => x"22", tuser => x"33" );
else
push_axi_stream(net, master_axi_stream, x"99", tlast => '1', tid => x"11", tdest => x"22", tuser => x"33" );
end if;
pop_axi_stream(net, slave_axi_stream, data, last, keep, strb, id, dest, user);
check_equal(data, std_logic_vector'(x"99"), result("pop axi stream data"));
check_equal(last, std_logic'('1'), result("pop stream last"));
check_equal(keep, std_logic_vector'("1"), result("pop stream keep"));
check_equal(strb, std_logic_vector'("1"), result("pop stream strb"));
check_equal(id, std_logic_vector'(x"11"), result("pop stream id"));
check_equal(dest, std_logic_vector'(x"22"), result("pop stream dest"));
check_equal(user, std_logic_vector'(x"33"), result("pop stream user"));

for i in 1 to n_monitors loop
get_axi_stream_transaction(axi_stream_transaction);
check_equal(axi_stream_transaction.tdata, std_logic_vector'(x"99"), result("for axi_stream_transaction.tdata"));
check_true(axi_stream_transaction.tlast, result("for axi_stream_transaction.tlast"));
check_equal(axi_stream_transaction.tkeep, std_logic_vector'("1"), result("pop stream keep"));
check_equal(axi_stream_transaction.tstrb, std_logic_vector'("1"), result("pop stream strb"));
check_equal(axi_stream_transaction.tid, std_logic_vector'(x"11"), result("pop stream id"));
check_equal(axi_stream_transaction.tdest, std_logic_vector'(x"22"), result("pop stream dest"));
check_equal(axi_stream_transaction.tuser, std_logic_vector'(x"33"), result("pop stream user"));
end loop;
end loop;

elsif run("test single stalled push and pop") then
wait until rising_edge(aclk);
wait_for_time(net, master_sync, 30 ns);
Expand Down Expand Up @@ -644,19 +676,22 @@ begin
tready => tready,
tdata => tdata,
tlast => tlast,
tkeep => tkeep,
tstrb => tstrb,
tkeep => tkeep_from_master,
tstrb => tstrb_from_master,
tid => tid,
tuser => tuser,
tdest => tdest);

tkeep <= tkeep_from_master when connected_tkeep else (others => '1');
tstrb <= tstrb_from_master when connected_tstrb else (others => 'U');

not_valid <= not tvalid;

not_valid_data <= '1' when is_x(tdata) else '0';
check_true(aclk, not_valid, not_valid_data, "Invalid data not X");
not_valid_keep <= '1' when is_x(tkeep) else '0';
not_valid_keep <= '1' when is_x(tkeep_from_master) else '0';
check_true(aclk, not_valid, not_valid_keep, "Invalid keep not X");
not_valid_strb <= '1' when is_x(tstrb) else '0';
not_valid_strb <= '1' when is_x(tstrb_from_master) else '0';
check_true(aclk, not_valid, not_valid_strb, "Invalid strb not X");
GEN_CHECK_INVALID_ID: if g_id_length > 0 generate
not_valid_id <= '1' when is_x(tid) else '0';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,10 @@ begin
procedure fail_unknown_test(
signal d: out std_logic_vector;
signal e1, e2: out std_logic;
constant rname : string; constant sname : string; constant e1name : string
constant rname : string;
constant sname : string;
constant e1name : string;
constant skip_meta_values : boolean_vector(meta_values'range) := (others => false)
) is
variable rule_logger : logger_t;
begin
Expand All @@ -214,6 +217,7 @@ begin
e1 <= '1';
e2 <= '1';
for i in meta_values'range loop
next when skip_meta_values(i);
d <= (d'range => meta_values(i));
wait until rising_edge(aclk);
wait for 1 ns;
Expand Down Expand Up @@ -543,9 +547,21 @@ begin
tkeep <= (others => '1');
pass_unknown_test(tstrb, tvalid, tready);

-- U is reolved to the value of tkeep and should not fail
tvalid <= '0';
tready <= '0';
wait until rising_edge(aclk);
tvalid <= '1';
tready <= '1';
tstrb <= (others => 'U');
wait until rising_edge(aclk);
wait for 1 ns;
check_no_log;

elsif run("Test failing check of that tstrb must not be unknown when tvalid is high") then
tkeep <= (others => '1');
fail_unknown_test(tstrb, tvalid, tready, ":rule 18", "tstrb", "tvalid");
-- U is reolved to the value of tkeep and should not fail
fail_unknown_test(tstrb, tvalid, tready, ":rule 18", "tstrb", "tvalid", skip_meta_values => (5 => true, others => false));

elsif run("Test passing check of that tkeep must not be unknown when tvalid is high") then
pass_unknown_test(tkeep, tvalid, tready);
Expand Down

0 comments on commit 4df4223

Please sign in to comment.