Skip to content

Commit

Permalink
Added AXI stream protocol checker
Browse files Browse the repository at this point in the history
  • Loading branch information
LarsAsplund committed Aug 2, 2018
1 parent 1055126 commit 605e144
Show file tree
Hide file tree
Showing 6 changed files with 758 additions and 45 deletions.
3 changes: 3 additions & 0 deletions vunit/vhdl/run/src/run_api.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -149,4 +149,7 @@ package run_pkg is
alias test_runner_cleanup_entry_gate is entry_gate[runner_sync_t];
alias test_runner_cleanup_exit_gate is exit_gate[runner_sync_t];

-- Private
procedure notify(signal runner : inout runner_sync_t);

end package;
11 changes: 11 additions & 0 deletions vunit/vhdl/verification_components/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,16 @@ def gen_avalon_master_tests(obj, *args):
for test in tb_wishbone_master.get_tests():
gen_wb_tests(test, [8, 32], [1, 64], [0.3, 1.0], [0.3, 1.0], [0.4, 0.0])

tb_axi_stream_protocol_checker = lib.test_bench("tb_axi_stream_protocol_checker")

for data_length in [0, 8]:
for test in tb_axi_stream_protocol_checker.get_tests("*passing*tdata*"):
test.add_config(name="data_length=%d" % data_length, generics=dict(data_length=data_length))

test_failing_max_waits = tb_axi_stream_protocol_checker.test(
"Test failing check of that tready comes within max_waits after valid")
for max_waits in [0, 8]:
test_failing_max_waits.add_config(name="max_waits=%d" % max_waits, generics=dict(max_waits=max_waits))


ui.main()
100 changes: 64 additions & 36 deletions vunit/vhdl/verification_components/src/axi_stream_pkg.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,18 @@ package axi_stream_pkg is
p_logger : logger_t;
end record;

type axi_stream_protocol_checker_t is record
p_actor : actor_t;
p_data_length : natural;
p_logger : logger_t;
p_max_waits : natural;
end record;

constant null_axi_stream_monitor : axi_stream_monitor_t := (
p_data_length => natural'high,
p_logger => null_logger,
p_actor => null_actor
);
);

type axi_stream_master_t is record
p_actor : actor_t;
Expand All @@ -51,37 +58,42 @@ package axi_stream_pkg is
logger : logger_t := axi_stream_logger;
actor : actor_t := null_actor;
monitor : axi_stream_monitor_t := null_axi_stream_monitor
) return axi_stream_master_t;
) return axi_stream_master_t;
impure function new_axi_stream_master_with_monitor(data_length : natural;
logger : logger_t := axi_stream_logger;
actor : actor_t
) return axi_stream_master_t;
) return axi_stream_master_t;
impure function new_axi_stream_slave(data_length : natural;
logger : logger_t := axi_stream_logger;
actor : actor_t := null_actor;
monitor : axi_stream_monitor_t := null_axi_stream_monitor
) return axi_stream_slave_t;
) return axi_stream_slave_t;
impure function new_axi_stream_slave_with_monitor(data_length : natural;
logger : logger_t := axi_stream_logger;
actor : actor_t
) return axi_stream_slave_t;
) return axi_stream_slave_t;
impure function new_axi_stream_monitor(data_length : natural;
logger : logger_t := axi_stream_logger;
actor : actor_t) return axi_stream_monitor_t;
impure function data_length(master : axi_stream_master_t) return natural;
impure function data_length(slave : axi_stream_slave_t) return natural;
impure function data_length(monitor : axi_stream_monitor_t) return natural;
impure function as_stream(master : axi_stream_master_t) return stream_master_t;
impure function as_stream(slave : axi_stream_slave_t) return stream_slave_t;
impure function as_sync(master : axi_stream_master_t) return sync_handle_t;
impure function new_axi_stream_protocol_checker(data_length : natural;
logger : logger_t := axi_stream_logger;
actor : actor_t;
max_waits : natural := 16) return axi_stream_protocol_checker_t;
impure function data_length(master : axi_stream_master_t) return natural;
impure function data_length(slave : axi_stream_slave_t) return natural;
impure function data_length(monitor : axi_stream_monitor_t) return natural;
impure function data_length(protocol_checker : axi_stream_protocol_checker_t) return natural;
impure function as_stream(master : axi_stream_master_t) return stream_master_t;
impure function as_stream(slave : axi_stream_slave_t) return stream_slave_t;
impure function as_sync(master : axi_stream_master_t) return sync_handle_t;

constant push_axi_stream_msg : msg_type_t := new_msg_type("push axi stream");
constant axi_stream_transaction_msg : msg_type_t := new_msg_type("axi stream transaction");

procedure push_axi_stream(signal net : inout network_t;
axi_stream : axi_stream_master_t;
tdata : std_logic_vector;
tlast : std_logic := '1');
axi_stream : axi_stream_master_t;
tdata : std_logic_vector;
tlast : std_logic := '1');

type axi_stream_transaction_t is record
tdata : std_logic_vector;
Expand All @@ -90,36 +102,36 @@ package axi_stream_pkg is

procedure push_axi_stream_transaction(msg : msg_t; axi_stream_transaction : axi_stream_transaction_t);
procedure pop_axi_stream_transaction(
constant msg : in msg_t;
constant msg : in msg_t;
variable axi_stream_transaction : out axi_stream_transaction_t
);
);

