Skip to content

Commit ac0952b

Browse files
committed
uart vc: add testbenches/test cases
1 parent 2fc01ff commit ac0952b

6 files changed

Lines changed: 113 additions & 11 deletions

File tree

examples/vhdl/uart/run.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,14 @@
2727
VU.add_library("uart_lib").add_source_files(SRC_PATH / "*.vhd")
2828
VU.add_library("tb_uart_lib").add_source_files(SRC_PATH / "test" / "*.vhd")
2929

30+
for tb in VU.library("tb_uart_lib").get_test_benches():
31+
for parity in [0, 1, 2]:
32+
generics = dict(
33+
parity=parity
34+
)
35+
tb.add_config(
36+
name=",".join("{}={}".format(k, v) for (k, v) in generics.items()),
37+
generics=generics,
38+
)
39+
3040
VU.main()

examples/vhdl/uart/src/test/tb_uart_rx.vhd

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ library uart_lib;
1616

1717
entity tb_uart_rx is
1818
generic (
19-
runner_cfg : string);
19+
runner_cfg : string;
20+
parity : natural);
2021
end entity;
2122

2223
architecture tb of tb_uart_rx is
@@ -33,7 +34,8 @@ architecture tb of tb_uart_rx is
3334

3435
signal num_overflows : integer := 0;
3536

36-
constant uart_bfm : uart_master_t := new_uart_master(initial_baud_rate => baud_rate);
37+
constant uart_bfm : uart_master_t := new_uart_master(initial_baud_rate => baud_rate,
38+
initial_parity => parity);
3739
constant uart_stream : stream_master_t := as_stream(uart_bfm);
3840

3941
constant axi_stream_bfm : axi_stream_slave_t := new_axi_stream_slave(data_length => tdata'length);
@@ -87,7 +89,8 @@ begin
8789

8890
dut : entity uart_lib.uart_rx
8991
generic map (
90-
cycles_per_bit => cycles_per_bit)
92+
cycles_per_bit => cycles_per_bit,
93+
parity => parity)
9194
port map (
9295
clk => clk,
9396
rx => rx,

examples/vhdl/uart/src/test/tb_uart_tx.vhd

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ library uart_lib;
1919

2020
entity tb_uart_tx is
2121
generic (
22-
runner_cfg : string);
22+
runner_cfg : string;
23+
parity : natural);
2324
end entity;
2425

2526
architecture tb of tb_uart_tx is
@@ -35,6 +36,7 @@ architecture tb of tb_uart_tx is
3536

3637
shared variable rnd_stimuli, rnd_expected : RandomPType;
3738
constant uart_bfm : uart_slave_t := new_uart_slave(initial_baud_rate => baud_rate,
39+
initial_parity => parity,
3840
data_length => tdata'length);
3941
constant uart_stream : stream_slave_t := as_stream(uart_bfm);
4042

@@ -79,7 +81,8 @@ begin
7981

8082
dut : entity uart_lib.uart_tx
8183
generic map (
82-
cycles_per_bit => cycles_per_bit)
84+
cycles_per_bit => cycles_per_bit,
85+
parity => parity)
8386
port map (
8487
clk => clk,
8588
tx => tx,

examples/vhdl/uart/src/uart_rx.vhd

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ use vunit_lib.logger_pkg.all;
1515

1616
entity uart_rx is
1717
generic (
18-
cycles_per_bit : natural := 434);
18+
cycles_per_bit : natural := 434;
19+
parity : natural := 0);
1920
port (
2021
clk : in std_logic;
2122

@@ -29,6 +30,7 @@ entity uart_rx is
2930
tvalid : out std_Logic := '0';
3031
tdata : out std_logic_vector(7 downto 0));
3132
begin
33+
3234
-- pragma translate_off
3335
check_stable(clk, check_enabled, tvalid, tready, tdata, "tdata must be stable until tready is active");
3436
check_stable(clk, check_enabled, tvalid, tready, tvalid, "tvalid must be active until tready is active");
@@ -46,12 +48,30 @@ end entity;
4648

4749
architecture a of uart_rx is
4850
signal tvalid_int : std_logic := '0';
51+
52+
function data_size(
53+
constant parity: natural
54+
) return natural is
55+
begin
56+
if parity = 0 then
57+
-- uart data (8 bits)
58+
return 8;
59+
elsif parity = 1 or parity = 2 then
60+
-- uart data (8 bits)+ parity
61+
return 9;
62+
else
63+
-- invalid mode
64+
return 0;
65+
end if;
66+
end function data_size;
67+
4968
begin
5069
main : process (clk)
5170
type state_t is (idle, receiving, done);
5271
variable state : state_t := idle;
72+
variable datawidth : natural := data_size(parity);
5373
variable cycles : natural range 0 to cycles_per_bit-1 := 0;
54-
variable data : std_logic_vector(7 downto 0);
74+
variable data : std_logic_vector(datawidth-1 downto 0);
5575
variable index : natural range 0 to data'length-1 := 0;
5676
begin
5777
if rising_edge(clk) then
@@ -89,7 +109,7 @@ begin
89109
-- New output overwrites old output
90110
overflow <= tvalid_int and not tready;
91111
tvalid_int <= '1';
92-
tdata <= data;
112+
tdata <= data(7 downto 0);
93113
state := idle;
94114
end case;
95115

