From 99fe60dee5186a7e99da7b71a57a0e859f06bd2e Mon Sep 17 00:00:00 2001 From: Rafael do Nascimento Pereira Date: Wed, 11 Mar 2026 23:10:44 +0100 Subject: [PATCH 1/7] uart vc: implement parity on uart_master --- .../src/uart_master.vhd | 24 +++++-- .../verification_components/src/uart_pkg.vhd | 69 ++++++++++++++++++- 2 files changed, 85 insertions(+), 8 deletions(-) diff --git a/vunit/vhdl/verification_components/src/uart_master.vhd b/vunit/vhdl/verification_components/src/uart_master.vhd index 0b2b49384..c183c98f1 100644 --- a/vunit/vhdl/verification_components/src/uart_master.vhd +++ b/vunit/vhdl/verification_components/src/uart_master.vhd @@ -17,10 +17,12 @@ use work.uart_pkg.all; entity uart_master is generic ( - uart : uart_master_t); + uart : uart_master_t + ); port ( - tx : out std_logic := uart.p_idle_state); -end entity; + tx : out std_logic := uart.p_idle_state + ); +end entity uart_master; architecture a of uart_master is begin @@ -28,7 +30,9 @@ begin main : process procedure uart_send(data : std_logic_vector; signal tx : out std_logic; - baud_rate : integer) is + baud_rate : integer; + parity : natural + ) is constant time_per_bit : time := (10**9 / baud_rate) * 1 ns; procedure send_bit(value : std_logic) is @@ -43,11 +47,19 @@ begin for i in 0 to data'length-1 loop send_bit(data(i)); end loop; + + if parity = 1 then + send_bit(odd_parity(data)); + elsif parity = 2 then + send_bit(even_parity(data)); + end if; + send_bit(uart.p_idle_state); end procedure; variable msg : msg_t; variable baud_rate : natural := uart.p_baud_rate; + variable parity : natural := uart.p_parity; variable msg_type : msg_type_t; begin receive(net, uart.p_actor, msg); @@ -56,9 +68,11 @@ begin handle_sync_message(net, msg_type, msg); if msg_type = stream_push_msg then - uart_send(pop_std_ulogic_vector(msg), tx, baud_rate); + uart_send(pop_std_ulogic_vector(msg), tx, baud_rate, parity); elsif msg_type = uart_set_baud_rate_msg then baud_rate := pop(msg); + elsif msg_type = uart_set_parity_msg then + parity := pop(msg); else unexpected_msg_type(msg_type); end if; diff --git a/vunit/vhdl/verification_components/src/uart_pkg.vhd b/vunit/vhdl/verification_components/src/uart_pkg.vhd index 690003b4f..86c5023a8 100644 --- a/vunit/vhdl/verification_components/src/uart_pkg.vhd +++ b/vunit/vhdl/verification_components/src/uart_pkg.vhd @@ -18,12 +18,14 @@ package uart_pkg is type uart_master_t is record p_actor : actor_t; p_baud_rate : natural; + p_parity : natural; p_idle_state : std_logic; - end record; + end record uart_master_t; type uart_slave_t is record p_actor : actor_t; p_baud_rate : natural; + p_parity : natural; p_idle_state : std_logic; p_data_length : positive; end record; @@ -37,12 +39,25 @@ package uart_pkg is uart_slave : uart_slave_t; baud_rate : natural); + -- 0 = no parity, 1 = odd parity, 2 = even parity + procedure set_parity(signal net : inout network_t; + uart_master : uart_master_t; + parity : natural); + + procedure set_parity(signal net : inout network_t; + uart_slave : uart_slave_t; + parity : natural); + constant default_baud_rate : natural := 115200; constant default_idle_state : std_logic := '1'; constant default_data_length : positive := 8; + constant default_parity : natural := 0; + impure function new_uart_master(initial_baud_rate : natural := default_baud_rate; + initial_parity : natural := default_parity; idle_state : std_logic := default_idle_state) return uart_master_t; impure function new_uart_slave(initial_baud_rate : natural := default_baud_rate; + initial_parity : natural := default_parity; idle_state : std_logic := default_idle_state; data_length : positive := default_data_length) return uart_slave_t; @@ -52,24 +67,37 @@ package uart_pkg is impure function as_sync(uart_slave : uart_slave_t) return sync_handle_t; constant uart_set_baud_rate_msg : msg_type_t := new_msg_type("uart set baud rate"); + + constant uart_set_parity_msg : msg_type_t := new_msg_type("uart set parity rate"); + + function even_parity(data : std_logic_vector) return std_logic; + function odd_parity (data : std_logic_vector) return std_logic; + end package; package body uart_pkg is impure function new_uart_master(initial_baud_rate : natural := default_baud_rate; + initial_parity : natural := default_parity; idle_state : std_logic := default_idle_state) return uart_master_t is begin return (p_actor => new_actor, p_baud_rate => initial_baud_rate, + p_parity => initial_parity, p_idle_state => idle_state); end; - impure function new_uart_slave(initial_baud_rate : natural := default_baud_rate; + impure function new_uart_slave( + initial_baud_rate : natural := default_baud_rate; + initial_parity : natural := default_parity; idle_state : std_logic := default_idle_state; - data_length : positive := default_data_length) return uart_slave_t is + data_length : positive := default_data_length + ) return uart_slave_t is + begin return (p_actor => new_actor, p_baud_rate => initial_baud_rate, + p_parity => initial_parity, p_idle_state => idle_state, p_data_length => data_length); end; @@ -116,4 +144,39 @@ package body uart_pkg is begin set_baud_rate(net, uart_slave.p_actor, baud_rate); end; + + procedure set_parity(signal net : inout network_t; + actor : actor_t; + parity : natural) is + variable msg : msg_t := new_msg(uart_set_parity_msg); + begin + push(msg, parity); + send(net, actor, msg); + end; + + procedure set_parity(signal net : inout network_t; + uart_master : uart_master_t; + parity : natural) is + begin + set_parity(net, uart_master.p_actor, parity); + end; + + procedure set_parity(signal net : inout network_t; + uart_slave : uart_slave_t; + parity : natural) is + begin + set_parity(net, uart_slave.p_actor, parity); + end; + + function even_parity (data : std_logic_vector) return std_logic is + begin + return xor data; + + end function even_parity; + + function odd_parity (data : std_logic_vector) return std_logic is + begin + + return xnor data; + end function odd_parity; end package body; From 03c183dfb8e1cc0bf9fa8bc59617228bdf063734 Mon Sep 17 00:00:00 2001 From: Rafael do Nascimento Pereira Date: Fri, 13 Mar 2026 21:25:23 +0100 Subject: [PATCH 2/7] uart vc: implement parity on uart_slave --- .../src/uart_slave.vhd | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/vunit/vhdl/verification_components/src/uart_slave.vhd b/vunit/vhdl/verification_components/src/uart_slave.vhd index 480f4558e..b42f40046 100644 --- a/vunit/vhdl/verification_components/src/uart_slave.vhd +++ b/vunit/vhdl/verification_components/src/uart_slave.vhd @@ -24,6 +24,7 @@ end entity; architecture a of uart_slave is signal baud_rate : natural := uart.p_baud_rate; + signal parity : natural := uart.p_parity; signal local_event : std_logic := '0'; constant data_queue : queue_t := new_queue; begin @@ -37,7 +38,8 @@ begin if msg_type = uart_set_baud_rate_msg then baud_rate <= pop(msg); - + elsif msg_type = uart_set_parity_msg then + parity <= pop(msg); elsif msg_type = stream_pop_msg then reply_msg := new_msg; if not (length(data_queue) > 0) then @@ -56,9 +58,12 @@ begin recv : process procedure uart_recv(variable data : out std_logic_vector; signal rx : in std_logic; - baud_rate : integer) is + baud_rate : integer; + parity : natural) is constant time_per_bit : time := (10**9 / baud_rate) * 1 ns; constant time_per_half_bit : time := (10**9 / (2*baud_rate)) * 1 ns; + variable parity_bit : std_logic; + variable parity_calc : std_logic; begin wait for time_per_half_bit; -- middle of start bit assert rx = not uart.p_idle_state; @@ -69,13 +74,37 @@ begin wait for time_per_bit; end loop; + if parity = 1 then + parity_bit := rx; + parity_calc := odd_parity(data); + wait for 0 ns; + + if parity_bit /= parity_calc then + report "odd parity mismatch" + severity WARNING; + end if; + + wait for time_per_bit; + elsif parity = 2 then + parity_bit := rx; + parity_calc := even_parity(data); + wait for 0 ns; + + if parity_bit /= parity_calc then + report "even parity mismatch" + severity WARNING; + end if; + + wait for time_per_bit; + end if; + assert rx = uart.p_idle_state; end procedure; variable data : std_logic_vector(uart.p_data_length-1 downto 0); begin wait on rx until rx = not uart.p_idle_state; - uart_recv(data, rx, baud_rate); + uart_recv(data, rx, baud_rate, parity); push_std_ulogic_vector(data_queue, data); local_event <= '1'; wait for 0 ns; From 7940e58678e56322bc7fee698a0edc7cea651586 Mon Sep 17 00:00:00 2001 From: Rafael do Nascimento Pereira Date: Fri, 13 Mar 2026 21:27:51 +0100 Subject: [PATCH 3/7] uart_vc: fix identation --- vunit/vhdl/verification_components/src/uart_master.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vunit/vhdl/verification_components/src/uart_master.vhd b/vunit/vhdl/verification_components/src/uart_master.vhd index c183c98f1..42acc01f7 100644 --- a/vunit/vhdl/verification_components/src/uart_master.vhd +++ b/vunit/vhdl/verification_components/src/uart_master.vhd @@ -52,7 +52,7 @@ begin send_bit(odd_parity(data)); elsif parity = 2 then send_bit(even_parity(data)); - end if; + end if; send_bit(uart.p_idle_state); end procedure; From 2fc01fff6a96158a421cfa72739f4f585ad2eec1 Mon Sep 17 00:00:00 2001 From: Rafael do Nascimento Pereira Date: Sun, 15 Mar 2026 21:38:33 +0100 Subject: [PATCH 4/7] uart vc: check parity value --- vunit/vhdl/verification_components/src/uart_pkg.vhd | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vunit/vhdl/verification_components/src/uart_pkg.vhd b/vunit/vhdl/verification_components/src/uart_pkg.vhd index 86c5023a8..d9bd7b760 100644 --- a/vunit/vhdl/verification_components/src/uart_pkg.vhd +++ b/vunit/vhdl/verification_components/src/uart_pkg.vhd @@ -150,6 +150,11 @@ package body uart_pkg is parity : natural) is variable msg : msg_t := new_msg(uart_set_parity_msg); begin + if parity > 2 then + report "Invalid parity value: " & to_string(parity) + severity error; + end if; + push(msg, parity); send(net, actor, msg); end; From ac0952b93944b2852ad902681c84cb70326f3ca0 Mon Sep 17 00:00:00 2001 From: Rafael do Nascimento Pereira Date: Sun, 15 Mar 2026 21:39:47 +0100 Subject: [PATCH 5/7] uart vc: add testbenches/test cases --- examples/vhdl/uart/run.py | 10 +++++ examples/vhdl/uart/src/test/tb_uart_rx.vhd | 9 ++-- examples/vhdl/uart/src/test/tb_uart_tx.vhd | 7 ++- examples/vhdl/uart/src/uart_rx.vhd | 26 +++++++++-- examples/vhdl/uart/src/uart_tx.vhd | 44 +++++++++++++++++-- .../verification_components/test/tb_uart.vhd | 28 ++++++++++++ 6 files changed, 113 insertions(+), 11 deletions(-) diff --git a/examples/vhdl/uart/run.py b/examples/vhdl/uart/run.py index 1f73b5f5a..45f240a19 100644 --- a/examples/vhdl/uart/run.py +++ b/examples/vhdl/uart/run.py @@ -27,4 +27,14 @@ VU.add_library("uart_lib").add_source_files(SRC_PATH / "*.vhd") VU.add_library("tb_uart_lib").add_source_files(SRC_PATH / "test" / "*.vhd") +for tb in VU.library("tb_uart_lib").get_test_benches(): + for parity in [0, 1, 2]: + generics = dict( + parity=parity + ) + tb.add_config( + name=",".join("{}={}".format(k, v) for (k, v) in generics.items()), + generics=generics, + ) + VU.main() diff --git a/examples/vhdl/uart/src/test/tb_uart_rx.vhd b/examples/vhdl/uart/src/test/tb_uart_rx.vhd index e9e136280..678eb8e5f 100644 --- a/examples/vhdl/uart/src/test/tb_uart_rx.vhd +++ b/examples/vhdl/uart/src/test/tb_uart_rx.vhd @@ -16,7 +16,8 @@ library uart_lib; entity tb_uart_rx is generic ( - runner_cfg : string); + runner_cfg : string; + parity : natural); end entity; architecture tb of tb_uart_rx is @@ -33,7 +34,8 @@ architecture tb of tb_uart_rx is signal num_overflows : integer := 0; - constant uart_bfm : uart_master_t := new_uart_master(initial_baud_rate => baud_rate); + constant uart_bfm : uart_master_t := new_uart_master(initial_baud_rate => baud_rate, + initial_parity => parity); constant uart_stream : stream_master_t := as_stream(uart_bfm); constant axi_stream_bfm : axi_stream_slave_t := new_axi_stream_slave(data_length => tdata'length); @@ -87,7 +89,8 @@ begin dut : entity uart_lib.uart_rx generic map ( - cycles_per_bit => cycles_per_bit) + cycles_per_bit => cycles_per_bit, + parity => parity) port map ( clk => clk, rx => rx, diff --git a/examples/vhdl/uart/src/test/tb_uart_tx.vhd b/examples/vhdl/uart/src/test/tb_uart_tx.vhd index 62cd6ade3..c26f4bb28 100644 --- a/examples/vhdl/uart/src/test/tb_uart_tx.vhd +++ b/examples/vhdl/uart/src/test/tb_uart_tx.vhd @@ -19,7 +19,8 @@ library uart_lib; entity tb_uart_tx is generic ( - runner_cfg : string); + runner_cfg : string; + parity : natural); end entity; architecture tb of tb_uart_tx is @@ -35,6 +36,7 @@ architecture tb of tb_uart_tx is shared variable rnd_stimuli, rnd_expected : RandomPType; constant uart_bfm : uart_slave_t := new_uart_slave(initial_baud_rate => baud_rate, + initial_parity => parity, data_length => tdata'length); constant uart_stream : stream_slave_t := as_stream(uart_bfm); @@ -79,7 +81,8 @@ begin dut : entity uart_lib.uart_tx generic map ( - cycles_per_bit => cycles_per_bit) + cycles_per_bit => cycles_per_bit, + parity => parity) port map ( clk => clk, tx => tx, diff --git a/examples/vhdl/uart/src/uart_rx.vhd b/examples/vhdl/uart/src/uart_rx.vhd index acd196dcb..2ae7079b4 100644 --- a/examples/vhdl/uart/src/uart_rx.vhd +++ b/examples/vhdl/uart/src/uart_rx.vhd @@ -15,7 +15,8 @@ use vunit_lib.logger_pkg.all; entity uart_rx is generic ( - cycles_per_bit : natural := 434); + cycles_per_bit : natural := 434; + parity : natural := 0); port ( clk : in std_logic; @@ -29,6 +30,7 @@ entity uart_rx is tvalid : out std_Logic := '0'; tdata : out std_logic_vector(7 downto 0)); begin + -- pragma translate_off check_stable(clk, check_enabled, tvalid, tready, tdata, "tdata must be stable until tready is active"); check_stable(clk, check_enabled, tvalid, tready, tvalid, "tvalid must be active until tready is active"); @@ -46,12 +48,30 @@ end entity; architecture a of uart_rx is signal tvalid_int : std_logic := '0'; + + function data_size( + constant parity: natural + ) return natural is + begin + if parity = 0 then + -- uart data (8 bits) + return 8; + elsif parity = 1 or parity = 2 then + -- uart data (8 bits)+ parity + return 9; + else + -- invalid mode + return 0; + end if; + end function data_size; + begin main : process (clk) type state_t is (idle, receiving, done); variable state : state_t := idle; + variable datawidth : natural := data_size(parity); variable cycles : natural range 0 to cycles_per_bit-1 := 0; - variable data : std_logic_vector(7 downto 0); + variable data : std_logic_vector(datawidth-1 downto 0); variable index : natural range 0 to data'length-1 := 0; begin if rising_edge(clk) then @@ -89,7 +109,7 @@ begin -- New output overwrites old output overflow <= tvalid_int and not tready; tvalid_int <= '1'; - tdata <= data; + tdata <= data(7 downto 0); state := idle; end case; diff --git a/examples/vhdl/uart/src/uart_tx.vhd b/examples/vhdl/uart/src/uart_tx.vhd index 23993adaa..45b476abd 100644 --- a/examples/vhdl/uart/src/uart_tx.vhd +++ b/examples/vhdl/uart/src/uart_tx.vhd @@ -15,7 +15,8 @@ use vunit_lib.logger_pkg.all; entity uart_tx is generic ( - cycles_per_bit : natural := 434); + cycles_per_bit : natural := 434; + parity : natural := 0); port ( clk : in std_logic; @@ -44,12 +45,42 @@ end entity; architecture a of uart_tx is signal tready_int : std_logic := '0'; + + function data_size( + constant parity: natural + ) return natural is + begin + if parity = 0 then + -- uart data (8 bits) + return 8; + elsif parity = 1 or parity = 2 then + -- uart data (8 bits)+ parity + return 9; + else + -- invalid mode + return 0; + end if; + end function data_size; + + function even_parity (data : std_logic_vector) return std_logic is + begin + return xor data; + + end function even_parity; + + function odd_parity (data : std_logic_vector) return std_logic is + begin + + return xnor data; + end function odd_parity; + begin main : process (clk) type state_t is (idle, sending); variable state : state_t := idle; + variable datawidth : natural := data_size(parity) + 2; variable cycles : natural range 0 to cycles_per_bit-1 := 0; - variable data : std_logic_vector(9 downto 0); + variable data : std_logic_vector(datawidth-1 downto 0); variable index : natural range 0 to data'length-1 := 0; begin if rising_edge(clk) then @@ -60,7 +91,14 @@ begin state := sending; cycles := 0; index := 0; - data := '1' & tdata & '0'; + + if parity = 0 then + data := '1' & tdata & '0'; + elsif parity = 1 then + data := '1' & odd_parity(tdata) & tdata & '0'; + elsif parity = 2 then + data := '1' & even_parity(tdata) & tdata & '0'; + end if; end if; when sending => tx <= data(0); diff --git a/vunit/vhdl/verification_components/test/tb_uart.vhd b/vunit/vhdl/verification_components/test/tb_uart.vhd index a7e6e5037..4631d9e52 100644 --- a/vunit/vhdl/verification_components/test/tb_uart.vhd +++ b/vunit/vhdl/verification_components/test/tb_uart.vhd @@ -27,6 +27,12 @@ architecture a of tb_uart is constant slave_uart : uart_slave_t := new_uart_slave(data_length => 8); constant slave_stream : stream_slave_t := as_stream(slave_uart); + -- parity related VCs + constant master_uart_p : uart_master_t := new_uart_master; + constant master_stream_p : stream_master_t := as_stream(master_uart); + + constant slave_uart_p : uart_slave_t := new_uart_slave(data_length => 8); + constant slave_stream_p : stream_slave_t := as_stream(slave_uart); signal chan : std_logic; begin @@ -83,6 +89,28 @@ begin test_baud_rate(2000); test_baud_rate(7000); test_baud_rate(200000); + elsif run("test_parity_odd") then + set_parity(net, master_uart_p, 1); + set_parity(net, slave_uart_p, 1); + + for i in 0 to 7 loop + push_stream(net, master_stream_p, + std_logic_vector(to_unsigned(i+1, data'length))); + pop_stream(net, slave_stream_p, data); + check_equal(data, std_logic_vector(to_unsigned(i+1, data'length)), "pop stream data"); + end loop; + + elsif run("test_parity_even") then + set_parity(net, master_uart_p, 2); + set_parity(net, slave_uart_p, 2); + + for i in 0 to 7 loop + push_stream(net, master_stream_p, + std_logic_vector(to_unsigned(i+1, data'length))); + pop_stream(net, slave_stream_p, data); + check_equal(data, std_logic_vector(to_unsigned(i+1, data'length)), "pop stream data"); + end loop; + end if; test_runner_cleanup(runner); From dc5a6f70f2d175f7b24a0cdaac982c11f2d0b77a Mon Sep 17 00:00:00 2001 From: Rafael do Nascimento Pereira Date: Fri, 20 Mar 2026 21:58:15 +0100 Subject: [PATCH 6/7] uart vc: use an enumerated type for parity --- examples/vhdl/uart/src/test/tb_uart_rx.vhd | 3 +- examples/vhdl/uart/src/test/tb_uart_tx.vhd | 2 +- vunit/vhdl/com/src/com_types.vhd | 22 +++++++++++++ .../src/uart_master.vhd | 10 +++--- .../verification_components/src/uart_pkg.vhd | 32 ++++++++----------- .../src/uart_slave.vhd | 10 +++--- .../verification_components/test/tb_uart.vhd | 8 ++--- 7 files changed, 53 insertions(+), 34 deletions(-) diff --git a/examples/vhdl/uart/src/test/tb_uart_rx.vhd b/examples/vhdl/uart/src/test/tb_uart_rx.vhd index 678eb8e5f..a55c3e92e 100644 --- a/examples/vhdl/uart/src/test/tb_uart_rx.vhd +++ b/examples/vhdl/uart/src/test/tb_uart_rx.vhd @@ -35,7 +35,8 @@ architecture tb of tb_uart_rx is signal num_overflows : integer := 0; constant uart_bfm : uart_master_t := new_uart_master(initial_baud_rate => baud_rate, - initial_parity => parity); + initial_parity => int_to_parity(parity)); + constant uart_stream : stream_master_t := as_stream(uart_bfm); constant axi_stream_bfm : axi_stream_slave_t := new_axi_stream_slave(data_length => tdata'length); diff --git a/examples/vhdl/uart/src/test/tb_uart_tx.vhd b/examples/vhdl/uart/src/test/tb_uart_tx.vhd index c26f4bb28..157f7df38 100644 --- a/examples/vhdl/uart/src/test/tb_uart_tx.vhd +++ b/examples/vhdl/uart/src/test/tb_uart_tx.vhd @@ -36,7 +36,7 @@ architecture tb of tb_uart_tx is shared variable rnd_stimuli, rnd_expected : RandomPType; constant uart_bfm : uart_slave_t := new_uart_slave(initial_baud_rate => baud_rate, - initial_parity => parity, + initial_parity => int_to_parity(parity), data_length => tdata'length); constant uart_stream : stream_slave_t := as_stream(uart_bfm); diff --git a/vunit/vhdl/com/src/com_types.vhd b/vunit/vhdl/com/src/com_types.vhd index 3d10519b2..ccfacf72e 100644 --- a/vunit/vhdl/com/src/com_types.vhd +++ b/vunit/vhdl/com/src/com_types.vhd @@ -48,6 +48,11 @@ package com_types_pkg is duplicate_actor_name_error, new_actor_from_root_id_error); + type parity_t is ( + PARITY_NONE, + PARITY_ODD, + PARITY_EVEN); + subtype com_error_t is com_status_t range timeout to new_actor_from_root_id_error; -- All fields of the actor type are private @@ -406,6 +411,9 @@ package com_types_pkg is -- Private impure function is_valid(code : integer) return boolean; + + function int_to_parity(value : integer) return parity_t; + end package; package body com_types_pkg is @@ -889,4 +897,18 @@ package body com_types_pkg is return (p_id_number => value); end; + function int_to_parity(value: integer) return parity_t is + begin + case value is + when 0 => + return PARITY_NONE; + when 1 => + return PARITY_ODD; + when 2 => + return PARITY_EVEN; + when others => + return PARITY_NONE; + end case; + end function int_to_parity; + end package body com_types_pkg; diff --git a/vunit/vhdl/verification_components/src/uart_master.vhd b/vunit/vhdl/verification_components/src/uart_master.vhd index 42acc01f7..5fb77234e 100644 --- a/vunit/vhdl/verification_components/src/uart_master.vhd +++ b/vunit/vhdl/verification_components/src/uart_master.vhd @@ -31,7 +31,7 @@ begin procedure uart_send(data : std_logic_vector; signal tx : out std_logic; baud_rate : integer; - parity : natural + parity : parity_t ) is constant time_per_bit : time := (10**9 / baud_rate) * 1 ns; @@ -48,9 +48,9 @@ begin send_bit(data(i)); end loop; - if parity = 1 then + if parity = PARITY_ODD then send_bit(odd_parity(data)); - elsif parity = 2 then + elsif parity = PARITY_EVEN then send_bit(even_parity(data)); end if; @@ -59,7 +59,7 @@ begin variable msg : msg_t; variable baud_rate : natural := uart.p_baud_rate; - variable parity : natural := uart.p_parity; + variable parity : parity_t := uart.p_parity; variable msg_type : msg_type_t; begin receive(net, uart.p_actor, msg); @@ -72,7 +72,7 @@ begin elsif msg_type = uart_set_baud_rate_msg then baud_rate := pop(msg); elsif msg_type = uart_set_parity_msg then - parity := pop(msg); + parity := int_to_parity(pop(msg)); else unexpected_msg_type(msg_type); end if; diff --git a/vunit/vhdl/verification_components/src/uart_pkg.vhd b/vunit/vhdl/verification_components/src/uart_pkg.vhd index d9bd7b760..812c3b355 100644 --- a/vunit/vhdl/verification_components/src/uart_pkg.vhd +++ b/vunit/vhdl/verification_components/src/uart_pkg.vhd @@ -18,14 +18,14 @@ package uart_pkg is type uart_master_t is record p_actor : actor_t; p_baud_rate : natural; - p_parity : natural; + p_parity : parity_t; p_idle_state : std_logic; end record uart_master_t; type uart_slave_t is record p_actor : actor_t; p_baud_rate : natural; - p_parity : natural; + p_parity : parity_t; p_idle_state : std_logic; p_data_length : positive; end record; @@ -42,22 +42,22 @@ package uart_pkg is -- 0 = no parity, 1 = odd parity, 2 = even parity procedure set_parity(signal net : inout network_t; uart_master : uart_master_t; - parity : natural); + parity : parity_t); procedure set_parity(signal net : inout network_t; uart_slave : uart_slave_t; - parity : natural); + parity : parity_t); constant default_baud_rate : natural := 115200; constant default_idle_state : std_logic := '1'; constant default_data_length : positive := 8; - constant default_parity : natural := 0; + constant default_parity : parity_t := PARITY_NONE; impure function new_uart_master(initial_baud_rate : natural := default_baud_rate; - initial_parity : natural := default_parity; + initial_parity : parity_t := default_parity; idle_state : std_logic := default_idle_state) return uart_master_t; impure function new_uart_slave(initial_baud_rate : natural := default_baud_rate; - initial_parity : natural := default_parity; + initial_parity : parity_t := default_parity; idle_state : std_logic := default_idle_state; data_length : positive := default_data_length) return uart_slave_t; @@ -68,7 +68,7 @@ package uart_pkg is constant uart_set_baud_rate_msg : msg_type_t := new_msg_type("uart set baud rate"); - constant uart_set_parity_msg : msg_type_t := new_msg_type("uart set parity rate"); + constant uart_set_parity_msg : msg_type_t := new_msg_type("uart set parity"); function even_parity(data : std_logic_vector) return std_logic; function odd_parity (data : std_logic_vector) return std_logic; @@ -78,7 +78,7 @@ end package; package body uart_pkg is impure function new_uart_master(initial_baud_rate : natural := default_baud_rate; - initial_parity : natural := default_parity; + initial_parity : parity_t := default_parity; idle_state : std_logic := default_idle_state) return uart_master_t is begin return (p_actor => new_actor, @@ -89,7 +89,7 @@ package body uart_pkg is impure function new_uart_slave( initial_baud_rate : natural := default_baud_rate; - initial_parity : natural := default_parity; + initial_parity : parity_t := default_parity; idle_state : std_logic := default_idle_state; data_length : positive := default_data_length ) return uart_slave_t is @@ -147,28 +147,24 @@ package body uart_pkg is procedure set_parity(signal net : inout network_t; actor : actor_t; - parity : natural) is + parity : parity_t) is variable msg : msg_t := new_msg(uart_set_parity_msg); begin - if parity > 2 then - report "Invalid parity value: " & to_string(parity) - severity error; - end if; - push(msg, parity); + push(msg, parity_t'pos(parity)); send(net, actor, msg); end; procedure set_parity(signal net : inout network_t; uart_master : uart_master_t; - parity : natural) is + parity : parity_t) is begin set_parity(net, uart_master.p_actor, parity); end; procedure set_parity(signal net : inout network_t; uart_slave : uart_slave_t; - parity : natural) is + parity : parity_t) is begin set_parity(net, uart_slave.p_actor, parity); end; diff --git a/vunit/vhdl/verification_components/src/uart_slave.vhd b/vunit/vhdl/verification_components/src/uart_slave.vhd index b42f40046..29dfb0007 100644 --- a/vunit/vhdl/verification_components/src/uart_slave.vhd +++ b/vunit/vhdl/verification_components/src/uart_slave.vhd @@ -24,7 +24,7 @@ end entity; architecture a of uart_slave is signal baud_rate : natural := uart.p_baud_rate; - signal parity : natural := uart.p_parity; + signal parity : parity_t := uart.p_parity; signal local_event : std_logic := '0'; constant data_queue : queue_t := new_queue; begin @@ -39,7 +39,7 @@ begin if msg_type = uart_set_baud_rate_msg then baud_rate <= pop(msg); elsif msg_type = uart_set_parity_msg then - parity <= pop(msg); + parity <= int_to_parity(pop(msg)); elsif msg_type = stream_pop_msg then reply_msg := new_msg; if not (length(data_queue) > 0) then @@ -59,7 +59,7 @@ begin procedure uart_recv(variable data : out std_logic_vector; signal rx : in std_logic; baud_rate : integer; - parity : natural) is + parity : parity_t) is constant time_per_bit : time := (10**9 / baud_rate) * 1 ns; constant time_per_half_bit : time := (10**9 / (2*baud_rate)) * 1 ns; variable parity_bit : std_logic; @@ -74,7 +74,7 @@ begin wait for time_per_bit; end loop; - if parity = 1 then + if parity = PARITY_ODD then parity_bit := rx; parity_calc := odd_parity(data); wait for 0 ns; @@ -85,7 +85,7 @@ begin end if; wait for time_per_bit; - elsif parity = 2 then + elsif parity = PARITY_EVEN then parity_bit := rx; parity_calc := even_parity(data); wait for 0 ns; diff --git a/vunit/vhdl/verification_components/test/tb_uart.vhd b/vunit/vhdl/verification_components/test/tb_uart.vhd index 4631d9e52..cfb769e98 100644 --- a/vunit/vhdl/verification_components/test/tb_uart.vhd +++ b/vunit/vhdl/verification_components/test/tb_uart.vhd @@ -90,8 +90,8 @@ begin test_baud_rate(7000); test_baud_rate(200000); elsif run("test_parity_odd") then - set_parity(net, master_uart_p, 1); - set_parity(net, slave_uart_p, 1); + set_parity(net, master_uart_p, PARITY_ODD); + set_parity(net, slave_uart_p, PARITY_ODD); for i in 0 to 7 loop push_stream(net, master_stream_p, @@ -101,8 +101,8 @@ begin end loop; elsif run("test_parity_even") then - set_parity(net, master_uart_p, 2); - set_parity(net, slave_uart_p, 2); + set_parity(net, master_uart_p, PARITY_EVEN); + set_parity(net, slave_uart_p, PARITY_EVEN); for i in 0 to 7 loop push_stream(net, master_stream_p, From 144a2ba90f04ef6296901bf64160a2ccc6022514 Mon Sep 17 00:00:00 2001 From: Rafael do Nascimento Pereira Date: Fri, 20 Mar 2026 22:29:07 +0100 Subject: [PATCH 7/7] uart vc: move new uart vc parameter to the end, to avoid breaking existing implementations --- .../verification_components/src/uart_pkg.vhd | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/vunit/vhdl/verification_components/src/uart_pkg.vhd b/vunit/vhdl/verification_components/src/uart_pkg.vhd index 812c3b355..b558324c5 100644 --- a/vunit/vhdl/verification_components/src/uart_pkg.vhd +++ b/vunit/vhdl/verification_components/src/uart_pkg.vhd @@ -54,12 +54,12 @@ package uart_pkg is constant default_parity : parity_t := PARITY_NONE; impure function new_uart_master(initial_baud_rate : natural := default_baud_rate; - initial_parity : parity_t := default_parity; - idle_state : std_logic := default_idle_state) return uart_master_t; + idle_state : std_logic := default_idle_state; + initial_parity : parity_t := default_parity) return uart_master_t; impure function new_uart_slave(initial_baud_rate : natural := default_baud_rate; - initial_parity : parity_t := default_parity; idle_state : std_logic := default_idle_state; - data_length : positive := default_data_length) return uart_slave_t; + data_length : positive := default_data_length; + initial_parity : parity_t := default_parity) return uart_slave_t; impure function as_stream(uart_master : uart_master_t) return stream_master_t; impure function as_stream(uart_slave : uart_slave_t) return stream_slave_t; @@ -78,8 +78,9 @@ end package; package body uart_pkg is impure function new_uart_master(initial_baud_rate : natural := default_baud_rate; - initial_parity : parity_t := default_parity; - idle_state : std_logic := default_idle_state) return uart_master_t is + idle_state : std_logic := default_idle_state; + initial_parity : parity_t := default_parity + ) return uart_master_t is begin return (p_actor => new_actor, p_baud_rate => initial_baud_rate, @@ -89,9 +90,9 @@ package body uart_pkg is impure function new_uart_slave( initial_baud_rate : natural := default_baud_rate; - initial_parity : parity_t := default_parity; idle_state : std_logic := default_idle_state; - data_length : positive := default_data_length + data_length : positive := default_data_length; + initial_parity : parity_t := default_parity ) return uart_slave_t is begin