Skip to content

Commit ad8dbf2

Browse files
committed
Added VHDL configuration examples.
1 parent d1330d6 commit ad8dbf2

12 files changed

Lines changed: 677 additions & 0 deletions
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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-2021, Lars Asplund lars.anders.asplund@gmail.com
6+
library ieee;
7+
use ieee.std_logic_1164.all;
8+
9+
entity dff is
10+
generic(
11+
width : positive := 8
12+
);
13+
port(
14+
clk : in std_logic;
15+
reset : in std_logic;
16+
d : in std_logic_vector(width - 1 downto 0);
17+
q : out std_logic_vector(width - 1 downto 0)
18+
);
19+
end;
20+
21+
architecture rtl of dff is
22+
begin
23+
process(clk) is
24+
begin
25+
if rising_edge(clk) then
26+
if reset = '1' then
27+
q <= (others => '0');
28+
else
29+
q <= d;
30+
end if;
31+
end if;
32+
end process;
33+
end;
34+
35+
configuration dff_rtl of tb_selecting_dut_with_vhdl_configuration is
36+
for tb
37+
for test_fixture
38+
for dut : dff
39+
use entity work.dff(rtl);
40+
end for;
41+
end for;
42+
end for;
43+
end;
44+
45+
architecture behavioral of dff is
46+
begin
47+
process
48+
begin
49+
wait until rising_edge(clk);
50+
q <= (others => '0') when reset else d;
51+
end process;
52+
end;
53+
54+
configuration dff_behavioral of tb_selecting_dut_with_vhdl_configuration is
55+
for tb
56+
for test_fixture
57+
for dut : dff
58+
use entity work.dff(behavioral);
59+
end for;
60+
end for;
61+
end for;
62+
end;
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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-2021, Lars Asplund lars.anders.asplund@gmail.com
6+
--
7+
-- Description: Instead of having a testbench containing a shared test fixture
8+
-- and then use VHDL configurations to select different test runners implementing
9+
-- different tests one can flip things upside down. Each test become a separate
10+
-- top-level testbench and the shared test fixture is placed in a separate entity
11+
-- imported by each tetbench.
12+
13+
library vunit_lib;
14+
context vunit_lib.vunit_context;
15+
16+
library ieee;
17+
use ieee.std_logic_1164.all;
18+
19+
entity tb_reset is
20+
generic(
21+
runner_cfg : string;
22+
width : positive
23+
);
24+
end entity;
25+
26+
architecture tb of tb_reset is
27+
constant clk_period : time := 10 ns;
28+
29+
signal reset : std_logic;
30+
signal clk : std_logic;
31+
signal d : std_logic_vector(width - 1 downto 0);
32+
signal q : std_logic_vector(width - 1 downto 0);
33+
begin
34+
text_fixture_inst : entity work.test_fixture
35+
generic map(
36+
width => width,
37+
clk_period => clk_period
38+
)
39+
port map(
40+
clk => clk,
41+
reset => reset,
42+
d => d,
43+
q => q
44+
);
45+
46+
test_runner : process
47+
begin
48+
test_runner_setup(runner, runner_cfg);
49+
50+
d <= (others => '1');
51+
reset <= '1';
52+
wait until rising_edge(clk);
53+
wait for 0 ns;
54+
check_equal(q, 0);
55+
56+
test_runner_cleanup(runner);
57+
end process;
58+
59+
end architecture;
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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-2021, Lars Asplund lars.anders.asplund@gmail.com
6+
--
7+
-- Description: This is an example of a testbench using a generic instead
8+
-- of VHDL configurations to select the DUT to run. Without VHDL configurations
9+
-- the width generic to the dff entity can be exposed and modified at the top-level
10+
11+
library vunit_lib;
12+
context vunit_lib.vunit_context;
13+
14+
library ieee;
15+
use ieee.std_logic_1164.all;
16+
17+
entity tb_selecting_dut_with_generate_statement is
18+
generic(
19+
runner_cfg : string;
20+
width : positive;
21+
dff_arch : string
22+
);
23+
end entity;
24+
25+
architecture tb of tb_selecting_dut_with_generate_statement is
26+
constant clk_period : time := 10 ns;
27+
28+
signal reset : std_logic;
29+
signal clk : std_logic := '0';
30+
signal d : std_logic_vector(width - 1 downto 0);
31+
signal q : std_logic_vector(width - 1 downto 0);
32+
begin
33+
test_runner : process
34+
begin
35+
test_runner_setup(runner, runner_cfg);
36+
37+
while test_suite loop
38+
if run("Test reset") then
39+
d <= (others => '1');
40+
reset <= '1';
41+
wait until rising_edge(clk);
42+
wait for 0 ns;
43+
check_equal(q, 0);
44+
45+
elsif run("Test state change") then
46+
reset <= '0';
47+
48+
d <= (others => '1');
49+
wait until rising_edge(clk);
50+
wait for 0 ns;
51+
check_equal(q, std_logic_vector'(q'range => '1'));
52+
53+
d <= (others => '0');
54+
wait until rising_edge(clk);
55+
wait for 0 ns;
56+
check_equal(q, 0);
57+
end if;
58+
end loop;
59+
60+
test_runner_cleanup(runner);
61+
end process;
62+
63+
test_fixture : block is
64+
begin
65+
clk <= not clk after clk_period / 2;
66+
67+
dut_selection : if dff_arch = "rtl" generate
68+
dut : entity work.dff(rtl)
69+
generic map(
70+
width => width
71+
)
72+
port map(
73+
clk => clk,
74+
reset => reset,
75+
d => d,
76+
q => q
77+
);
78+
79+
elsif dff_arch = "behavioral" generate
80+
dut : entity work.dff(behavioral)
81+
generic map(
82+
width => width
83+
)
84+
port map(
85+
clk => clk,
86+
reset => reset,
87+
d => d,
88+
q => q
89+
);
90+
91+
else generate
92+
error("Unknown DFF architecture");
93+
end generate;
94+
end block;
95+
end architecture;
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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-2021, Lars Asplund lars.anders.asplund@gmail.com
6+
--
7+
-- Description: Instead of having a testbench containing a shared test fixture
8+
-- and then use VHDL configurations to select different test runners implementing
9+
-- different tests one can flip things upside down. Each test become a separate
10+
-- top-level testbench and the shared test fixture is placed in a separate entity
11+
-- imported by each tetbench.
12+
13+
library vunit_lib;
14+
context vunit_lib.vunit_context;
15+
16+
library ieee;
17+
use ieee.std_logic_1164.all;
18+
19+
entity tb_state_change is
20+
generic(
21+
runner_cfg : string;
22+
width : positive
23+
);
24+
end entity;
25+
26+
architecture tb of tb_state_change is
27+
constant clk_period : time := 10 ns;
28+
29+
signal reset : std_logic;
30+
signal clk : std_logic;
31+
signal d : std_logic_vector(width - 1 downto 0);
32+
signal q : std_logic_vector(width - 1 downto 0);
33+
begin
34+
text_fixture_inst : entity work.test_fixture
35+
generic map(
36+
width => width,
37+
clk_period => clk_period
38+
)
39+
port map(
40+
clk => clk,
41+
reset => reset,
42+
d => d,
43+
q => q
44+
);
45+
46+
test_runner : process
47+
begin
48+
test_runner_setup(runner, runner_cfg);
49+
50+
reset <= '0';
51+
52+
d <= (others => '1');
53+
wait until rising_edge(clk);
54+
wait for 0 ns;
55+
check_equal(q, std_logic_vector'(q'range => '1'));
56+
57+
d <= (others => '0');
58+
wait until rising_edge(clk);
59+
wait for 0 ns;
60+
check_equal(q, 0);
61+
62+
test_runner_cleanup(runner);
63+
end process;
64+
65+
end architecture;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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-2021, Lars Asplund lars.anders.asplund@gmail.com
6+
7+
library ieee;
8+
use ieee.std_logic_1164.all;
9+
10+
entity test_fixture is
11+
generic(
12+
width : positive := 8;
13+
clk_period : time
14+
);
15+
port(
16+
clk : out std_logic := '0';
17+
reset : in std_logic;
18+
d : in std_logic_vector(width - 1 downto 0);
19+
q : out std_logic_vector(width - 1 downto 0)
20+
);
21+
end entity;
22+
23+
architecture tb of test_fixture is
24+
begin
25+
clk <= not clk after clk_period / 2;
26+
27+
dut : entity work.dff(rtl)
28+
generic map(
29+
width => width
30+
)
31+
port map(
32+
clk => clk,
33+
reset => reset,
34+
d => d,
35+
q => q
36+
);
37+
38+
end architecture;
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/usr/bin/env python3
2+
3+
# This Source Code Form is subject to the terms of the Mozilla Public
4+
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
5+
# You can obtain one at http://mozilla.org/MPL/2.0/.
6+
#
7+
# Copyright (c) 2014-2021, Lars Asplund lars.anders.asplund@gmail.com
8+
9+
from pathlib import Path
10+
from vunit import VUnit
11+
from vunit.json4vhdl import encode_json, b16encode
12+
13+
vu = VUnit.from_argv(compile_builtins=False)
14+
vu.add_vhdl_builtins()
15+
lib = vu.add_library("lib")
16+
lib.add_source_files(Path(__file__).parent / "*.vhd")
17+
lib.add_source_files(Path(__file__).parent / "handling_generics_limitation" / "*.vhd")
18+
19+
# VHDL configurations are detected automatically and are treated as a special
20+
# case of the broader VUnit configuration concept. As such the configuration
21+
# can be extended beyond the capabilities of a pure VHDL configuration. For example,
22+
# by adding a post_check function. The exception is generics since VHDL doesn't allow
23+
# generics to be combined with configurations. Workarounds for this limitation can be
24+
# found in the handling_generics_limitation directory
25+
26+
# Get the VHDL-defined configurations from test or testbench objects using a pattern matching
27+
# configurations of interest.
28+
tb = lib.test_bench("tb_selecting_dut_with_vhdl_configuration")
29+
configurations = tb.get_configs("dff_*")
30+
31+
# Remember to run the run script with the -v flag to see the message from the dummy post_check
32+
def post_check(output_path):
33+
print("Running post-check")
34+
35+
return True
36+
37+
38+
configurations.set_post_check(post_check)
39+
40+
# The testbenches in the handling_generics_limitation directory are examples of how the generics
41+
# limitation of VHDL configurations can be worked around. This allow us to create configurations
42+
# with different settings for the DUT width generic
43+
44+
# This testbench replaces VHDL configurations with generate statements
45+
tb = lib.test_bench("tb_selecting_dut_with_generate_statement")
46+
for width in [8, 32]:
47+
for arch in ["rtl", "behavioral"]:
48+
tb.add_config(name=f"dff_{arch}_width={width}", generics=dict(dff_arch=arch, width=width))
49+
50+
# Instead of having a testbench containing a shared test fixture
51+
# and then use VHDL configurations to select different test runners implementing
52+
# different tests one can flip things upside down. Each test become a separate
53+
# top-level testbench and the shared test fixture is placed in a separate entity
54+
# imported by each tetbench.
55+
for tb_name in ["tb_reset", "tb_state_change"]:
56+
tb = lib.test_bench(tb_name)
57+
for width in [8, 32]:
58+
tb.add_config(name=f"width={width}", generics=dict(width=width))
59+
60+
vu.main()

0 commit comments

Comments
 (0)