examples/vhdl/uart/src/uart_tx.vhd

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ use vunit_lib.logger_pkg.all;
1515

1616
entity uart_tx is
1717
generic (
18-
cycles_per_bit : natural := 434);
18+
cycles_per_bit : natural := 434;
19+
parity : natural := 0);
1920
port (
2021
clk : in std_logic;
2122

@@ -44,12 +45,42 @@ end entity;
4445

4546
architecture a of uart_tx is
4647
signal tready_int : std_logic := '0';
48+
49+
function data_size(
50+
constant parity: natural
51+
) return natural is
52+
begin
53+
if parity = 0 then
54+
-- uart data (8 bits)
55+
return 8;
56+
elsif parity = 1 or parity = 2 then
57+
-- uart data (8 bits)+ parity
58+
return 9;
59+
else
60+
-- invalid mode
61+
return 0;
62+
end if;
63+
end function data_size;
64+
65+
function even_parity (data : std_logic_vector) return std_logic is
66+
begin
67+
return xor data;
68+
69+
end function even_parity;
70+
71+
function odd_parity (data : std_logic_vector) return std_logic is
72+
begin
73+
74+
return xnor data;
75+
end function odd_parity;
76+
4777
begin
4878
main : process (clk)
4979
type state_t is (idle, sending);
5080
variable state : state_t := idle;
81+
variable datawidth : natural := data_size(parity) + 2;
5182
variable cycles : natural range 0 to cycles_per_bit-1 := 0;
52-
variable data : std_logic_vector(9 downto 0);
83+
variable data : std_logic_vector(datawidth-1 downto 0);
5384
variable index : natural range 0 to data'length-1 := 0;
5485
begin
5586
if rising_edge(clk) then
@@ -60,7 +91,14 @@ begin
6091
state := sending;
6192
cycles := 0;
6293
index := 0;
63-
data := '1' & tdata & '0';
94+
95+
if parity = 0 then
96+
data := '1' & tdata & '0';
97+
elsif parity = 1 then
98+
data := '1' & odd_parity(tdata) & tdata & '0';
99+
elsif parity = 2 then
100+
data := '1' & even_parity(tdata) & tdata & '0';
101+
end if;
64102
end if;
65103
when sending =>
66104
tx <= data(0);

vunit/vhdl/verification_components/test/tb_uart.vhd

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ architecture a of tb_uart is
2727
constant slave_uart : uart_slave_t := new_uart_slave(data_length => 8);
2828
constant slave_stream : stream_slave_t := as_stream(slave_uart);
2929

30+
-- parity related VCs
31+
constant master_uart_p : uart_master_t := new_uart_master;
32+
constant master_stream_p : stream_master_t := as_stream(master_uart);
33+
34+
constant slave_uart_p : uart_slave_t := new_uart_slave(data_length => 8);
35+
constant slave_stream_p : stream_slave_t := as_stream(slave_uart);
3036
signal chan : std_logic;
3137
begin
3238

@@ -83,6 +89,28 @@ begin
8389
test_baud_rate(2000);
8490
test_baud_rate(7000);
8591
test_baud_rate(200000);
92+
elsif run("test_parity_odd") then
93+
set_parity(net, master_uart_p, 1);
94+
set_parity(net, slave_uart_p, 1);
95+
96+
for i in 0 to 7 loop
97+
push_stream(net, master_stream_p,
98+
std_logic_vector(to_unsigned(i+1, data'length)));
99+
pop_stream(net, slave_stream_p, data);
100+
check_equal(data, std_logic_vector(to_unsigned(i+1, data'length)), "pop stream data");
101+
end loop;
102+
103+
elsif run("test_parity_even") then
104+
set_parity(net, master_uart_p, 2);
105+
set_parity(net, slave_uart_p, 2);
106+
107+
for i in 0 to 7 loop
108+
push_stream(net, master_stream_p,
109+
std_logic_vector(to_unsigned(i+1, data'length)));
110+
pop_stream(net, slave_stream_p, data);
111+
check_equal(data, std_logic_vector(to_unsigned(i+1, data'length)), "pop stream data");
112+
end loop;
113+
86114
end if;
87115

88116
test_runner_cleanup(runner);

0 commit comments

Comments
 (0)