impure function new_axi_stream_transaction_msg(
axi_stream_transaction : axi_stream_transaction_t
) return msg_t;
) return msg_t;

procedure handle_axi_stream_transaction(
variable msg_type : inout msg_type_t;
variable msg : inout msg_t;
variable axi_transaction : out axi_stream_transaction_t);
variable axi_transaction : out axi_stream_transaction_t);

end package;

package body axi_stream_pkg is

impure function new_axi_stream_master(data_length : natural;
logger : logger_t := axi_stream_logger;
actor : actor_t := null_actor;
logger : logger_t := axi_stream_logger;
actor : actor_t := null_actor;
monitor : axi_stream_monitor_t := null_axi_stream_monitor
) return axi_stream_master_t is
) return axi_stream_master_t is
variable p_actor : actor_t;
begin
check_implication(
axi_stream_checker,
monitor /= null_axi_stream_monitor,
monitor.p_data_length = data_length,
"Data length of monitor doesn't match that of the master"
);
);
p_actor := actor when actor /= null_actor else new_actor;

return (p_actor => p_actor,
Expand All @@ -131,24 +143,24 @@ package body axi_stream_pkg is
impure function new_axi_stream_master_with_monitor(data_length : natural;
logger : logger_t := axi_stream_logger;
actor : actor_t
) return axi_stream_master_t is
) return axi_stream_master_t is
begin
return new_axi_stream_master(data_length, logger, actor, new_axi_stream_monitor(data_length, logger, actor));
end;

impure function new_axi_stream_slave(data_length : natural;
logger : logger_t := axi_stream_logger;
actor : actor_t := null_actor;
logger : logger_t := axi_stream_logger;
actor : actor_t := null_actor;
monitor : axi_stream_monitor_t := null_axi_stream_monitor
) return axi_stream_slave_t is
) return axi_stream_slave_t is
variable p_actor : actor_t;
begin
check_implication(
axi_stream_checker,
monitor /= null_axi_stream_monitor,
monitor.p_data_length = data_length,
"Data length of monitor doesn't match that of the master"
);
);
p_actor := actor when actor /= null_actor else new_actor;

return (p_actor => p_actor,
Expand All @@ -160,21 +172,32 @@ package body axi_stream_pkg is
impure function new_axi_stream_slave_with_monitor(data_length : natural;
logger : logger_t := axi_stream_logger;
actor : actor_t
) return axi_stream_slave_t is
) return axi_stream_slave_t is
begin
return new_axi_stream_slave(data_length, logger, actor, new_axi_stream_monitor(data_length, logger, actor));
end;

impure function new_axi_stream_monitor(data_length : natural;
logger : logger_t := axi_stream_logger;
actor : actor_t
) return axi_stream_monitor_t is
) return axi_stream_monitor_t is
begin
return (p_actor => actor,
p_data_length => data_length,
p_logger => logger);
end;

impure function new_axi_stream_protocol_checker(data_length : natural;
logger : logger_t := axi_stream_logger;
actor : actor_t;
max_waits : natural := 16) return axi_stream_protocol_checker_t is
begin
return (p_actor => actor,
p_data_length => data_length,
p_logger => logger,
p_max_waits => max_waits);
end;

impure function data_length(master : axi_stream_master_t) return natural is
begin
return master.p_data_length;
Expand All @@ -190,6 +213,11 @@ package body axi_stream_pkg is
return monitor.p_data_length;
end;

impure function data_length(protocol_checker : axi_stream_protocol_checker_t) return natural is
begin
return protocol_checker.p_data_length;
end;

impure function as_stream(master : axi_stream_master_t) return stream_master_t is
begin
return (p_actor => master.p_actor);
Expand All @@ -206,9 +234,9 @@ package body axi_stream_pkg is
end;

procedure push_axi_stream(signal net : inout network_t;
axi_stream : axi_stream_master_t;
tdata : std_logic_vector;
tlast : std_logic := '1') is
axi_stream : axi_stream_master_t;
tdata : std_logic_vector;
tlast : std_logic := '1') is
variable msg : msg_t := new_msg(push_axi_stream_msg);
constant normalized_data : std_logic_vector(tdata'length - 1 downto 0) := tdata;
begin
Expand All @@ -224,17 +252,17 @@ package body axi_stream_pkg is
end;

procedure pop_axi_stream_transaction(
constant msg : in msg_t;
constant msg : in msg_t;
variable axi_stream_transaction : out axi_stream_transaction_t
) is
) is
begin
axi_stream_transaction.tdata := pop_std_ulogic_vector(msg);
axi_stream_transaction.tlast := pop_boolean(msg);
end;

impure function new_axi_stream_transaction_msg(
axi_stream_transaction : axi_stream_transaction_t
) return msg_t is
) return msg_t is
variable msg : msg_t;
begin
msg := new_msg(axi_stream_transaction_msg);
Expand All @@ -246,7 +274,7 @@ package body axi_stream_pkg is
procedure handle_axi_stream_transaction(
variable msg_type : inout msg_type_t;
variable msg : inout msg_t;
variable axi_transaction : out axi_stream_transaction_t) is
variable axi_transaction : out axi_stream_transaction_t) is
begin
if msg_type = axi_stream_transaction_msg then
handle_message(msg_type);
Expand Down
Loading

0 comments on commit 605e144

Please sign in to comment.