Skip to content

Commit b89e635

Browse files
LarsAsplundLars Asplund
authored andcommitted
WIP: Added VC template
1 parent 069ccde commit b89e635

5 files changed

Lines changed: 425 additions & 0 deletions

File tree

examples/vhdl/vc_foo_bar/run.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# This Source Code Form is subject to the terms of the Mozilla Public
2+
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
3+
# You can obtain one at http://mozilla.org/MPL/2.0/.
4+
#
5+
# Copyright (c) 2014-2019, Lars Asplund lars.anders.asplund@gmail.com
6+
7+
from os.path import join, dirname
8+
from vunit import VUnit
9+
10+
root = dirname(__file__)
11+
12+
ui = VUnit.from_argv()
13+
ui.add_com();
14+
ui.add_verification_components()
15+
16+
vc_foo_bar_lib = ui.add_library("vc_foo_bar_lib")
17+
vc_foo_bar_lib.add_source_files(join(root, "src", "*.vhd"))
18+
vc_foo_bar_lib.add_source_files(join(root, "test", "*.vhd"))
19+
20+
tb_compliance = vc_foo_bar_lib.test_bench("tb_compliance")
21+
test = tb_compliance.test("Test that the actor can be customized")
22+
test.set_generic("use_custom_actor", True)
23+
24+
test = tb_compliance.test("Test unexpected message handling")
25+
for fail_on_unexpected_msg_type in [False, True]:
26+
test.add_config(name="fail_on_unexpected_msg_type=%s" % str(fail_on_unexpected_msg_type),
27+
generics = dict(fail_on_unexpected_msg_type=fail_on_unexpected_msg_type, use_custom_actor=True))
28+
29+
test = tb_compliance.test("Test that the logger can be customized")
30+
test.set_generic("use_custom_actor", True)
31+
test.set_generic("use_custom_logger", True)
32+
33+
test = tb_compliance.test("Test that the checker can be customized")
34+
test.set_generic("use_custom_actor", True)
35+
test.set_generic("use_custom_checker", True)
36+
37+
ui.main()
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
-- This Source Code Form is subject to the terms of the Mozilla Public
2+
-- License, v. 2.0. If a copy of the MPL was not distributed with this file,
3+
-- You can obtain one at http://mozilla.org/MPL/2.0/.
4+
--
5+
-- Copyright (c) 2014-2019, Lars Asplund lars.anders.asplund@gmail.com
6+
7+
library vunit_lib;
8+
context vunit_lib.vunit_context;
9+
context vunit_lib.com_context;
10+
context vunit_lib.vc_context;
11+
12+
library ieee;
13+
use ieee.std_logic_1164.all;
14+
15+
use work.foo_bar_pkg.all;
16+
17+
-- foo_bar is a verification component (VC). foo is often an interface and bar a
18+
-- domain specific actor on such an interface. For example wishbone_master and
19+
-- avalon_source
20+
entity foo_bar is
21+
generic(
22+
foo_bar_h : foo_bar_handle_t -- foo_bar_h is the handle unique to every instance
23+
-- of foo_bar
24+
);
25+
port(
26+
-- Signals to connect to the foo interface. The clock is often generated
27+
-- externally (hence an input rather than an output)
28+
foo_clk : in std_logic;
29+
foo_input_on_dut : out std_logic;
30+
foo_output_on_dut : in std_logic
31+
);
32+
end entity;
33+
34+
architecture a of foo_bar is
35+
procedure transaction_1(arg_1 : integer; arg_2 : boolean) is
36+
begin
37+
-- Do some pin wiggling
38+
end;
39+
40+
procedure transaction_2(arg_1 : integer; arg_2 : boolean) is
41+
begin
42+
-- Do some pin wiggling
43+
end;
44+
begin
45+
46+
controller : process
47+
variable msg : msg_t;
48+
variable msg_type : msg_type_t;
49+
begin
50+
receive(net, foo_bar_h.p_actor, msg);
51+
52+
msg_type := message_type(msg);
53+
54+
-- The sync VCI is useful for any VC
55+
handle_sync_message(net, msg_type, msg);
56+
57+
if msg_type = transaction_1_msg then
58+
transaction_1(pop_integer(msg), pop_boolean(msg));
59+
60+
elsif msg_type = transaction_2_msg then
61+
transaction_2(pop_integer(msg), pop_boolean(msg));
62+
63+
elsif foo_bar_h.p_fail_on_unexpected_msg_type then
64+
unexpected_msg_type(msg_type, get_logger(foo_bar_h.p_checker));
65+
end if;
66+
end process;
67+
end architecture;
68+
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
-- This Source Code Form is subject to the terms of the Mozilla Public
2+
-- License, v. 2.0. If a copy of the MPL was not distributed with this file,
3+
-- You can obtain one at http://mozilla.org/MPL/2.0/.
4+
--
5+
-- Copyright (c) 2014-2019, Lars Asplund lars.anders.asplund@gmail.com
6+
7+
library vunit_lib;
8+
context vunit_lib.vunit_context;
9+
context vunit_lib.com_context;
10+
context vunit_lib.vc_context;
11+
12+
-- foo_bar_pkg defines the verification component interface (VCI)
13+
package foo_bar_pkg is
14+
-- The type of a VC instance handle. It contains the properties that can be
15+
-- configured when a new instance is created. p_* means that the content of
16+
-- the record is private and the user is not supposed to access these fields
17+
-- directly. It should be possible jto change the contents of the record
18+
-- without breaking backward compatibility.
19+
type foo_bar_handle_t is record
20+
p_actor : actor_t;
21+
p_logger : logger_t;
22+
p_checker : checker_t;
23+
p_fail_on_unexpected_msg_type : boolean;
24+
end record;
25+
26+
-- Transaction messages used to control the VC. Not used directly by a user of the VC.
27+
-- Someone writing another VC reusing this VCI would know about these messages.
28+
constant transaction_1_msg : msg_type_t := new_msg_type("transaction 1");
29+
constant transaction_2_msg : msg_type_t := new_msg_type("transaction 2");
30+
31+
-- Creates a new VC instance handle
32+
impure function new_foo_bar(
33+
logger : logger_t := null_logger;
34+
actor : actor_t := null_actor;
35+
checker : checker_t := null_checker;
36+
fail_on_unexpected_msg_type : boolean := true
37+
) return foo_bar_handle_t;
38+
39+
procedure transaction_1(
40+
signal net : inout network_t;
41+
foo_bar_h : foo_bar_handle_t;
42+
arg_1 : integer;
43+
arg_2 : boolean
44+
);
45+
46+
procedure transaction_2(
47+
signal net : inout network_t;
48+
foo_bar_h : foo_bar_handle_t;
49+
arg_1 : integer;
50+
arg_2 : boolean
51+
);
52+
53+
impure function as_sync(
54+
foo_bar_h : foo_bar_handle_t
55+
) return sync_handle_t;
56+
57+
end package;
58+
59+
package body foo_bar_pkg is
60+
impure function new_foo_bar(
61+
logger : logger_t := null_logger; -- Enables full control of reporting
62+
actor : actor_t := null_actor; -- Enables full control over messaging
63+
checker : checker_t := null_checker; -- Enables separation between error reporting and other reporting
64+
fail_on_unexpected_msg_type : boolean := true -- The presence of unexpected messages depends on the VC
65+
-- context so whether or not this is an error must be under user control.
66+
) return foo_bar_handle_t is
67+
variable p_logger : logger_t := logger;
68+
variable p_actor : actor_t := actor;
69+
variable p_checker : checker_t := checker;
70+
begin
71+
if logger = null_logger then
72+
p_logger := get_logger("foo_bar");
73+
end if;
74+
75+
if actor = null_actor then
76+
p_actor := new_actor;
77+
end if;
78+
79+
if checker = null_checker then
80+
if logger = null_logger then
81+
p_checker := new_checker(p_logger);
82+
else
83+
p_checker := new_checker(logger);
84+
end if;
85+
end if;
86+
87+
return (
88+
p_logger => p_logger,
89+
p_actor => p_actor,
90+
p_checker => p_checker,
91+
p_fail_on_unexpected_msg_type => fail_on_unexpected_msg_type
92+
);
93+
end;
94+
95+
procedure transaction_1(
96+
signal net : inout network_t;
97+
foo_bar_h : foo_bar_handle_t;
98+
arg_1 : integer;
99+
arg_2 : boolean
100+
) is
101+
variable msg : msg_t;
102+
begin
103+
msg := new_msg(transaction_1_msg);
104+
push(msg, arg_1);
105+
push(msg, arg_2);
106+
send(net, foo_bar_h.p_actor, msg);
107+
end procedure;
108+
109+
procedure transaction_2(
110+
signal net : inout network_t;
111+
foo_bar_h : foo_bar_handle_t;
112+
arg_1 : integer;
113+
arg_2 : boolean
114+
) is
115+
variable msg : msg_t;
116+
begin
117+
msg := new_msg(transaction_2_msg);
118+
push(msg, arg_1);
119+
push(msg, arg_2);
120+
send(net, foo_bar_h.p_actor, msg);
121+
end procedure;
122+
123+
impure function as_sync(foo_bar_h : foo_bar_handle_t) return sync_handle_t is
124+
begin
125+
return foo_bar_h.p_actor;
126+
end;
127+
128+
end package body;
129+
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
-- This Source Code Form is subject to the terms of the Mozilla Public
2+
-- License, v. 2.0. If a copy of the MPL was not distributed with this file,
3+
-- You can obtain one at http://mozilla.org/MPL/2.0/.
4+
--
5+
-- Copyright (c) 2014-2019, Lars Asplund lars.anders.asplund@gmail.com
6+
7+
library vunit_lib;
8+
context vunit_lib.vunit_context;
9+
context vunit_lib.vc_context;
10+
11+
library ieee;
12+
use ieee.std_logic_1164.all;
13+
use ieee.numeric_std.all;
14+
use ieee.numeric_std_unsigned.all;
15+
16+
library vc_foo_bar_lib;
17+
use vc_foo_bar_lib.foo_bar_pkg.all;
18+
19+
entity tb_compliance is
20+
generic(
21+
use_custom_logger : boolean := false;
22+
use_custom_actor : boolean := false;
23+
use_custom_checker : boolean := false;
24+
fail_on_unexpected_msg_type : boolean := true;
25+
runner_cfg : string
26+
);
27+
end entity;
28+
29+
architecture tb of tb_compliance is
30+
constant custom_actor : actor_t := new_actor("foo_bar", inbox_size => 1);
31+
constant custom_logger : logger_t := get_logger("custom logger");
32+
constant custom_checker : checker_t := new_checker("custom checker");
33+
34+
impure function create_handle return foo_bar_handle_t is
35+
variable logger : logger_t;
36+
variable actor : actor_t;
37+
variable checker : checker_t;
38+
begin
39+
logger := custom_logger when use_custom_logger else null_logger;
40+
actor := custom_actor when use_custom_actor else null_actor;
41+
checker := custom_checker when use_custom_checker else null_checker;
42+
43+
return new_foo_bar(
44+
logger => logger,
45+
actor => actor,
46+
checker => checker,
47+
fail_on_unexpected_msg_type => fail_on_unexpected_msg_type);
48+
end;
49+
50+
constant foo_bar_h : foo_bar_handle_t := create_handle;
51+
constant unexpected_msg : msg_type_t := new_msg_type("unexpected msg");
52+
53+
signal foo_clk : std_logic;
54+
signal foo_output_on_dut : std_logic;
55+
begin
56+
main : process
57+
variable t_start : time;
58+
variable msg : msg_t;
59+
constant default_logger : logger_t := get_logger("foo_bar");
60+
begin
61+
test_runner_setup(runner, runner_cfg);
62+
63+
while test_suite loop
64+
65+
if run("Test that the sync interface is supported") then
66+
t_start := now;
67+
wait_for_time(net, as_sync(foo_bar_h), 1 ns);
68+
wait_for_time(net, as_sync(foo_bar_h), 2 ns);
69+
wait_for_time(net, as_sync(foo_bar_h), 3 ns);
70+
check_equal(now - t_start, 0 ns);
71+
t_start := now;
72+
wait_until_idle(net, as_sync(foo_bar_h));
73+
check_equal(now - t_start, 6 ns);
74+
elsif run("Test that the actor can be customized") then
75+
t_start := now;
76+
wait_for_time(net, as_sync(foo_bar_h), 1 ns);
77+
wait_for_time(net, as_sync(foo_bar_h), 2 ns);
78+
check_equal(now - t_start, 0 ns);
79+
wait_for_time(net, as_sync(foo_bar_h), 3 ns);
80+
check_equal(now - t_start, 1 ns);
81+
wait_until_idle(net, as_sync(foo_bar_h));
82+
check_equal(now - t_start, 6 ns);
83+
elsif run("Test unexpected message handling") then
84+
mock(default_logger);
85+
msg := new_msg(unexpected_msg);
86+
send(net, custom_actor, msg);
87+
wait for 1 ns;
88+
if fail_on_unexpected_msg_type then
89+
check_only_log(default_logger, "Got unexpected message unexpected msg", failure);
90+
else
91+
check_no_log;
92+
end if;
93+
unmock(default_logger);
94+
elsif run("Test that the logger can be customized") then
95+
mock(custom_logger);
96+
msg := new_msg(unexpected_msg);
97+
send(net, custom_actor, msg);
98+
wait for 1 ns;
99+
check_only_log(custom_logger, "Got unexpected message unexpected msg", failure);
100+
unmock(custom_logger);
101+
elsif run("Test that the checker can be customized") then
102+
mock(get_logger(custom_checker));
103+
msg := new_msg(unexpected_msg);
104+
send(net, custom_actor, msg);
105+
wait for 1 ns;
106+
check_only_log(get_logger(custom_checker), "Got unexpected message unexpected msg", failure);
107+
unmock(get_logger(custom_checker));
108+
end if;
109+
end loop;
110+
111+
test_runner_cleanup(runner);
112+
end process;
113+
114+
vc_foo_bar : entity vc_foo_bar_lib.foo_bar
115+
generic map(
116+
foo_bar_h => foo_bar_h
117+
)
118+
port map(
119+
foo_clk => foo_clk,
120+
foo_input_on_dut => open,
121+
foo_output_on_dut => foo_output_on_dut
122+
);
123+
end architecture;

0 commit comments

Comments
 (0)