Skip to content

Commit 3438e5d

Browse files
committed
Add support for non-byte tdata widths in AXI stream VCs.
This is non-standard and must explicitly be enabled. The difference from the standard implementation is with respect to the length of tkeep and tstrb which is calculated as (tdata'length + 7) / 8 rather than tdata'length / 8 .
1 parent 4e30fa1 commit 3438e5d

File tree

9 files changed

+126
-56
lines changed

9 files changed

+126
-56
lines changed

docs/news.d/1127.feature.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
The AXI stream standard requires tdata to be a multiple of 8 bits. Updated AXI stream VCs to also support other bit widths.
2+
This affects tkeep and tstrb which widths are set to (tdata'length + 7) / 8 rather than tdata'length / 8. This new feature
3+
is disabled by default and is enabled by setting the allow_arbitrary_data_length to true in the VC constructor call.

vunit/vhdl/verification_components/run.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ def gen_avalon_master_tests(obj, *args):
134134
for id_length in [0, 8]:
135135
for dest_length in [0, 8]:
136136
for user_length in [0, 8]:
137-
for data_length in [8, 16]:
137+
for data_length in [3, 8, 11, 16]:
138138
for test in TB_AXI_STREAM.get_tests("*check"):
139139
test.add_config(
140140
name=f"id_l={id_length} dest_l={dest_length} user_l={user_length} data_l={data_length}",
@@ -150,7 +150,7 @@ def gen_avalon_master_tests(obj, *args):
150150

151151
TB_AXI_STREAM_PROTOCOL_CHECKER = LIB.test_bench("tb_axi_stream_protocol_checker")
152152

153-
for data_length in [0, 8, 32]:
153+
for data_length in [0, 3, 8, 11, 32]:
154154
for test in TB_AXI_STREAM_PROTOCOL_CHECKER.get_tests("*passing*tdata*"):
155155
test.add_config(name="data_length=%d" % data_length, generics=dict(data_length=data_length))
156156

vunit/vhdl/verification_components/src/axi_stream_master.vhd

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ entity axi_stream_master is
3737
tready : in std_logic := '1';
3838
tdata : out std_logic_vector(data_length(master)-1 downto 0) := (others => '0');
3939
tlast : out std_logic := '0';
40-
tkeep : out std_logic_vector(data_length(master)/8-1 downto 0) := (others => '1');
41-
tstrb : out std_logic_vector(data_length(master)/8-1 downto 0) := (others => '1');
40+
tkeep : out std_logic_vector(keep_strb_length(master)-1 downto 0) := (others => '1');
41+
tstrb : out std_logic_vector(keep_strb_length(master)-1 downto 0) := (others => '1');
4242
tid : out std_logic_vector(id_length(master)-1 downto 0) := (others => '0');
4343
tdest : out std_logic_vector(dest_length(master)-1 downto 0) := (others => '0');
4444
tuser : out std_logic_vector(user_length(master)-1 downto 0) := (others => '0')
@@ -55,8 +55,8 @@ architecture a of axi_stream_master is
5555

5656

5757
procedure drive_invalid_output(signal l_tdata : out std_logic_vector(data_length(master)-1 downto 0);
58-
signal l_tkeep : out std_logic_vector(data_length(master)/8-1 downto 0);
59-
signal l_tstrb : out std_logic_vector(data_length(master)/8-1 downto 0);
58+
signal l_tkeep : out std_logic_vector(keep_strb_length(master)-1 downto 0);
59+
signal l_tstrb : out std_logic_vector(keep_strb_length(master)-1 downto 0);
6060
signal l_tid : out std_logic_vector(id_length(master)-1 downto 0);
6161
signal l_tdest : out std_logic_vector(dest_length(master)-1 downto 0);
6262
signal l_tuser : out std_logic_vector(user_length(master)-1 downto 0))

vunit/vhdl/verification_components/src/axi_stream_monitor.vhd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ entity axi_stream_monitor is
2424
tready : in std_logic := '1';
2525
tdata : in std_logic_vector(data_length(monitor) - 1 downto 0);
2626
tlast : in std_logic := '1';
27-
tkeep : in std_logic_vector(data_length(monitor)/8-1 downto 0) := (others => '1');
28-
tstrb : in std_logic_vector(data_length(monitor)/8-1 downto 0) := (others => 'U');
27+
tkeep : in std_logic_vector(keep_strb_length(monitor)-1 downto 0) := (others => '1');
28+
tstrb : in std_logic_vector(keep_strb_length(monitor)-1 downto 0) := (others => 'U');
2929
tid : in std_logic_vector(id_length(monitor)-1 downto 0) := (others => '0');
3030
tdest : in std_logic_vector(dest_length(monitor)-1 downto 0) := (others => '0');
3131
tuser : in std_logic_vector(user_length(monitor)-1 downto 0) := (others => '0')

vunit/vhdl/verification_components/src/axi_stream_pkg.vhd

Lines changed: 95 additions & 32 deletions
Large diffs are not rendered by default.

vunit/vhdl/verification_components/src/axi_stream_protocol_checker.vhd

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ entity axi_stream_protocol_checker is
3030
tready : in std_logic := '1';
3131
tdata : in std_logic_vector(data_length(protocol_checker) - 1 downto 0);
3232
tlast : in std_logic := '1';
33-
tkeep : in std_logic_vector(data_length(protocol_checker)/8-1 downto 0) := (others => '1');
34-
tstrb : in std_logic_vector(data_length(protocol_checker)/8-1 downto 0) := (others => 'U');
33+
tkeep : in std_logic_vector(keep_strb_length(protocol_checker)-1 downto 0) := (others => '1');
34+
tstrb : in std_logic_vector(keep_strb_length(protocol_checker)-1 downto 0) := (others => 'U');
3535
tid : in std_logic_vector(id_length(protocol_checker)-1 downto 0) := (others => '0');
3636
tdest : in std_logic_vector(dest_length(protocol_checker)-1 downto 0) := (others => '0');
3737
tuser : in std_logic_vector(user_length(protocol_checker)-1 downto 0) := (others => '0')
@@ -85,7 +85,7 @@ architecture a of axi_stream_protocol_checker is
8585
ret := data;
8686
for i in keep'range loop
8787
if keep(i) = '0' or strb(i) = '0' then
88-
ret(i*8+7 downto i*8) := (others => '0');
88+
ret(minimum(i*8+7, ret'left) downto i*8) := (others => '0');
8989
end if;
9090
end loop;
9191
return ret;

vunit/vhdl/verification_components/src/axi_stream_slave.vhd

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ entity axi_stream_slave is
3434
tready : out std_logic := '0';
3535
tdata : in std_logic_vector(data_length(slave)-1 downto 0);
3636
tlast : in std_logic := '1';
37-
tkeep : in std_logic_vector(data_length(slave)/8-1 downto 0) := (others => '1');
38-
tstrb : in std_logic_vector(data_length(slave)/8-1 downto 0) := (others => 'U');
37+
tkeep : in std_logic_vector(keep_strb_length(slave)-1 downto 0) := (others => '1');
38+
tstrb : in std_logic_vector(keep_strb_length(slave)-1 downto 0) := (others => 'U');
3939
tid : in std_logic_vector(id_length(slave)-1 downto 0) := (others => '0');
4040
tdest : in std_logic_vector(dest_length(slave)-1 downto 0) := (others => '0');
4141
tuser : in std_logic_vector(user_length(slave)-1 downto 0) := (others => '0')
@@ -146,7 +146,8 @@ begin
146146
mismatch := false;
147147
for idx in tkeep'range loop
148148
if tkeep(idx) and tstrb_resolved(idx) then
149-
mismatch := tdata(8 * idx + 7 downto 8 * idx) /= expected_tdata(8 * idx + 7 downto 8 * idx);
149+
mismatch := tdata(minimum(8 * idx + 7, tdata'left) downto 8 * idx) /=
150+
expected_tdata(minimum(8 * idx + 7, tdata'left) downto 8 * idx);
150151
exit when mismatch;
151152
end if;
152153
end loop;

vunit/vhdl/verification_components/test/tb_axi_stream.vhd

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,29 +42,31 @@ architecture a of tb_axi_stream is
4242
constant master_axi_stream : axi_stream_master_t := new_axi_stream_master(
4343
data_length => g_data_length, id_length => g_id_length, dest_length => g_dest_length, user_length => g_user_length,
4444
stall_config => master_stall_config, logger => get_logger("master"), actor => new_actor("master"),
45-
monitor => default_axi_stream_monitor, protocol_checker => default_axi_stream_protocol_checker
45+
monitor => default_axi_stream_monitor, protocol_checker => default_axi_stream_protocol_checker,
46+
allow_arbitrary_data_length => g_data_length mod 8 /= 0
4647
);
4748
constant master_stream : stream_master_t := as_stream(master_axi_stream);
4849
constant master_sync : sync_handle_t := as_sync(master_axi_stream);
4950

5051
constant slave_axi_stream : axi_stream_slave_t := new_axi_stream_slave(
5152
data_length => g_data_length, id_length => g_id_length, dest_length => g_dest_length, user_length => g_user_length,
5253
stall_config => slave_stall_config, logger => get_logger("slave"), actor => new_actor("slave"),
53-
monitor => default_axi_stream_monitor, protocol_checker => default_axi_stream_protocol_checker
54+
monitor => default_axi_stream_monitor, protocol_checker => default_axi_stream_protocol_checker,
55+
allow_arbitrary_data_length => g_data_length mod 8 /= 0
5456
);
5557
constant slave_stream : stream_slave_t := as_stream(slave_axi_stream);
5658
constant slave_sync : sync_handle_t := as_sync(slave_axi_stream);
5759

5860
constant monitor : axi_stream_monitor_t := new_axi_stream_monitor(
5961
data_length => g_data_length, id_length => g_id_length, dest_length => g_dest_length, user_length => g_user_length,
6062
logger => get_logger("monitor"), actor => new_actor("monitor"),
61-
protocol_checker => default_axi_stream_protocol_checker
63+
protocol_checker => default_axi_stream_protocol_checker,
64+
allow_arbitrary_data_length => g_data_length mod 8 /= 0
6265
);
6366

6467
constant protocol_checker : axi_stream_protocol_checker_t := new_axi_stream_protocol_checker(
6568
data_length => g_data_length, id_length => g_id_length, dest_length => g_dest_length, user_length => g_user_length,
66-
logger => get_logger("protocol_checker"),
67-
max_waits => 8
69+
logger => get_logger("protocol_checker"), max_waits => 8, allow_arbitrary_data_length => g_data_length mod 8 /= 0
6870
);
6971

7072
constant n_monitors : natural := 3;
@@ -75,8 +77,8 @@ architecture a of tb_axi_stream is
7577
signal tready : std_logic;
7678
signal tdata : std_logic_vector(data_length(slave_axi_stream)-1 downto 0);
7779
signal tlast : std_logic;
78-
signal tkeep, tkeep_from_master : std_logic_vector(data_length(slave_axi_stream)/8-1 downto 0);
79-
signal tstrb, tstrb_from_master : std_logic_vector(data_length(slave_axi_stream)/8-1 downto 0);
80+
signal tkeep, tkeep_from_master : std_logic_vector(keep_strb_length(slave_axi_stream)-1 downto 0);
81+
signal tstrb, tstrb_from_master : std_logic_vector(keep_strb_length(slave_axi_stream)-1 downto 0);
8082
signal tid : std_logic_vector(id_length(slave_axi_stream)-1 downto 0);
8183
signal tdest : std_logic_vector(dest_length(slave_axi_stream)-1 downto 0);
8284
signal tuser : std_logic_vector(user_length(slave_axi_stream)-1 downto 0);

vunit/vhdl/verification_components/test/tb_axi_stream_protocol_checker.vhd

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,15 @@ architecture a of tb_axi_stream_protocol_checker is
3535
signal tlast : std_logic := '1';
3636
signal tdest : std_logic_vector(dest_length - 1 downto 0) := (others => '0');
3737
signal tid : std_logic_vector(id_length - 1 downto 0) := (others => '0');
38-
signal tstrb : std_logic_vector(data_length/8 - 1 downto 0) := (others => '0');
39-
signal tkeep : std_logic_vector(data_length/8 - 1 downto 0) := (others => '0');
38+
signal tstrb : std_logic_vector((data_length + 7) / 8 - 1 downto 0) := (others => '0');
39+
signal tkeep : std_logic_vector((data_length + 7) / 8 - 1 downto 0) := (others => '0');
4040
signal tuser : std_logic_vector(user_length - 1 downto 0) := (others => '0');
4141

4242
constant logger : logger_t := get_logger("protocol_checker");
4343
constant protocol_checker : axi_stream_protocol_checker_t := new_axi_stream_protocol_checker(
4444
data_length => tdata'length, id_length => tid'length, dest_length => tdest'length, user_length => tuser'length,
45-
logger => logger, actor => new_actor("protocol_checker"), max_waits => max_waits, allow_x_in_non_data_bytes => true
45+
logger => logger, actor => new_actor("protocol_checker"), max_waits => max_waits, allow_x_in_non_data_bytes => true,
46+
allow_arbitrary_data_length => data_length mod 8 /= 0
4647
);
4748
constant meta_values : std_logic_vector(1 to 5) := "-XWZU";
4849
constant valid_values : std_logic_vector(1 to 4) := "01LH";

0 commit comments

Comments
 (0)