From 54c28e86f484badbf7c637a988b8b074df484fa3 Mon Sep 17 00:00:00 2001 From: c-thaler Date: Fri, 25 Oct 2024 00:38:39 +0200 Subject: [PATCH 01/22] initial checkin of APB master and slave VC --- .../src/apb_master.vhd | 147 ++++++++++++++++++ .../verification_components/src/apb_pkg.vhd | 53 +++++++ .../verification_components/src/apb_slave.vhd | 77 +++++++++ .../test/tb_apb_master.vhd | 138 ++++++++++++++++ 4 files changed, 415 insertions(+) create mode 100644 vunit/vhdl/verification_components/src/apb_master.vhd create mode 100644 vunit/vhdl/verification_components/src/apb_pkg.vhd create mode 100644 vunit/vhdl/verification_components/src/apb_slave.vhd create mode 100644 vunit/vhdl/verification_components/test/tb_apb_master.vhd diff --git a/vunit/vhdl/verification_components/src/apb_master.vhd b/vunit/vhdl/verification_components/src/apb_master.vhd new file mode 100644 index 000000000..cdd22ff77 --- /dev/null +++ b/vunit/vhdl/verification_components/src/apb_master.vhd @@ -0,0 +1,147 @@ +-- This Source Code Form is subject to the terms of the Mozilla Public +-- License, v. 2.0. If a copy of the MPL was not distributed with this file, +-- You can obtain one at http://mozilla.org/MPL/2.0/. +-- +-- Copyright (c) 2014-2024, Lars Asplund lars.anders.asplund@gmail.com + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.bus_master_pkg.all; +use work.check_pkg.all; +use work.com_pkg.all; +use work.com_types_pkg.all; +use work.queue_pkg.all; +use work.sync_pkg.all; +use work.logger_pkg.all; +use work.log_levels_pkg.all; + +entity apb_master is + generic ( + bus_handle : bus_master_t; + drive_invalid : boolean := true; + drive_invalid_val : std_logic := 'X' + ); + port ( + clk : in std_logic; + reset : in std_logic; + psel_o : out std_logic; + penable_o : out std_logic; + paddr_o : out std_logic_vector(address_length(bus_handle) - 1 downto 0); + pwrite_o : out std_logic; + pwdata_o : out std_logic_vector(data_length(bus_handle) - 1 downto 0); + prdata_i : in std_logic_vector(data_length(bus_handle) - 1 downto 0); + pready_i : in std_logic + ); +end entity; + +architecture behav of apb_master is + constant message_queue : queue_t := new_queue; + signal idle_bus : boolean := true; + + impure function queues_empty return boolean is + begin + return is_empty(message_queue); + end function; + + impure function is_idle return boolean is + begin + return idle_bus; + end function; + +begin + + PROC_MAIN: process + variable request_msg : msg_t; + variable msg_type : msg_type_t; + begin + DISPATCH_LOOP : loop + receive(net, bus_handle.p_actor, request_msg); + msg_type := message_type(request_msg); + + if msg_type = bus_read_msg then + push(message_queue, request_msg); + elsif msg_type = bus_write_msg then + push(message_queue, request_msg); + elsif msg_type = wait_until_idle_msg then + if not is_idle or not queues_empty then + wait until is_idle and queues_empty and rising_edge(clk); + end if; + handle_wait_until_idle(net, msg_type, request_msg); + else + unexpected_msg_type(msg_type); + end if; + end loop; + end process; + + BUS_PROCESS: process + procedure drive_bus_invalid is + begin + if drive_invalid then + penable_o <= drive_invalid_val; + paddr_o <= (paddr_o'range => drive_invalid_val); + pwrite_o <= drive_invalid_val; + pwdata_o <= (pwdata_o'range => drive_invalid_val); + end if; + end procedure; + + variable request_msg, reply_msg : msg_t; + variable msg_type : msg_type_t; + variable addr_this_transaction : std_logic_vector(paddr_o'range) := (others => '0'); + variable data_this_transaction : std_logic_vector(prdata_i'range) := (others => '0'); + begin + loop + drive_bus_invalid; + psel_o <= '0'; + + if is_empty(message_queue) then + wait until rising_edge(clk) and not is_empty(message_queue); + end if; + idle_bus <= false; + wait for 0 ns; + + request_msg := pop(message_queue); + msg_type := message_type(request_msg); + + if msg_type = bus_write_msg then + addr_this_transaction := pop_std_ulogic_vector(request_msg); + data_this_transaction := pop_std_ulogic_vector(request_msg); + + psel_o <= '1'; + penable_o <= '0'; + pwrite_o <= '1'; + paddr_o <= addr_this_transaction; + pwdata_o <= data_this_transaction; + + wait until rising_edge(clk); + penable_o <= '1'; + wait until (pready_i and penable_o) = '1' and rising_edge(clk); + + if is_visible(bus_handle.p_logger, debug) then + debug(bus_handle.p_logger, + "Wrote 0x" & to_hstring(data_this_transaction) & + " to address 0x" & to_hstring(addr_this_transaction)); + end if; + + elsif msg_type = bus_read_msg then + addr_this_transaction := pop_std_ulogic_vector(request_msg); + + psel_o <= '1'; + penable_o <= '0'; + pwrite_o <= '0'; + paddr_o <= addr_this_transaction; + + wait until rising_edge(clk); + penable_o <= '1'; + wait until (pready_i and penable_o) = '1' and rising_edge(clk); + + reply_msg := new_msg; + push_std_ulogic_vector(reply_msg, prdata_i); + reply(net, request_msg, reply_msg); + end if; + + idle_bus <= true; + end loop; + end process; +end architecture; diff --git a/vunit/vhdl/verification_components/src/apb_pkg.vhd b/vunit/vhdl/verification_components/src/apb_pkg.vhd new file mode 100644 index 000000000..e9fa4fc12 --- /dev/null +++ b/vunit/vhdl/verification_components/src/apb_pkg.vhd @@ -0,0 +1,53 @@ +-- This Source Code Form is subject to the terms of the Mozilla Public +-- License, v. 2.0. If a copy of the MPL was not distributed with this file, +-- You can obtain one at http://mozilla.org/MPL/2.0/. +-- +-- Copyright (c) 2014-2024, Lars Asplund lars.anders.asplund@gmail.com + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.com_pkg.all; +use work.com_types_pkg.all; +use work.logger_pkg.all; +use work.memory_pkg.memory_t; +use work.memory_pkg.to_vc_interface; + +package apb_pkg is + + type apb_slave_t is record + ready_high_probability : real range 0.0 to 1.0; + -- Private + p_actor : actor_t; + p_memory : memory_t; + p_logger : logger_t; + end record; + + constant apb_slave_logger : logger_t := get_logger("vunit_lib:apb_slave_pkg"); + impure function new_apb_slave( + memory : memory_t; + ready_high_probability : real := 1.0; + logger : logger_t := apb_slave_logger) + return apb_slave_t; + + constant slave_write_msg : msg_type_t := new_msg_type("apb slave write"); + constant slave_read_msg : msg_type_t := new_msg_type("apb slave read"); +end package; + +package body apb_pkg is + + impure function new_apb_slave( + memory : memory_t; + ready_high_probability : real := 1.0; + logger : logger_t := apb_slave_logger) + return apb_slave_t is + begin + return (p_actor => new_actor, + p_memory => to_vc_interface(memory, logger), + p_logger => logger, + ready_high_probability => ready_high_probability + ); + end; + +end package body; \ No newline at end of file diff --git a/vunit/vhdl/verification_components/src/apb_slave.vhd b/vunit/vhdl/verification_components/src/apb_slave.vhd new file mode 100644 index 000000000..7f698ec61 --- /dev/null +++ b/vunit/vhdl/verification_components/src/apb_slave.vhd @@ -0,0 +1,77 @@ +-- This Source Code Form is subject to the terms of the Mozilla Public +-- License, v. 2.0. If a copy of the MPL was not distributed with this file, +-- You can obtain one at http://mozilla.org/MPL/2.0/. +-- +-- Copyright (c) 2014-2024, Lars Asplund lars.anders.asplund@gmail.com + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.memory_pkg.all; +use work.apb_pkg.all; +use work.logger_pkg.all; + +entity apb_slave is + generic ( + bus_handle : apb_slave_t; + drive_invalid : boolean := true; + drive_invalid_val : std_logic := 'X' + ); + port ( + clk : in std_logic; + reset : in std_logic; + psel_i : in std_logic; + penable_i : in std_logic; + paddr_i : in std_logic_vector; + pwrite_i : in std_logic; + pwdata_i : in std_logic_vector; + prdata_o : out std_logic_vector; + pready_o : out std_logic + ); +end entity; + +architecture a of apb_slave is + +begin + + PROC_MAIN: process + procedure drive_outputs_invalid is + begin + if drive_invalid then + prdata_o <= (prdata_o'range => drive_invalid_val); + pready_o <= drive_invalid_val; + end if; + end procedure; + + variable addr : integer; + begin + drive_outputs_invalid; + wait until rising_edge(clk); + + loop + -- IDLE/SETUP state + drive_outputs_invalid; + + wait until psel_i = '1' and rising_edge(clk); + -- ACCESS state + + pready_o <= '1'; + + addr := to_integer(unsigned(paddr_i)); + + if pwrite_i = '1' then + write_word(bus_handle.p_memory, addr, pwdata_i); + else + prdata_o <= read_word(bus_handle.p_memory, addr, prdata_o'length/8); + end if; + + wait until rising_edge(clk); + + if penable_i = '0' then + failure(bus_handle.p_logger, "penable_i must be active in the ACCESS phase."); + end if; + end loop; + end process; + +end architecture; \ No newline at end of file diff --git a/vunit/vhdl/verification_components/test/tb_apb_master.vhd b/vunit/vhdl/verification_components/test/tb_apb_master.vhd new file mode 100644 index 000000000..be8437b51 --- /dev/null +++ b/vunit/vhdl/verification_components/test/tb_apb_master.vhd @@ -0,0 +1,138 @@ +-- This Source Code Form is subject to the terms of the Mozilla Public +-- License, v. 2.0. If a copy of the MPL was not distributed with this file, +-- You can obtain one at http://mozilla.org/MPL/2.0/. +-- +-- Copyright (c) 2014-2024, Lars Asplund lars.anders.asplund@gmail.com + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +context work.vunit_context; +context work.com_context; +use work.memory_pkg.all; +use work.bus_master_pkg.all; +use work.apb_pkg.all; +use work.logger_pkg.all; + +library osvvm; +use osvvm.RandomPkg.all; + +entity tb_apb_master is + generic ( + runner_cfg : string + ); +end entity; + +architecture a of tb_apb_master is + + constant BUS_DATA_WIDTH : natural := 16; + constant BUS_ADDRESS_WIDTH : natural := 32; + + signal clk : std_logic := '0'; + signal reset : std_logic := '0'; + signal psel : std_logic; + signal penable : std_logic; + signal paddr : std_logic_vector(BUS_ADDRESS_WIDTH-1 downto 0); + signal pwrite : std_logic; + signal pwdata : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); + signal prdata : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); + signal pready : std_logic := '0'; + + constant bus_handle : bus_master_t := new_bus(data_length => pwdata'length, + address_length => paddr'length); + constant memory : memory_t := new_memory; + constant slave_handle : apb_slave_t := new_apb_slave(memory => memory, + logger => get_logger("apb slave")); + + signal start : boolean := false; +begin + + main_stim : process + variable buf : buffer_t; + variable data : std_logic_vector(prdata'range); + variable bus_ref1, bus_ref2 : bus_reference_t; + begin + show(get_logger("apb slave"), display_handler, debug); + + test_runner_setup(runner, runner_cfg); + start <= true; + wait for 0 ns; + + if run("single_write") then + buf := allocate(memory => memory, num_bytes => 2, permissions => write_only); + mock(get_logger(bus_handle), debug); + write_bus(net, bus_handle, base_address(buf), x"1122"); + wait_until_idle(net, bus_handle); + check_only_log(get_logger(bus_handle), "Wrote 0x1122 to address 0x00000000", debug); + unmock(get_logger(bus_handle)); + + elsif run("single_read") then + buf := allocate(memory => memory, num_bytes => 2, permissions => read_only); + write_word(memory, base_address(buf), x"1234"); + read_bus(net, bus_handle, base_address(buf), data); + check_equal(data, std_logic_vector'(x"1234"), "Check read data."); + + elsif run("consecutive_reads") then + buf := allocate(memory => memory, num_bytes => 4, permissions => read_only); + write_word(memory, base_address(buf), x"1234"); + write_word(memory, base_address(buf)+2, x"5678"); + read_bus(net, bus_handle, base_address(buf), bus_ref1); + read_bus(net, bus_handle, base_address(buf)+2, bus_ref2); + await_read_bus_reply(net, bus_ref1, data); + check_equal(data, std_logic_vector'(x"1234"), "Check read data."); + await_read_bus_reply(net, bus_ref2, data); + check_equal(data, std_logic_vector'(x"5678"), "Check read data."); + + elsif run("consecutive_writes") then + buf := allocate(memory => memory, num_bytes => 4, permissions => write_only); + set_expected_word(memory, base_address(buf), x"1234"); + set_expected_word(memory, base_address(buf)+2, x"5678"); + write_bus(net, bus_handle, base_address(buf), x"1234"); + write_bus(net, bus_handle, base_address(buf)+2, x"5678"); + wait_until_idle(net, bus_handle); + check_expected_was_written(memory); + + end if; + + wait for 100 ns; + + test_runner_cleanup(runner); + wait; + end process; + test_runner_watchdog(runner, 100 us); + + U_DUT_MASTER: entity work.apb_master + generic map ( + bus_handle => bus_handle + ) + port map ( + clk => clk, + reset => reset, + psel_o => psel, + penable_o => penable, + paddr_o => paddr, + pwrite_o => pwrite, + pwdata_o => pwdata, + prdata_i => prdata, + pready_i => pready + ); + + U_DUT_SLAVE: entity work.apb_slave + generic map ( + bus_handle => slave_handle + ) + port map ( + clk => clk, + reset => reset, + psel_i => psel, + penable_i => penable, + paddr_i => paddr, + pwrite_i => pwrite, + pwdata_i => pwdata, + prdata_o => prdata, + pready_o => pready + ); + + clk <= not clk after 5 ns; +end architecture; From 24733f6db30f969eb7e2f5628a294e2eba1c0b6e Mon Sep 17 00:00:00 2001 From: c-thaler Date: Fri, 25 Oct 2024 00:48:38 +0200 Subject: [PATCH 02/22] set expected word for single write test --- vunit/vhdl/verification_components/test/tb_apb_master.vhd | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vunit/vhdl/verification_components/test/tb_apb_master.vhd b/vunit/vhdl/verification_components/test/tb_apb_master.vhd index be8437b51..59ca40ae5 100644 --- a/vunit/vhdl/verification_components/test/tb_apb_master.vhd +++ b/vunit/vhdl/verification_components/test/tb_apb_master.vhd @@ -62,10 +62,12 @@ begin if run("single_write") then buf := allocate(memory => memory, num_bytes => 2, permissions => write_only); mock(get_logger(bus_handle), debug); + set_expected_word(memory, base_address(buf), x"1122"); write_bus(net, bus_handle, base_address(buf), x"1122"); wait_until_idle(net, bus_handle); check_only_log(get_logger(bus_handle), "Wrote 0x1122 to address 0x00000000", debug); unmock(get_logger(bus_handle)); + check_expected_was_written(memory); elsif run("single_read") then buf := allocate(memory => memory, num_bytes => 2, permissions => read_only); From cd82e04d4ce969b23bb0dd9d18494ae83c7621e7 Mon Sep 17 00:00:00 2001 From: c-thaler Date: Fri, 25 Oct 2024 02:07:01 +0200 Subject: [PATCH 03/22] implement wait states --- .../verification_components/src/apb_slave.vhd | 9 +++++++ .../test/tb_apb_master.vhd | 24 +++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/vunit/vhdl/verification_components/src/apb_slave.vhd b/vunit/vhdl/verification_components/src/apb_slave.vhd index 7f698ec61..8c1bd615a 100644 --- a/vunit/vhdl/verification_components/src/apb_slave.vhd +++ b/vunit/vhdl/verification_components/src/apb_slave.vhd @@ -8,6 +8,9 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; +library osvvm; +use osvvm.RandomPkg.RandomPType; + use work.memory_pkg.all; use work.apb_pkg.all; use work.logger_pkg.all; @@ -45,6 +48,7 @@ begin end procedure; variable addr : integer; + variable rnd : RandomPType; begin drive_outputs_invalid; wait until rising_edge(clk); @@ -56,6 +60,11 @@ begin wait until psel_i = '1' and rising_edge(clk); -- ACCESS state + while rnd.Uniform(0.0, 1.0) > bus_handle.ready_high_probability loop + pready_o <= '0'; + wait until rising_edge(clk); + end loop; + pready_o <= '1'; addr := to_integer(unsigned(paddr_i)); diff --git a/vunit/vhdl/verification_components/test/tb_apb_master.vhd b/vunit/vhdl/verification_components/test/tb_apb_master.vhd index 59ca40ae5..f2e24f55c 100644 --- a/vunit/vhdl/verification_components/test/tb_apb_master.vhd +++ b/vunit/vhdl/verification_components/test/tb_apb_master.vhd @@ -43,14 +43,15 @@ architecture a of tb_apb_master is address_length => paddr'length); constant memory : memory_t := new_memory; constant slave_handle : apb_slave_t := new_apb_slave(memory => memory, - logger => get_logger("apb slave")); + logger => get_logger("apb slave"), + ready_high_probability => 0.5); signal start : boolean := false; begin main_stim : process variable buf : buffer_t; - variable data : std_logic_vector(prdata'range); + variable data, data2 : std_logic_vector(prdata'range); variable bus_ref1, bus_ref2 : bus_reference_t; begin show(get_logger("apb slave"), display_handler, debug); @@ -95,6 +96,25 @@ begin wait_until_idle(net, bus_handle); check_expected_was_written(memory); + elsif run("many_reads") then + for i in 1 to 100 loop + buf := allocate(memory => memory, num_bytes => 2, permissions => read_only); + data := std_logic_vector(to_unsigned(i, BUS_DATA_WIDTH)); + write_word(memory, base_address(buf), data); + read_bus(net, bus_handle, base_address(buf), data2); + check_equal(data2, data, "Check read data."); + end loop; + + elsif run("many_writes") then + for i in 1 to 100 loop + buf := allocate(memory => memory, num_bytes => 2, permissions => write_only); + data := std_logic_vector(to_unsigned(i, BUS_DATA_WIDTH)); + set_expected_word(memory, base_address(buf), data); + write_bus(net, bus_handle, base_address(buf), data); + end loop; + wait_until_idle(net, bus_handle); + check_expected_was_written(memory); + end if; wait for 100 ns; From 9768826293136b309f00dce2f02d88d8048b260e Mon Sep 17 00:00:00 2001 From: c-thaler Date: Mon, 28 Oct 2024 01:30:16 +0100 Subject: [PATCH 04/22] fix trailing whitespace --- vunit/vhdl/verification_components/test/tb_apb_master.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vunit/vhdl/verification_components/test/tb_apb_master.vhd b/vunit/vhdl/verification_components/test/tb_apb_master.vhd index f2e24f55c..3bdc9a521 100644 --- a/vunit/vhdl/verification_components/test/tb_apb_master.vhd +++ b/vunit/vhdl/verification_components/test/tb_apb_master.vhd @@ -126,7 +126,7 @@ begin U_DUT_MASTER: entity work.apb_master generic map ( - bus_handle => bus_handle + bus_handle => bus_handle ) port map ( clk => clk, From 64051a7cda54ce2658f178433c4fc96c126a73bf Mon Sep 17 00:00:00 2001 From: c-thaler Date: Mon, 28 Oct 2024 01:32:30 +0100 Subject: [PATCH 05/22] fix another trailing whitespace --- vunit/vhdl/verification_components/src/apb_master.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vunit/vhdl/verification_components/src/apb_master.vhd b/vunit/vhdl/verification_components/src/apb_master.vhd index cdd22ff77..9c46ccf7e 100644 --- a/vunit/vhdl/verification_components/src/apb_master.vhd +++ b/vunit/vhdl/verification_components/src/apb_master.vhd @@ -49,7 +49,7 @@ architecture behav of apb_master is begin return idle_bus; end function; - + begin PROC_MAIN: process From 1e2f86fbe2943e260a31e2dcec6e50f5fc46fa33 Mon Sep 17 00:00:00 2001 From: c-thaler Date: Tue, 29 Oct 2024 00:16:53 +0100 Subject: [PATCH 06/22] use single generic parameter All generics are now integrated into a single parameter of type apb_master_t. --- .../src/apb_master.vhd | 27 +- .../src/apb_master_pkg.vhd | 250 ++++++++++++++++++ .../verification_components/src/apb_slave.vhd | 2 +- .../src/{apb_pkg.vhd => apb_slave_pkg.vhd} | 4 +- .../test/tb_apb_master.vhd | 7 +- 5 files changed, 270 insertions(+), 20 deletions(-) create mode 100644 vunit/vhdl/verification_components/src/apb_master_pkg.vhd rename vunit/vhdl/verification_components/src/{apb_pkg.vhd => apb_slave_pkg.vhd} (96%) diff --git a/vunit/vhdl/verification_components/src/apb_master.vhd b/vunit/vhdl/verification_components/src/apb_master.vhd index 9c46ccf7e..70d3d7880 100644 --- a/vunit/vhdl/verification_components/src/apb_master.vhd +++ b/vunit/vhdl/verification_components/src/apb_master.vhd @@ -16,22 +16,21 @@ use work.queue_pkg.all; use work.sync_pkg.all; use work.logger_pkg.all; use work.log_levels_pkg.all; +use work.apb_master_pkg.all; entity apb_master is generic ( - bus_handle : bus_master_t; - drive_invalid : boolean := true; - drive_invalid_val : std_logic := 'X' + bus_handle : apb_master_t ); port ( clk : in std_logic; reset : in std_logic; psel_o : out std_logic; penable_o : out std_logic; - paddr_o : out std_logic_vector(address_length(bus_handle) - 1 downto 0); + paddr_o : out std_logic_vector(address_length(bus_handle.p_bus_handle) - 1 downto 0); pwrite_o : out std_logic; - pwdata_o : out std_logic_vector(data_length(bus_handle) - 1 downto 0); - prdata_i : in std_logic_vector(data_length(bus_handle) - 1 downto 0); + pwdata_o : out std_logic_vector(data_length(bus_handle.p_bus_handle) - 1 downto 0); + prdata_i : in std_logic_vector(data_length(bus_handle.p_bus_handle) - 1 downto 0); pready_i : in std_logic ); end entity; @@ -57,7 +56,7 @@ begin variable msg_type : msg_type_t; begin DISPATCH_LOOP : loop - receive(net, bus_handle.p_actor, request_msg); + receive(net, bus_handle.p_bus_handle.p_actor, request_msg); msg_type := message_type(request_msg); if msg_type = bus_read_msg then @@ -78,11 +77,11 @@ begin BUS_PROCESS: process procedure drive_bus_invalid is begin - if drive_invalid then - penable_o <= drive_invalid_val; - paddr_o <= (paddr_o'range => drive_invalid_val); - pwrite_o <= drive_invalid_val; - pwdata_o <= (pwdata_o'range => drive_invalid_val); + if bus_handle.p_drive_invalid then + penable_o <= bus_handle.p_drive_invalid_val; + paddr_o <= (paddr_o'range => bus_handle.p_drive_invalid_val); + pwrite_o <= bus_handle.p_drive_invalid_val; + pwdata_o <= (pwdata_o'range => bus_handle.p_drive_invalid_val); end if; end procedure; @@ -118,8 +117,8 @@ begin penable_o <= '1'; wait until (pready_i and penable_o) = '1' and rising_edge(clk); - if is_visible(bus_handle.p_logger, debug) then - debug(bus_handle.p_logger, + if is_visible(bus_handle.p_bus_handle.p_logger, debug) then + debug(bus_handle.p_bus_handle.p_logger, "Wrote 0x" & to_hstring(data_this_transaction) & " to address 0x" & to_hstring(addr_this_transaction)); end if; diff --git a/vunit/vhdl/verification_components/src/apb_master_pkg.vhd b/vunit/vhdl/verification_components/src/apb_master_pkg.vhd new file mode 100644 index 000000000..f7bff7fd3 --- /dev/null +++ b/vunit/vhdl/verification_components/src/apb_master_pkg.vhd @@ -0,0 +1,250 @@ +-- This Source Code Form is subject to the terms of the Mozilla Public +-- License, v. 2.0. If a copy of the MPL was not distributed with this file, +-- You can obtain one at http://mozilla.org/MPL/2.0/. +-- +-- Copyright (c) 2014-2024, Lars Asplund lars.anders.asplund@gmail.com + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.bus_master_pkg.all; +use work.com_pkg.all; +use work.com_types_pkg.all; +use work.logger_pkg.all; +use work.memory_pkg.memory_t; +use work.memory_pkg.to_vc_interface; + +package apb_master_pkg is + + type apb_master_t is record + -- Private + p_bus_handle : bus_master_t; + p_drive_invalid : boolean; + p_drive_invalid_val : std_logic; + p_ready_high_probability : real range 0.0 to 1.0; + end record; + + impure function new_apb_master( + data_length : natural; + address_length : natural; + logger : logger_t := bus_logger; + actor : actor_t := null_actor; + drive_invalid : boolean := true; + drive_invalid_val : std_logic := 'X'; + ready_high_probability : real := 1.0 + ) return apb_master_t; + + function get_logger(bus_handle : apb_master_t) return logger_t; + + -- Blocking: Write the bus + procedure write_bus(signal net : inout network_t; + constant bus_handle : apb_master_t; + constant address : std_logic_vector; + constant data : std_logic_vector; + -- default byte enable is all bytes + constant byte_enable : std_logic_vector := ""); + procedure write_bus(signal net : inout network_t; + constant bus_handle : apb_master_t; + constant address : natural; + constant data : std_logic_vector; + -- default byte enable is all bytes + constant byte_enable : std_logic_vector := ""); + + procedure wait_until_idle(signal net : inout network_t; + bus_handle : apb_master_t); + + -- Non blocking: Read the bus returning a reference to the future reply + procedure read_bus(signal net : inout network_t; + constant bus_handle : apb_master_t; + constant address : std_logic_vector; + variable reference : inout bus_reference_t); + + procedure read_bus(signal net : inout network_t; + constant bus_handle : apb_master_t; + constant address : natural; + variable reference : inout bus_reference_t); + + -- Blocking: read bus with immediate reply + procedure read_bus(signal net : inout network_t; + constant bus_handle : apb_master_t; + constant address : std_logic_vector; + variable data : inout std_logic_vector); + + procedure read_bus(signal net : inout network_t; + constant bus_handle : apb_master_t; + constant address : natural; + variable data : inout std_logic_vector); + + -- Blocking: Read bus and check result against expected data + procedure check_bus(signal net : inout network_t; + constant bus_handle : apb_master_t; + constant address : std_logic_vector; + constant expected : std_logic_vector; + constant msg : string := ""); + + procedure check_bus(signal net : inout network_t; + constant bus_handle : apb_master_t; + constant address : natural; + constant expected : std_logic_vector; + constant msg : string := ""); + + -- Blocking: Wait until a read from address equals the value using + -- std_match If timeout is reached error with msg + procedure wait_until_read_equals( + signal net : inout network_t; + bus_handle : apb_master_t; + addr : std_logic_vector; + value : std_logic_vector; + timeout : delay_length := delay_length'high; + msg : string := ""); + + -- Blocking: Wait until a read from address has the bit with this + -- index set to value If timeout is reached error with msg + procedure wait_until_read_bit_equals( + signal net : inout network_t; + bus_handle : apb_master_t; + addr : std_logic_vector; + idx : natural; + value : std_logic; + timeout : delay_length := delay_length'high; + msg : string := ""); +end package; + +package body apb_master_pkg is + + impure function new_apb_master( + data_length : natural; + address_length : natural; + logger : logger_t := bus_logger; + actor : actor_t := null_actor; + drive_invalid : boolean := true; + drive_invalid_val : std_logic := 'X'; + ready_high_probability : real := 1.0 + ) return apb_master_t is + variable bus_handle : bus_master_t := new_bus( + data_length => data_length, + address_length => address_length, + logger => logger, + actor => actor + ); + begin + return ( + p_bus_handle => bus_handle, + p_drive_invalid => drive_invalid, + p_drive_invalid_val => drive_invalid_val, + p_ready_high_probability => ready_high_probability + ); + end; + + function get_logger(bus_handle : apb_master_t) return logger_t is + begin + return get_logger(bus_handle.p_bus_handle); + end function; + + -- Blocking: Write the bus + procedure write_bus(signal net : inout network_t; + constant bus_handle : apb_master_t; + constant address : std_logic_vector; + constant data : std_logic_vector; + -- default byte enable is all bytes + constant byte_enable : std_logic_vector := "") is + begin + write_bus(net, bus_handle.p_bus_handle, address, data, byte_enable); + end procedure; + + procedure write_bus(signal net : inout network_t; + constant bus_handle : apb_master_t; + constant address : natural; + constant data : std_logic_vector; + -- default byte enable is all bytes + constant byte_enable : std_logic_vector := "") is + begin + write_bus(net, bus_handle.p_bus_handle, address, data, byte_enable); + end procedure; + + procedure wait_until_idle(signal net : inout network_t; + bus_handle : apb_master_t) is + begin + wait_until_idle(net, bus_handle.P_bus_handle); + end procedure; + + -- Blocking: read bus with immediate reply + procedure read_bus(signal net : inout network_t; + constant bus_handle : apb_master_t; + constant address : std_logic_vector; + variable data : inout std_logic_vector) is + begin + read_bus(net, bus_handle.p_bus_handle, address, data); + end procedure; + + procedure read_bus(signal net : inout network_t; + constant bus_handle : apb_master_t; + constant address : natural; + variable data : inout std_logic_vector) is + begin + read_bus(net, bus_handle.p_bus_handle, address, data); + end procedure; + + procedure read_bus(signal net : inout network_t; + constant bus_handle : apb_master_t; + constant address : natural; + variable reference : inout bus_reference_t) is + begin + read_bus(net, bus_handle.p_bus_handle, address, reference); + end procedure; + + procedure read_bus(signal net : inout network_t; + constant bus_handle : apb_master_t; + constant address : std_logic_vector; + variable reference : inout bus_reference_t) is + begin + read_bus(net, bus_handle.p_bus_handle, address, reference); + end procedure; + + -- Blocking: Read bus and check result against expected data + procedure check_bus(signal net : inout network_t; + constant bus_handle : apb_master_t; + constant address : std_logic_vector; + constant expected : std_logic_vector; + constant msg : string := "") is + begin + check_bus(net, bus_handle.p_bus_handle, address, expected, msg); + end procedure; + + procedure check_bus(signal net : inout network_t; + constant bus_handle : apb_master_t; + constant address : natural; + constant expected : std_logic_vector; + constant msg : string := "") is + begin + check_bus(net, bus_handle.p_bus_handle, address, expected, msg); + end procedure; + + -- Blocking: Wait until a read from address equals the value using + -- std_match If timeout is reached error with msg + procedure wait_until_read_equals( + signal net : inout network_t; + bus_handle : apb_master_t; + addr : std_logic_vector; + value : std_logic_vector; + timeout : delay_length := delay_length'high; + msg : string := "") is + begin + wait_until_read_equals(net, bus_handle.p_bus_handle, addr, value, timeout, msg); + end procedure; + + -- Blocking: Wait until a read from address has the bit with this + -- index set to value If timeout is reached error with msg + procedure wait_until_read_bit_equals( + signal net : inout network_t; + bus_handle : apb_master_t; + addr : std_logic_vector; + idx : natural; + value : std_logic; + timeout : delay_length := delay_length'high; + msg : string := "") is + begin + wait_until_read_bit_equals(net, bus_handle.p_bus_handle, addr, idx, value, timeout, msg); + end procedure; +end package body; \ No newline at end of file diff --git a/vunit/vhdl/verification_components/src/apb_slave.vhd b/vunit/vhdl/verification_components/src/apb_slave.vhd index 8c1bd615a..3dfba6885 100644 --- a/vunit/vhdl/verification_components/src/apb_slave.vhd +++ b/vunit/vhdl/verification_components/src/apb_slave.vhd @@ -12,7 +12,7 @@ library osvvm; use osvvm.RandomPkg.RandomPType; use work.memory_pkg.all; -use work.apb_pkg.all; +use work.apb_slave_pkg.all; use work.logger_pkg.all; entity apb_slave is diff --git a/vunit/vhdl/verification_components/src/apb_pkg.vhd b/vunit/vhdl/verification_components/src/apb_slave_pkg.vhd similarity index 96% rename from vunit/vhdl/verification_components/src/apb_pkg.vhd rename to vunit/vhdl/verification_components/src/apb_slave_pkg.vhd index e9fa4fc12..c89a36945 100644 --- a/vunit/vhdl/verification_components/src/apb_pkg.vhd +++ b/vunit/vhdl/verification_components/src/apb_slave_pkg.vhd @@ -14,7 +14,7 @@ use work.logger_pkg.all; use work.memory_pkg.memory_t; use work.memory_pkg.to_vc_interface; -package apb_pkg is +package apb_slave_pkg is type apb_slave_t is record ready_high_probability : real range 0.0 to 1.0; @@ -35,7 +35,7 @@ package apb_pkg is constant slave_read_msg : msg_type_t := new_msg_type("apb slave read"); end package; -package body apb_pkg is +package body apb_slave_pkg is impure function new_apb_slave( memory : memory_t; diff --git a/vunit/vhdl/verification_components/test/tb_apb_master.vhd b/vunit/vhdl/verification_components/test/tb_apb_master.vhd index 3bdc9a521..719e96f30 100644 --- a/vunit/vhdl/verification_components/test/tb_apb_master.vhd +++ b/vunit/vhdl/verification_components/test/tb_apb_master.vhd @@ -12,7 +12,8 @@ context work.vunit_context; context work.com_context; use work.memory_pkg.all; use work.bus_master_pkg.all; -use work.apb_pkg.all; +use work.apb_slave_pkg.all; +use work.apb_master_pkg.all; use work.logger_pkg.all; library osvvm; @@ -39,8 +40,8 @@ architecture a of tb_apb_master is signal prdata : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); signal pready : std_logic := '0'; - constant bus_handle : bus_master_t := new_bus(data_length => pwdata'length, - address_length => paddr'length); + constant bus_handle : apb_master_t := new_apb_master(data_length => pwdata'length, + address_length => paddr'length); constant memory : memory_t := new_memory; constant slave_handle : apb_slave_t := new_apb_slave(memory => memory, logger => get_logger("apb slave"), From d29dd9f46c07aedd04f7a1e6f6766228fe2c1869 Mon Sep 17 00:00:00 2001 From: c-thaler Date: Tue, 29 Oct 2024 01:15:36 +0100 Subject: [PATCH 07/22] reduce to single generic parameter in apb slave --- .../verification_components/src/apb_slave.vhd | 12 +++---- .../src/apb_slave_pkg.vhd | 32 +++++++++++++------ 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/vunit/vhdl/verification_components/src/apb_slave.vhd b/vunit/vhdl/verification_components/src/apb_slave.vhd index 3dfba6885..b4b61a7a4 100644 --- a/vunit/vhdl/verification_components/src/apb_slave.vhd +++ b/vunit/vhdl/verification_components/src/apb_slave.vhd @@ -17,9 +17,7 @@ use work.logger_pkg.all; entity apb_slave is generic ( - bus_handle : apb_slave_t; - drive_invalid : boolean := true; - drive_invalid_val : std_logic := 'X' + bus_handle : apb_slave_t ); port ( clk : in std_logic; @@ -41,9 +39,9 @@ begin PROC_MAIN: process procedure drive_outputs_invalid is begin - if drive_invalid then - prdata_o <= (prdata_o'range => drive_invalid_val); - pready_o <= drive_invalid_val; + if bus_handle.p_drive_invalid then + prdata_o <= (prdata_o'range => bus_handle.p_drive_invalid_val); + pready_o <= bus_handle.p_drive_invalid_val; end if; end procedure; @@ -60,7 +58,7 @@ begin wait until psel_i = '1' and rising_edge(clk); -- ACCESS state - while rnd.Uniform(0.0, 1.0) > bus_handle.ready_high_probability loop + while rnd.Uniform(0.0, 1.0) > bus_handle.p_ready_high_probability loop pready_o <= '0'; wait until rising_edge(clk); end loop; diff --git a/vunit/vhdl/verification_components/src/apb_slave_pkg.vhd b/vunit/vhdl/verification_components/src/apb_slave_pkg.vhd index c89a36945..5e00046e4 100644 --- a/vunit/vhdl/verification_components/src/apb_slave_pkg.vhd +++ b/vunit/vhdl/verification_components/src/apb_slave_pkg.vhd @@ -8,6 +8,7 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; +use work.bus_master_pkg.all; use work.com_pkg.all; use work.com_types_pkg.all; use work.logger_pkg.all; @@ -17,18 +18,23 @@ use work.memory_pkg.to_vc_interface; package apb_slave_pkg is type apb_slave_t is record - ready_high_probability : real range 0.0 to 1.0; -- Private p_actor : actor_t; p_memory : memory_t; p_logger : logger_t; + p_drive_invalid : boolean; + p_drive_invalid_val : std_logic; + p_ready_high_probability : real range 0.0 to 1.0; end record; constant apb_slave_logger : logger_t := get_logger("vunit_lib:apb_slave_pkg"); impure function new_apb_slave( memory : memory_t; - ready_high_probability : real := 1.0; - logger : logger_t := apb_slave_logger) + logger : logger_t := bus_logger; + actor : actor_t := null_actor; + drive_invalid : boolean := true; + drive_invalid_val : std_logic := 'X'; + ready_high_probability : real := 1.0) return apb_slave_t; constant slave_write_msg : msg_type_t := new_msg_type("apb slave write"); @@ -39,15 +45,21 @@ package body apb_slave_pkg is impure function new_apb_slave( memory : memory_t; - ready_high_probability : real := 1.0; - logger : logger_t := apb_slave_logger) + logger : logger_t := bus_logger; + actor : actor_t := null_actor; + drive_invalid : boolean := true; + drive_invalid_val : std_logic := 'X'; + ready_high_probability : real := 1.0) return apb_slave_t is begin - return (p_actor => new_actor, - p_memory => to_vc_interface(memory, logger), - p_logger => logger, - ready_high_probability => ready_high_probability - ); + return ( + p_memory => to_vc_interface(memory, logger), + p_logger => logger, + p_actor => new_actor, + p_drive_invalid => drive_invalid, + p_drive_invalid_val => drive_invalid_val, + p_ready_high_probability => ready_high_probability + ); end; end package body; \ No newline at end of file From 64e0096b322475347ac646571f28254702957a71 Mon Sep 17 00:00:00 2001 From: c-thaler Date: Tue, 29 Oct 2024 01:55:07 +0100 Subject: [PATCH 08/22] use null_actor/null_logger as defaults for master --- .../src/apb_master_pkg.vhd | 43 ++++++++++++------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/vunit/vhdl/verification_components/src/apb_master_pkg.vhd b/vunit/vhdl/verification_components/src/apb_master_pkg.vhd index f7bff7fd3..500ed0164 100644 --- a/vunit/vhdl/verification_components/src/apb_master_pkg.vhd +++ b/vunit/vhdl/verification_components/src/apb_master_pkg.vhd @@ -22,17 +22,15 @@ package apb_master_pkg is p_bus_handle : bus_master_t; p_drive_invalid : boolean; p_drive_invalid_val : std_logic; - p_ready_high_probability : real range 0.0 to 1.0; end record; impure function new_apb_master( data_length : natural; address_length : natural; - logger : logger_t := bus_logger; + logger : logger_t := null_logger; actor : actor_t := null_actor; drive_invalid : boolean := true; - drive_invalid_val : std_logic := 'X'; - ready_high_probability : real := 1.0 + drive_invalid_val : std_logic := 'X' ) return apb_master_t; function get_logger(bus_handle : apb_master_t) return logger_t; @@ -116,24 +114,37 @@ package body apb_master_pkg is impure function new_apb_master( data_length : natural; address_length : natural; - logger : logger_t := bus_logger; + logger : logger_t := null_logger; actor : actor_t := null_actor; drive_invalid : boolean := true; - drive_invalid_val : std_logic := 'X'; - ready_high_probability : real := 1.0 + drive_invalid_val : std_logic := 'X' ) return apb_master_t is - variable bus_handle : bus_master_t := new_bus( - data_length => data_length, - address_length => address_length, - logger => logger, - actor => actor - ); + impure function create_bus (logger : logger_t; actor : actor_t) return bus_master_t is + begin + return new_bus( + data_length => data_length, + address_length => address_length, + logger => logger, + actor => actor + ); + end function; + variable actor_tmp : actor_t := null_actor; + variable logger_tmp : logger_t := null_logger; begin + if actor = null_actor then + actor_tmp := new_actor; + else + actor_tmp := actor; + end if; + if logger = null_logger then + logger_tmp := bus_logger; + else + logger_tmp := logger; + end if; return ( - p_bus_handle => bus_handle, + p_bus_handle => create_bus(logger_tmp, actor_tmp), p_drive_invalid => drive_invalid, - p_drive_invalid_val => drive_invalid_val, - p_ready_high_probability => ready_high_probability + p_drive_invalid_val => drive_invalid_val ); end; From 51cd95318b99e2b1acb392f1e1839689f27cb200 Mon Sep 17 00:00:00 2001 From: c-thaler Date: Tue, 29 Oct 2024 01:58:56 +0100 Subject: [PATCH 09/22] use null_logger as default for apb slave --- .../src/apb_slave_pkg.vhd | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/vunit/vhdl/verification_components/src/apb_slave_pkg.vhd b/vunit/vhdl/verification_components/src/apb_slave_pkg.vhd index 5e00046e4..54adb5f71 100644 --- a/vunit/vhdl/verification_components/src/apb_slave_pkg.vhd +++ b/vunit/vhdl/verification_components/src/apb_slave_pkg.vhd @@ -30,7 +30,7 @@ package apb_slave_pkg is constant apb_slave_logger : logger_t := get_logger("vunit_lib:apb_slave_pkg"); impure function new_apb_slave( memory : memory_t; - logger : logger_t := bus_logger; + logger : logger_t := null_logger; actor : actor_t := null_actor; drive_invalid : boolean := true; drive_invalid_val : std_logic := 'X'; @@ -45,17 +45,29 @@ package body apb_slave_pkg is impure function new_apb_slave( memory : memory_t; - logger : logger_t := bus_logger; + logger : logger_t := null_logger; actor : actor_t := null_actor; drive_invalid : boolean := true; drive_invalid_val : std_logic := 'X'; ready_high_probability : real := 1.0) return apb_slave_t is + variable actor_tmp : actor_t := null_actor; + variable logger_tmp : logger_t := null_logger; begin + if actor = null_actor then + actor_tmp := new_actor; + else + actor_tmp := actor; + end if; + if logger = null_logger then + logger_tmp := bus_logger; + else + logger_tmp := logger; + end if; return ( p_memory => to_vc_interface(memory, logger), - p_logger => logger, - p_actor => new_actor, + p_logger => logger_tmp, + p_actor => actor_tmp, p_drive_invalid => drive_invalid, p_drive_invalid_val => drive_invalid_val, p_ready_high_probability => ready_high_probability From dd5143fbdc38fce01cfe9e4e791dd96d9ed06840 Mon Sep 17 00:00:00 2001 From: c-thaler Date: Tue, 29 Oct 2024 02:01:31 +0100 Subject: [PATCH 10/22] let the apb_master ctor be handled by bus_master The bus_master implementation will create an actor if null_actor is given as parameter. So we don't have to do it in apb_master. --- .../verification_components/src/apb_master_pkg.vhd | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/vunit/vhdl/verification_components/src/apb_master_pkg.vhd b/vunit/vhdl/verification_components/src/apb_master_pkg.vhd index 500ed0164..3f73745c4 100644 --- a/vunit/vhdl/verification_components/src/apb_master_pkg.vhd +++ b/vunit/vhdl/verification_components/src/apb_master_pkg.vhd @@ -119,7 +119,7 @@ package body apb_master_pkg is drive_invalid : boolean := true; drive_invalid_val : std_logic := 'X' ) return apb_master_t is - impure function create_bus (logger : logger_t; actor : actor_t) return bus_master_t is + impure function create_bus (logger : logger_t) return bus_master_t is begin return new_bus( data_length => data_length, @@ -128,21 +128,15 @@ package body apb_master_pkg is actor => actor ); end function; - variable actor_tmp : actor_t := null_actor; variable logger_tmp : logger_t := null_logger; begin - if actor = null_actor then - actor_tmp := new_actor; - else - actor_tmp := actor; - end if; if logger = null_logger then logger_tmp := bus_logger; else logger_tmp := logger; end if; return ( - p_bus_handle => create_bus(logger_tmp, actor_tmp), + p_bus_handle => create_bus(logger_tmp), p_drive_invalid => drive_invalid, p_drive_invalid_val => drive_invalid_val ); From 6ee4d32ce4368a502f95ae16aad2ee4501f5807b Mon Sep 17 00:00:00 2001 From: c-thaler Date: Fri, 1 Nov 2024 22:25:12 +0200 Subject: [PATCH 11/22] lock test_runner_cleanup entry gate Keep it locked while there is unfinished work to do. --- vunit/vhdl/verification_components/src/apb_master.vhd | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vunit/vhdl/verification_components/src/apb_master.vhd b/vunit/vhdl/verification_components/src/apb_master.vhd index 70d3d7880..609619e2c 100644 --- a/vunit/vhdl/verification_components/src/apb_master.vhd +++ b/vunit/vhdl/verification_components/src/apb_master.vhd @@ -15,6 +15,9 @@ use work.com_types_pkg.all; use work.queue_pkg.all; use work.sync_pkg.all; use work.logger_pkg.all; +use work.runner_pkg.all; +use work.run_pkg.all; +use work.run_types_pkg.all; use work.log_levels_pkg.all; use work.apb_master_pkg.all; @@ -89,14 +92,17 @@ begin variable msg_type : msg_type_t; variable addr_this_transaction : std_logic_vector(paddr_o'range) := (others => '0'); variable data_this_transaction : std_logic_vector(prdata_i'range) := (others => '0'); + constant key : key_t := get_entry_key(test_runner_cleanup); begin loop drive_bus_invalid; psel_o <= '0'; if is_empty(message_queue) then + unlock(runner, key); wait until rising_edge(clk) and not is_empty(message_queue); end if; + lock(runner, key); idle_bus <= false; wait for 0 ns; From 5c764e3e853ee6fb6b695d3cd2ef2c8776367cfc Mon Sep 17 00:00:00 2001 From: c-thaler Date: Fri, 1 Nov 2024 23:25:49 +0200 Subject: [PATCH 12/22] add support for sync interface --- .../src/apb_master.vhd | 7 ++++ .../src/apb_master_pkg.vhd | 32 +++++++++++++------ .../test/tb_apb_master.vhd | 10 ++++++ 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/vunit/vhdl/verification_components/src/apb_master.vhd b/vunit/vhdl/verification_components/src/apb_master.vhd index 609619e2c..af1beacee 100644 --- a/vunit/vhdl/verification_components/src/apb_master.vhd +++ b/vunit/vhdl/verification_components/src/apb_master.vhd @@ -71,6 +71,8 @@ begin wait until is_idle and queues_empty and rising_edge(clk); end if; handle_wait_until_idle(net, msg_type, request_msg); + elsif msg_type = wait_for_time_msg then + push(message_queue, request_msg); else unexpected_msg_type(msg_type); end if; @@ -144,6 +146,11 @@ begin reply_msg := new_msg; push_std_ulogic_vector(reply_msg, prdata_i); reply(net, request_msg, reply_msg); + + elsif msg_type = wait_for_time_msg then + handle_wait_for_time(net, msg_type, request_msg); + -- Re-align with the clock when a wait for time message was handled, because this breaks edge alignment. + wait until rising_edge(clk); end if; idle_bus <= true; diff --git a/vunit/vhdl/verification_components/src/apb_master_pkg.vhd b/vunit/vhdl/verification_components/src/apb_master_pkg.vhd index 3f73745c4..1ae693ee4 100644 --- a/vunit/vhdl/verification_components/src/apb_master_pkg.vhd +++ b/vunit/vhdl/verification_components/src/apb_master_pkg.vhd @@ -12,6 +12,7 @@ use work.bus_master_pkg.all; use work.com_pkg.all; use work.com_types_pkg.all; use work.logger_pkg.all; +use work.sync_pkg.all; use work.memory_pkg.memory_t; use work.memory_pkg.to_vc_interface; @@ -49,9 +50,6 @@ package apb_master_pkg is -- default byte enable is all bytes constant byte_enable : std_logic_vector := ""); - procedure wait_until_idle(signal net : inout network_t; - bus_handle : apb_master_t); - -- Non blocking: Read the bus returning a reference to the future reply procedure read_bus(signal net : inout network_t; constant bus_handle : apb_master_t; @@ -107,6 +105,14 @@ package apb_master_pkg is value : std_logic; timeout : delay_length := delay_length'high; msg : string := ""); + + procedure wait_until_idle(signal net : inout network_t; + handle : apb_master_t; + timeout : delay_length := max_timeout); + + procedure wait_for_time(signal net : inout network_t; + handle : apb_master_t; + delay : delay_length); end package; package body apb_master_pkg is @@ -168,12 +174,6 @@ package body apb_master_pkg is write_bus(net, bus_handle.p_bus_handle, address, data, byte_enable); end procedure; - procedure wait_until_idle(signal net : inout network_t; - bus_handle : apb_master_t) is - begin - wait_until_idle(net, bus_handle.P_bus_handle); - end procedure; - -- Blocking: read bus with immediate reply procedure read_bus(signal net : inout network_t; constant bus_handle : apb_master_t; @@ -252,4 +252,18 @@ package body apb_master_pkg is begin wait_until_read_bit_equals(net, bus_handle.p_bus_handle, addr, idx, value, timeout, msg); end procedure; + + procedure wait_until_idle(signal net : inout network_t; + handle : apb_master_t; + timeout : delay_length := max_timeout) is + begin + wait_until_idle(net, handle.p_bus_handle.p_actor, timeout); + end procedure; + + procedure wait_for_time(signal net : inout network_t; + handle : apb_master_t; + delay : delay_length) is + begin + wait_for_time(net, handle.p_bus_handle.p_actor, delay); + end procedure; end package body; \ No newline at end of file diff --git a/vunit/vhdl/verification_components/test/tb_apb_master.vhd b/vunit/vhdl/verification_components/test/tb_apb_master.vhd index 719e96f30..1a75d7d65 100644 --- a/vunit/vhdl/verification_components/test/tb_apb_master.vhd +++ b/vunit/vhdl/verification_components/test/tb_apb_master.vhd @@ -116,6 +116,16 @@ begin wait_until_idle(net, bus_handle); check_expected_was_written(memory); + elsif run("wait_between_writes") then + buf := allocate(memory => memory, num_bytes => 4, permissions => write_only); + set_expected_word(memory, base_address(buf), x"1234"); + set_expected_word(memory, base_address(buf)+2, x"5678"); + write_bus(net, bus_handle, base_address(buf), x"1234"); + wait_for_time(net, bus_handle, 500 ns); + write_bus(net, bus_handle, base_address(buf)+2, x"5678"); + wait_until_idle(net, bus_handle); + check_expected_was_written(memory); + end if; wait for 100 ns; From a321bdff9dab7a226d15888d5462885fd1100de5 Mon Sep 17 00:00:00 2001 From: c-thaler Date: Sun, 3 Nov 2024 11:41:07 +0200 Subject: [PATCH 13/22] fix whitespace issues --- vunit/vhdl/verification_components/src/apb_master.vhd | 8 ++++---- vunit/vhdl/verification_components/src/apb_master_pkg.vhd | 6 +++--- vunit/vhdl/verification_components/src/apb_slave.vhd | 4 ++-- vunit/vhdl/verification_components/src/apb_slave_pkg.vhd | 1 - vunit/vhdl/verification_components/test/tb_apb_master.vhd | 4 ++-- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/vunit/vhdl/verification_components/src/apb_master.vhd b/vunit/vhdl/verification_components/src/apb_master.vhd index af1beacee..f76ccab92 100644 --- a/vunit/vhdl/verification_components/src/apb_master.vhd +++ b/vunit/vhdl/verification_components/src/apb_master.vhd @@ -57,7 +57,7 @@ begin PROC_MAIN: process variable request_msg : msg_t; variable msg_type : msg_type_t; - begin + begin DISPATCH_LOOP : loop receive(net, bus_handle.p_bus_handle.p_actor, request_msg); msg_type := message_type(request_msg); @@ -133,16 +133,16 @@ begin elsif msg_type = bus_read_msg then addr_this_transaction := pop_std_ulogic_vector(request_msg); - + psel_o <= '1'; penable_o <= '0'; pwrite_o <= '0'; paddr_o <= addr_this_transaction; - + wait until rising_edge(clk); penable_o <= '1'; wait until (pready_i and penable_o) = '1' and rising_edge(clk); - + reply_msg := new_msg; push_std_ulogic_vector(reply_msg, prdata_i); reply(net, request_msg, reply_msg); diff --git a/vunit/vhdl/verification_components/src/apb_master_pkg.vhd b/vunit/vhdl/verification_components/src/apb_master_pkg.vhd index 1ae693ee4..d87ed302c 100644 --- a/vunit/vhdl/verification_components/src/apb_master_pkg.vhd +++ b/vunit/vhdl/verification_components/src/apb_master_pkg.vhd @@ -66,7 +66,7 @@ package apb_master_pkg is constant bus_handle : apb_master_t; constant address : std_logic_vector; variable data : inout std_logic_vector); - + procedure read_bus(signal net : inout network_t; constant bus_handle : apb_master_t; constant address : natural; @@ -78,7 +78,7 @@ package apb_master_pkg is constant address : std_logic_vector; constant expected : std_logic_vector; constant msg : string := ""); - + procedure check_bus(signal net : inout network_t; constant bus_handle : apb_master_t; constant address : natural; @@ -225,7 +225,7 @@ package body apb_master_pkg is begin check_bus(net, bus_handle.p_bus_handle, address, expected, msg); end procedure; - + -- Blocking: Wait until a read from address equals the value using -- std_match If timeout is reached error with msg procedure wait_until_read_equals( diff --git a/vunit/vhdl/verification_components/src/apb_slave.vhd b/vunit/vhdl/verification_components/src/apb_slave.vhd index b4b61a7a4..cd9d82ec2 100644 --- a/vunit/vhdl/verification_components/src/apb_slave.vhd +++ b/vunit/vhdl/verification_components/src/apb_slave.vhd @@ -33,7 +33,7 @@ entity apb_slave is end entity; architecture a of apb_slave is - + begin PROC_MAIN: process @@ -77,7 +77,7 @@ begin if penable_i = '0' then failure(bus_handle.p_logger, "penable_i must be active in the ACCESS phase."); - end if; + end if; end loop; end process; diff --git a/vunit/vhdl/verification_components/src/apb_slave_pkg.vhd b/vunit/vhdl/verification_components/src/apb_slave_pkg.vhd index 54adb5f71..a2d56c87e 100644 --- a/vunit/vhdl/verification_components/src/apb_slave_pkg.vhd +++ b/vunit/vhdl/verification_components/src/apb_slave_pkg.vhd @@ -73,5 +73,4 @@ package body apb_slave_pkg is p_ready_high_probability => ready_high_probability ); end; - end package body; \ No newline at end of file diff --git a/vunit/vhdl/verification_components/test/tb_apb_master.vhd b/vunit/vhdl/verification_components/test/tb_apb_master.vhd index 1a75d7d65..1f347eb79 100644 --- a/vunit/vhdl/verification_components/test/tb_apb_master.vhd +++ b/vunit/vhdl/verification_components/test/tb_apb_master.vhd @@ -137,7 +137,7 @@ begin U_DUT_MASTER: entity work.apb_master generic map ( - bus_handle => bus_handle + bus_handle => bus_handle ) port map ( clk => clk, @@ -153,7 +153,7 @@ begin U_DUT_SLAVE: entity work.apb_slave generic map ( - bus_handle => slave_handle + bus_handle => slave_handle ) port map ( clk => clk, From a6b150305e7867f10ba4bf427b1817f1eae6c846 Mon Sep 17 00:00:00 2001 From: c-thaler Date: Sun, 3 Nov 2024 21:24:03 +0200 Subject: [PATCH 14/22] rename APB files according to specification --- .../src/{apb_slave.vhd => apb_completer.vhd} | 0 .../src/{apb_slave_pkg.vhd => apb_completer_pkg.vhd} | 0 .../src/{apb_master.vhd => apb_requester.vhd} | 0 .../src/{apb_master_pkg.vhd => apb_requester_pkg.vhd} | 0 .../test/{tb_apb_master.vhd => tb_apb_requester.vhd} | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename vunit/vhdl/verification_components/src/{apb_slave.vhd => apb_completer.vhd} (100%) rename vunit/vhdl/verification_components/src/{apb_slave_pkg.vhd => apb_completer_pkg.vhd} (100%) rename vunit/vhdl/verification_components/src/{apb_master.vhd => apb_requester.vhd} (100%) rename vunit/vhdl/verification_components/src/{apb_master_pkg.vhd => apb_requester_pkg.vhd} (100%) rename vunit/vhdl/verification_components/test/{tb_apb_master.vhd => tb_apb_requester.vhd} (100%) diff --git a/vunit/vhdl/verification_components/src/apb_slave.vhd b/vunit/vhdl/verification_components/src/apb_completer.vhd similarity index 100% rename from vunit/vhdl/verification_components/src/apb_slave.vhd rename to vunit/vhdl/verification_components/src/apb_completer.vhd diff --git a/vunit/vhdl/verification_components/src/apb_slave_pkg.vhd b/vunit/vhdl/verification_components/src/apb_completer_pkg.vhd similarity index 100% rename from vunit/vhdl/verification_components/src/apb_slave_pkg.vhd rename to vunit/vhdl/verification_components/src/apb_completer_pkg.vhd diff --git a/vunit/vhdl/verification_components/src/apb_master.vhd b/vunit/vhdl/verification_components/src/apb_requester.vhd similarity index 100% rename from vunit/vhdl/verification_components/src/apb_master.vhd rename to vunit/vhdl/verification_components/src/apb_requester.vhd diff --git a/vunit/vhdl/verification_components/src/apb_master_pkg.vhd b/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd similarity index 100% rename from vunit/vhdl/verification_components/src/apb_master_pkg.vhd rename to vunit/vhdl/verification_components/src/apb_requester_pkg.vhd diff --git a/vunit/vhdl/verification_components/test/tb_apb_master.vhd b/vunit/vhdl/verification_components/test/tb_apb_requester.vhd similarity index 100% rename from vunit/vhdl/verification_components/test/tb_apb_master.vhd rename to vunit/vhdl/verification_components/test/tb_apb_requester.vhd From aba1bcabc0a820c96af4ec44e7ba8d2f8649d80c Mon Sep 17 00:00:00 2001 From: c-thaler Date: Sun, 3 Nov 2024 21:31:20 +0200 Subject: [PATCH 15/22] rename entities according to spec --- .../src/apb_completer.vhd | 8 +-- .../src/apb_completer_pkg.vhd | 16 ++--- .../src/apb_requester.vhd | 8 +-- .../src/apb_requester_pkg.vhd | 66 +++++++++---------- .../test/tb_apb_requester.vhd | 16 ++--- 5 files changed, 57 insertions(+), 57 deletions(-) diff --git a/vunit/vhdl/verification_components/src/apb_completer.vhd b/vunit/vhdl/verification_components/src/apb_completer.vhd index cd9d82ec2..c4d17d6f0 100644 --- a/vunit/vhdl/verification_components/src/apb_completer.vhd +++ b/vunit/vhdl/verification_components/src/apb_completer.vhd @@ -12,12 +12,12 @@ library osvvm; use osvvm.RandomPkg.RandomPType; use work.memory_pkg.all; -use work.apb_slave_pkg.all; +use work.apb_completer_pkg.all; use work.logger_pkg.all; -entity apb_slave is +entity apb_completer is generic ( - bus_handle : apb_slave_t + bus_handle : apb_completer_t ); port ( clk : in std_logic; @@ -32,7 +32,7 @@ entity apb_slave is ); end entity; -architecture a of apb_slave is +architecture a of apb_completer is begin diff --git a/vunit/vhdl/verification_components/src/apb_completer_pkg.vhd b/vunit/vhdl/verification_components/src/apb_completer_pkg.vhd index a2d56c87e..7564646a1 100644 --- a/vunit/vhdl/verification_components/src/apb_completer_pkg.vhd +++ b/vunit/vhdl/verification_components/src/apb_completer_pkg.vhd @@ -15,9 +15,9 @@ use work.logger_pkg.all; use work.memory_pkg.memory_t; use work.memory_pkg.to_vc_interface; -package apb_slave_pkg is +package apb_completer_pkg is - type apb_slave_t is record + type apb_completer_t is record -- Private p_actor : actor_t; p_memory : memory_t; @@ -27,30 +27,30 @@ package apb_slave_pkg is p_ready_high_probability : real range 0.0 to 1.0; end record; - constant apb_slave_logger : logger_t := get_logger("vunit_lib:apb_slave_pkg"); - impure function new_apb_slave( + constant apb_completer_logger : logger_t := get_logger("vunit_lib:apb_completer_pkg"); + impure function new_apb_completer( memory : memory_t; logger : logger_t := null_logger; actor : actor_t := null_actor; drive_invalid : boolean := true; drive_invalid_val : std_logic := 'X'; ready_high_probability : real := 1.0) - return apb_slave_t; + return apb_completer_t; constant slave_write_msg : msg_type_t := new_msg_type("apb slave write"); constant slave_read_msg : msg_type_t := new_msg_type("apb slave read"); end package; -package body apb_slave_pkg is +package body apb_completer_pkg is - impure function new_apb_slave( + impure function new_apb_completer( memory : memory_t; logger : logger_t := null_logger; actor : actor_t := null_actor; drive_invalid : boolean := true; drive_invalid_val : std_logic := 'X'; ready_high_probability : real := 1.0) - return apb_slave_t is + return apb_completer_t is variable actor_tmp : actor_t := null_actor; variable logger_tmp : logger_t := null_logger; begin diff --git a/vunit/vhdl/verification_components/src/apb_requester.vhd b/vunit/vhdl/verification_components/src/apb_requester.vhd index f76ccab92..622adceb4 100644 --- a/vunit/vhdl/verification_components/src/apb_requester.vhd +++ b/vunit/vhdl/verification_components/src/apb_requester.vhd @@ -19,11 +19,11 @@ use work.runner_pkg.all; use work.run_pkg.all; use work.run_types_pkg.all; use work.log_levels_pkg.all; -use work.apb_master_pkg.all; +use work.apb_requester_pkg.all; -entity apb_master is +entity apb_requester is generic ( - bus_handle : apb_master_t + bus_handle : apb_requester_t ); port ( clk : in std_logic; @@ -38,7 +38,7 @@ entity apb_master is ); end entity; -architecture behav of apb_master is +architecture behav of apb_requester is constant message_queue : queue_t := new_queue; signal idle_bus : boolean := true; diff --git a/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd b/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd index d87ed302c..ef6999a28 100644 --- a/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd +++ b/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd @@ -16,35 +16,35 @@ use work.sync_pkg.all; use work.memory_pkg.memory_t; use work.memory_pkg.to_vc_interface; -package apb_master_pkg is +package apb_requester_pkg is - type apb_master_t is record + type apb_requester_t is record -- Private p_bus_handle : bus_master_t; p_drive_invalid : boolean; p_drive_invalid_val : std_logic; end record; - impure function new_apb_master( + impure function new_apb_requester( data_length : natural; address_length : natural; logger : logger_t := null_logger; actor : actor_t := null_actor; drive_invalid : boolean := true; drive_invalid_val : std_logic := 'X' - ) return apb_master_t; + ) return apb_requester_t; - function get_logger(bus_handle : apb_master_t) return logger_t; + function get_logger(bus_handle : apb_requester_t) return logger_t; -- Blocking: Write the bus procedure write_bus(signal net : inout network_t; - constant bus_handle : apb_master_t; + constant bus_handle : apb_requester_t; constant address : std_logic_vector; constant data : std_logic_vector; -- default byte enable is all bytes constant byte_enable : std_logic_vector := ""); procedure write_bus(signal net : inout network_t; - constant bus_handle : apb_master_t; + constant bus_handle : apb_requester_t; constant address : natural; constant data : std_logic_vector; -- default byte enable is all bytes @@ -52,35 +52,35 @@ package apb_master_pkg is -- Non blocking: Read the bus returning a reference to the future reply procedure read_bus(signal net : inout network_t; - constant bus_handle : apb_master_t; + constant bus_handle : apb_requester_t; constant address : std_logic_vector; variable reference : inout bus_reference_t); procedure read_bus(signal net : inout network_t; - constant bus_handle : apb_master_t; + constant bus_handle : apb_requester_t; constant address : natural; variable reference : inout bus_reference_t); -- Blocking: read bus with immediate reply procedure read_bus(signal net : inout network_t; - constant bus_handle : apb_master_t; + constant bus_handle : apb_requester_t; constant address : std_logic_vector; variable data : inout std_logic_vector); procedure read_bus(signal net : inout network_t; - constant bus_handle : apb_master_t; + constant bus_handle : apb_requester_t; constant address : natural; variable data : inout std_logic_vector); -- Blocking: Read bus and check result against expected data procedure check_bus(signal net : inout network_t; - constant bus_handle : apb_master_t; + constant bus_handle : apb_requester_t; constant address : std_logic_vector; constant expected : std_logic_vector; constant msg : string := ""); procedure check_bus(signal net : inout network_t; - constant bus_handle : apb_master_t; + constant bus_handle : apb_requester_t; constant address : natural; constant expected : std_logic_vector; constant msg : string := ""); @@ -89,7 +89,7 @@ package apb_master_pkg is -- std_match If timeout is reached error with msg procedure wait_until_read_equals( signal net : inout network_t; - bus_handle : apb_master_t; + bus_handle : apb_requester_t; addr : std_logic_vector; value : std_logic_vector; timeout : delay_length := delay_length'high; @@ -99,7 +99,7 @@ package apb_master_pkg is -- index set to value If timeout is reached error with msg procedure wait_until_read_bit_equals( signal net : inout network_t; - bus_handle : apb_master_t; + bus_handle : apb_requester_t; addr : std_logic_vector; idx : natural; value : std_logic; @@ -107,24 +107,24 @@ package apb_master_pkg is msg : string := ""); procedure wait_until_idle(signal net : inout network_t; - handle : apb_master_t; + handle : apb_requester_t; timeout : delay_length := max_timeout); procedure wait_for_time(signal net : inout network_t; - handle : apb_master_t; + handle : apb_requester_t; delay : delay_length); end package; -package body apb_master_pkg is +package body apb_requester_pkg is - impure function new_apb_master( + impure function new_apb_requester( data_length : natural; address_length : natural; logger : logger_t := null_logger; actor : actor_t := null_actor; drive_invalid : boolean := true; drive_invalid_val : std_logic := 'X' - ) return apb_master_t is + ) return apb_requester_t is impure function create_bus (logger : logger_t) return bus_master_t is begin return new_bus( @@ -148,14 +148,14 @@ package body apb_master_pkg is ); end; - function get_logger(bus_handle : apb_master_t) return logger_t is + function get_logger(bus_handle : apb_requester_t) return logger_t is begin return get_logger(bus_handle.p_bus_handle); end function; -- Blocking: Write the bus procedure write_bus(signal net : inout network_t; - constant bus_handle : apb_master_t; + constant bus_handle : apb_requester_t; constant address : std_logic_vector; constant data : std_logic_vector; -- default byte enable is all bytes @@ -165,7 +165,7 @@ package body apb_master_pkg is end procedure; procedure write_bus(signal net : inout network_t; - constant bus_handle : apb_master_t; + constant bus_handle : apb_requester_t; constant address : natural; constant data : std_logic_vector; -- default byte enable is all bytes @@ -176,7 +176,7 @@ package body apb_master_pkg is -- Blocking: read bus with immediate reply procedure read_bus(signal net : inout network_t; - constant bus_handle : apb_master_t; + constant bus_handle : apb_requester_t; constant address : std_logic_vector; variable data : inout std_logic_vector) is begin @@ -184,7 +184,7 @@ package body apb_master_pkg is end procedure; procedure read_bus(signal net : inout network_t; - constant bus_handle : apb_master_t; + constant bus_handle : apb_requester_t; constant address : natural; variable data : inout std_logic_vector) is begin @@ -192,7 +192,7 @@ package body apb_master_pkg is end procedure; procedure read_bus(signal net : inout network_t; - constant bus_handle : apb_master_t; + constant bus_handle : apb_requester_t; constant address : natural; variable reference : inout bus_reference_t) is begin @@ -200,7 +200,7 @@ package body apb_master_pkg is end procedure; procedure read_bus(signal net : inout network_t; - constant bus_handle : apb_master_t; + constant bus_handle : apb_requester_t; constant address : std_logic_vector; variable reference : inout bus_reference_t) is begin @@ -209,7 +209,7 @@ package body apb_master_pkg is -- Blocking: Read bus and check result against expected data procedure check_bus(signal net : inout network_t; - constant bus_handle : apb_master_t; + constant bus_handle : apb_requester_t; constant address : std_logic_vector; constant expected : std_logic_vector; constant msg : string := "") is @@ -218,7 +218,7 @@ package body apb_master_pkg is end procedure; procedure check_bus(signal net : inout network_t; - constant bus_handle : apb_master_t; + constant bus_handle : apb_requester_t; constant address : natural; constant expected : std_logic_vector; constant msg : string := "") is @@ -230,7 +230,7 @@ package body apb_master_pkg is -- std_match If timeout is reached error with msg procedure wait_until_read_equals( signal net : inout network_t; - bus_handle : apb_master_t; + bus_handle : apb_requester_t; addr : std_logic_vector; value : std_logic_vector; timeout : delay_length := delay_length'high; @@ -243,7 +243,7 @@ package body apb_master_pkg is -- index set to value If timeout is reached error with msg procedure wait_until_read_bit_equals( signal net : inout network_t; - bus_handle : apb_master_t; + bus_handle : apb_requester_t; addr : std_logic_vector; idx : natural; value : std_logic; @@ -254,14 +254,14 @@ package body apb_master_pkg is end procedure; procedure wait_until_idle(signal net : inout network_t; - handle : apb_master_t; + handle : apb_requester_t; timeout : delay_length := max_timeout) is begin wait_until_idle(net, handle.p_bus_handle.p_actor, timeout); end procedure; procedure wait_for_time(signal net : inout network_t; - handle : apb_master_t; + handle : apb_requester_t; delay : delay_length) is begin wait_for_time(net, handle.p_bus_handle.p_actor, delay); diff --git a/vunit/vhdl/verification_components/test/tb_apb_requester.vhd b/vunit/vhdl/verification_components/test/tb_apb_requester.vhd index 1f347eb79..9ea03b2d5 100644 --- a/vunit/vhdl/verification_components/test/tb_apb_requester.vhd +++ b/vunit/vhdl/verification_components/test/tb_apb_requester.vhd @@ -12,20 +12,20 @@ context work.vunit_context; context work.com_context; use work.memory_pkg.all; use work.bus_master_pkg.all; -use work.apb_slave_pkg.all; -use work.apb_master_pkg.all; +use work.apb_completer_pkg.all; +use work.apb_requester_pkg.all; use work.logger_pkg.all; library osvvm; use osvvm.RandomPkg.all; -entity tb_apb_master is +entity tb_apb_requester is generic ( runner_cfg : string ); end entity; -architecture a of tb_apb_master is +architecture a of tb_apb_requester is constant BUS_DATA_WIDTH : natural := 16; constant BUS_ADDRESS_WIDTH : natural := 32; @@ -40,10 +40,10 @@ architecture a of tb_apb_master is signal prdata : std_logic_vector(BUS_DATA_WIDTH-1 downto 0); signal pready : std_logic := '0'; - constant bus_handle : apb_master_t := new_apb_master(data_length => pwdata'length, + constant bus_handle : apb_requester_t := new_apb_requester(data_length => pwdata'length, address_length => paddr'length); constant memory : memory_t := new_memory; - constant slave_handle : apb_slave_t := new_apb_slave(memory => memory, + constant slave_handle : apb_completer_t := new_apb_completer(memory => memory, logger => get_logger("apb slave"), ready_high_probability => 0.5); @@ -135,7 +135,7 @@ begin end process; test_runner_watchdog(runner, 100 us); - U_DUT_MASTER: entity work.apb_master + U_DUT_MASTER: entity work.apb_requester generic map ( bus_handle => bus_handle ) @@ -151,7 +151,7 @@ begin pready_i => pready ); - U_DUT_SLAVE: entity work.apb_slave + U_DUT_SLAVE: entity work.apb_completer generic map ( bus_handle => slave_handle ) From 2683038b4371f10452035960708ffd62818c7f8f Mon Sep 17 00:00:00 2001 From: c-thaler Date: Thu, 7 Nov 2024 23:38:40 +0200 Subject: [PATCH 16/22] implement support for pslverror Major change to support optional pslverror signal of APB3. --- .../src/apb_requester.vhd | 24 +++-- .../src/apb_requester_pkg.vhd | 90 ++++++++++++++++--- 2 files changed, 94 insertions(+), 20 deletions(-) diff --git a/vunit/vhdl/verification_components/src/apb_requester.vhd b/vunit/vhdl/verification_components/src/apb_requester.vhd index 622adceb4..4c53034a2 100644 --- a/vunit/vhdl/verification_components/src/apb_requester.vhd +++ b/vunit/vhdl/verification_components/src/apb_requester.vhd @@ -34,7 +34,8 @@ entity apb_requester is pwrite_o : out std_logic; pwdata_o : out std_logic_vector(data_length(bus_handle.p_bus_handle) - 1 downto 0); prdata_i : in std_logic_vector(data_length(bus_handle.p_bus_handle) - 1 downto 0); - pready_i : in std_logic + pready_i : in std_logic; + pslverr_i : in std_logic := '0' ); end entity; @@ -62,9 +63,8 @@ begin receive(net, bus_handle.p_bus_handle.p_actor, request_msg); msg_type := message_type(request_msg); - if msg_type = bus_read_msg then - push(message_queue, request_msg); - elsif msg_type = bus_write_msg then + if msg_type = bus_read_msg or msg_type = apb_read_msg + or msg_type = bus_write_msg or msg_type = apb_write_msg then push(message_queue, request_msg); elsif msg_type = wait_until_idle_msg then if not is_idle or not queues_empty then @@ -94,6 +94,8 @@ begin variable msg_type : msg_type_t; variable addr_this_transaction : std_logic_vector(paddr_o'range) := (others => '0'); variable data_this_transaction : std_logic_vector(prdata_i'range) := (others => '0'); + variable byte_enable_this_transaction : std_logic_vector(byte_enable_length(bus_handle)-1 downto 0); + variable error_this_transaction : std_logic := '0'; constant key : key_t := get_entry_key(test_runner_cleanup); begin loop @@ -111,9 +113,11 @@ begin request_msg := pop(message_queue); msg_type := message_type(request_msg); - if msg_type = bus_write_msg then + if msg_type = apb_write_msg then addr_this_transaction := pop_std_ulogic_vector(request_msg); data_this_transaction := pop_std_ulogic_vector(request_msg); + byte_enable_this_transaction := pop_std_ulogic_vector(request_msg); + error_this_transaction := pop_std_ulogic(request_msg); psel_o <= '1'; penable_o <= '0'; @@ -125,14 +129,20 @@ begin penable_o <= '1'; wait until (pready_i and penable_o) = '1' and rising_edge(clk); + check_equal(pslverr_i, error_this_transaction, "Unexpected error response."); + if is_visible(bus_handle.p_bus_handle.p_logger, debug) then debug(bus_handle.p_bus_handle.p_logger, "Wrote 0x" & to_hstring(data_this_transaction) & " to address 0x" & to_hstring(addr_this_transaction)); end if; - elsif msg_type = bus_read_msg then + reply_msg := new_msg; + reply(net, request_msg, reply_msg); + + elsif msg_type = apb_read_msg then addr_this_transaction := pop_std_ulogic_vector(request_msg); + error_this_transaction := pop_std_ulogic(request_msg); psel_o <= '1'; penable_o <= '0'; @@ -143,6 +153,8 @@ begin penable_o <= '1'; wait until (pready_i and penable_o) = '1' and rising_edge(clk); + check_equal(pslverr_i, error_this_transaction, "Unexpected error response."); + reply_msg := new_msg; push_std_ulogic_vector(reply_msg, prdata_i); reply(net, request_msg, reply_msg); diff --git a/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd b/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd index ef6999a28..0dcc4bb7c 100644 --- a/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd +++ b/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd @@ -36,17 +36,21 @@ package apb_requester_pkg is function get_logger(bus_handle : apb_requester_t) return logger_t; + impure function byte_enable_length(bus_handle : apb_requester_t) return natural; + -- Blocking: Write the bus procedure write_bus(signal net : inout network_t; constant bus_handle : apb_requester_t; constant address : std_logic_vector; constant data : std_logic_vector; + variable expected_error : std_logic := '0'; -- default byte enable is all bytes constant byte_enable : std_logic_vector := ""); procedure write_bus(signal net : inout network_t; constant bus_handle : apb_requester_t; constant address : natural; constant data : std_logic_vector; + variable expected_error : std_logic := '0'; -- default byte enable is all bytes constant byte_enable : std_logic_vector := ""); @@ -54,23 +58,27 @@ package apb_requester_pkg is procedure read_bus(signal net : inout network_t; constant bus_handle : apb_requester_t; constant address : std_logic_vector; - variable reference : inout bus_reference_t); + variable reference : inout bus_reference_t; + variable expected_error : std_logic := '0'); procedure read_bus(signal net : inout network_t; constant bus_handle : apb_requester_t; constant address : natural; - variable reference : inout bus_reference_t); + variable reference : inout bus_reference_t; + variable expected_error : std_logic := '0'); -- Blocking: read bus with immediate reply procedure read_bus(signal net : inout network_t; constant bus_handle : apb_requester_t; constant address : std_logic_vector; - variable data : inout std_logic_vector); + variable data : inout std_logic_vector; + variable expected_error : std_logic := '0'); procedure read_bus(signal net : inout network_t; constant bus_handle : apb_requester_t; constant address : natural; - variable data : inout std_logic_vector); + variable data : inout std_logic_vector; + variable expected_error : std_logic := '0'); -- Blocking: Read bus and check result against expected data procedure check_bus(signal net : inout network_t; @@ -113,6 +121,9 @@ package apb_requester_pkg is procedure wait_for_time(signal net : inout network_t; handle : apb_requester_t; delay : delay_length); + + constant apb_write_msg : msg_type_t := new_msg_type("write apb bus"); + constant apb_read_msg : msg_type_t := new_msg_type("read apb bus"); end package; package body apb_requester_pkg is @@ -153,58 +164,109 @@ package body apb_requester_pkg is return get_logger(bus_handle.p_bus_handle); end function; + impure function address_length(bus_handle : apb_requester_t) return natural is + begin + return bus_handle.p_bus_handle.p_address_length; + end; + + impure function byte_enable_length(bus_handle : apb_requester_t) return natural is + begin + return (bus_handle.p_bus_handle.p_data_length + bus_handle.p_bus_handle.p_byte_length - 1) + / bus_handle.p_bus_handle.p_byte_length; + end; + + impure function to_address(constant bus_handle : apb_requester_t; address : natural) return std_logic_vector is + begin + return std_logic_vector(to_unsigned(address, address_length(bus_handle))); + end; + -- Blocking: Write the bus procedure write_bus(signal net : inout network_t; constant bus_handle : apb_requester_t; constant address : std_logic_vector; constant data : std_logic_vector; + variable expected_error : std_logic := '0'; -- default byte enable is all bytes constant byte_enable : std_logic_vector := "") is + variable request_msg : msg_t := new_msg(apb_write_msg); + variable full_data : std_logic_vector(bus_handle.p_bus_handle.p_data_length-1 downto 0) := (others => '0'); + variable full_address : std_logic_vector(bus_handle.p_bus_handle.p_address_length-1 downto 0) := (others => '0'); + variable full_byte_enable : std_logic_vector(byte_enable_length(bus_handle)-1 downto 0); begin - write_bus(net, bus_handle.p_bus_handle, address, data, byte_enable); + full_address(address'length-1 downto 0) := address; + push_std_ulogic_vector(request_msg, full_address); + + full_data(data'length-1 downto 0) := data; + push_std_ulogic_vector(request_msg, full_data); + + if byte_enable = "" then + full_byte_enable := (others => '1'); + else + full_byte_enable(byte_enable'length-1 downto 0) := byte_enable; + end if; + push_std_ulogic_vector(request_msg, full_byte_enable); + push_std_ulogic(request_msg, expected_error); + + send(net, bus_handle.p_bus_handle.p_actor, request_msg); end procedure; procedure write_bus(signal net : inout network_t; constant bus_handle : apb_requester_t; constant address : natural; constant data : std_logic_vector; + variable expected_error : std_logic := '0'; -- default byte enable is all bytes constant byte_enable : std_logic_vector := "") is begin - write_bus(net, bus_handle.p_bus_handle, address, data, byte_enable); + write_bus(net, bus_handle, to_address(bus_handle, address), data, expected_error, byte_enable); end procedure; -- Blocking: read bus with immediate reply procedure read_bus(signal net : inout network_t; constant bus_handle : apb_requester_t; constant address : std_logic_vector; - variable data : inout std_logic_vector) is + variable data : inout std_logic_vector; + variable expected_error : std_logic := '0') is + variable reference : bus_reference_t; begin - read_bus(net, bus_handle.p_bus_handle, address, data); + read_bus(net, bus_handle, address, reference, expected_error); + await_read_bus_reply(net, reference, data); end procedure; procedure read_bus(signal net : inout network_t; constant bus_handle : apb_requester_t; constant address : natural; - variable data : inout std_logic_vector) is + variable data : inout std_logic_vector; + variable expected_error : std_logic := '0') is + variable reference : bus_reference_t; begin - read_bus(net, bus_handle.p_bus_handle, address, data); + read_bus(net, bus_handle, to_address(bus_handle, address), reference, expected_error); + await_read_bus_reply(net, reference, data); end procedure; + -- Non blocking read with delayed reply procedure read_bus(signal net : inout network_t; constant bus_handle : apb_requester_t; constant address : natural; - variable reference : inout bus_reference_t) is + variable reference : inout bus_reference_t; + variable expected_error : std_logic := '0') is begin - read_bus(net, bus_handle.p_bus_handle, address, reference); + read_bus(net, bus_handle, to_address(bus_handle, address), reference, expected_error); end procedure; procedure read_bus(signal net : inout network_t; constant bus_handle : apb_requester_t; constant address : std_logic_vector; - variable reference : inout bus_reference_t) is + variable reference : inout bus_reference_t; + variable expected_error : std_logic := '0') is + variable full_address : std_logic_vector(bus_handle.p_bus_handle.p_address_length-1 downto 0) := (others => '0'); + alias request_msg : msg_t is reference; begin - read_bus(net, bus_handle.p_bus_handle, address, reference); + request_msg := new_msg(apb_read_msg); + full_address(address'length-1 downto 0) := address; + push_std_ulogic_vector(request_msg, full_address); + push_std_ulogic(request_msg, expected_error); + send(net, bus_handle.p_bus_handle.p_actor, request_msg); end procedure; -- Blocking: Read bus and check result against expected data From baa2a59a58c419c07bb17cc3210b7fef7ad1b415 Mon Sep 17 00:00:00 2001 From: c-thaler Date: Fri, 8 Nov 2024 00:44:50 +0200 Subject: [PATCH 17/22] add pslverror test cases and fix issue --- .../src/apb_requester.vhd | 4 ++-- .../src/apb_requester_pkg.vhd | 24 +++++++++---------- .../test/tb_apb_requester.vhd | 19 +++++++++++++++ 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/vunit/vhdl/verification_components/src/apb_requester.vhd b/vunit/vhdl/verification_components/src/apb_requester.vhd index 4c53034a2..fba759ceb 100644 --- a/vunit/vhdl/verification_components/src/apb_requester.vhd +++ b/vunit/vhdl/verification_components/src/apb_requester.vhd @@ -129,7 +129,7 @@ begin penable_o <= '1'; wait until (pready_i and penable_o) = '1' and rising_edge(clk); - check_equal(pslverr_i, error_this_transaction, "Unexpected error response."); + check_equal(pslverr_i, error_this_transaction, "Unexpected pslverror response for write request."); if is_visible(bus_handle.p_bus_handle.p_logger, debug) then debug(bus_handle.p_bus_handle.p_logger, @@ -153,7 +153,7 @@ begin penable_o <= '1'; wait until (pready_i and penable_o) = '1' and rising_edge(clk); - check_equal(pslverr_i, error_this_transaction, "Unexpected error response."); + check_equal(pslverr_i, error_this_transaction, "Unexpected pslverror response for read request."); reply_msg := new_msg; push_std_ulogic_vector(reply_msg, prdata_i); diff --git a/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd b/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd index 0dcc4bb7c..88e532476 100644 --- a/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd +++ b/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd @@ -43,14 +43,14 @@ package apb_requester_pkg is constant bus_handle : apb_requester_t; constant address : std_logic_vector; constant data : std_logic_vector; - variable expected_error : std_logic := '0'; + constant expected_error : std_logic := '0'; -- default byte enable is all bytes constant byte_enable : std_logic_vector := ""); procedure write_bus(signal net : inout network_t; constant bus_handle : apb_requester_t; constant address : natural; constant data : std_logic_vector; - variable expected_error : std_logic := '0'; + constant expected_error : std_logic := '0'; -- default byte enable is all bytes constant byte_enable : std_logic_vector := ""); @@ -59,26 +59,26 @@ package apb_requester_pkg is constant bus_handle : apb_requester_t; constant address : std_logic_vector; variable reference : inout bus_reference_t; - variable expected_error : std_logic := '0'); + constant expected_error : std_logic := '0'); procedure read_bus(signal net : inout network_t; constant bus_handle : apb_requester_t; constant address : natural; variable reference : inout bus_reference_t; - variable expected_error : std_logic := '0'); + constant expected_error : std_logic := '0'); -- Blocking: read bus with immediate reply procedure read_bus(signal net : inout network_t; constant bus_handle : apb_requester_t; constant address : std_logic_vector; variable data : inout std_logic_vector; - variable expected_error : std_logic := '0'); + constant expected_error : std_logic := '0'); procedure read_bus(signal net : inout network_t; constant bus_handle : apb_requester_t; constant address : natural; variable data : inout std_logic_vector; - variable expected_error : std_logic := '0'); + constant expected_error : std_logic := '0'); -- Blocking: Read bus and check result against expected data procedure check_bus(signal net : inout network_t; @@ -185,7 +185,7 @@ package body apb_requester_pkg is constant bus_handle : apb_requester_t; constant address : std_logic_vector; constant data : std_logic_vector; - variable expected_error : std_logic := '0'; + constant expected_error : std_logic := '0'; -- default byte enable is all bytes constant byte_enable : std_logic_vector := "") is variable request_msg : msg_t := new_msg(apb_write_msg); @@ -214,7 +214,7 @@ package body apb_requester_pkg is constant bus_handle : apb_requester_t; constant address : natural; constant data : std_logic_vector; - variable expected_error : std_logic := '0'; + constant expected_error : std_logic := '0'; -- default byte enable is all bytes constant byte_enable : std_logic_vector := "") is begin @@ -226,7 +226,7 @@ package body apb_requester_pkg is constant bus_handle : apb_requester_t; constant address : std_logic_vector; variable data : inout std_logic_vector; - variable expected_error : std_logic := '0') is + constant expected_error : std_logic := '0') is variable reference : bus_reference_t; begin read_bus(net, bus_handle, address, reference, expected_error); @@ -237,7 +237,7 @@ package body apb_requester_pkg is constant bus_handle : apb_requester_t; constant address : natural; variable data : inout std_logic_vector; - variable expected_error : std_logic := '0') is + constant expected_error : std_logic := '0') is variable reference : bus_reference_t; begin read_bus(net, bus_handle, to_address(bus_handle, address), reference, expected_error); @@ -249,7 +249,7 @@ package body apb_requester_pkg is constant bus_handle : apb_requester_t; constant address : natural; variable reference : inout bus_reference_t; - variable expected_error : std_logic := '0') is + constant expected_error : std_logic := '0') is begin read_bus(net, bus_handle, to_address(bus_handle, address), reference, expected_error); end procedure; @@ -258,7 +258,7 @@ package body apb_requester_pkg is constant bus_handle : apb_requester_t; constant address : std_logic_vector; variable reference : inout bus_reference_t; - variable expected_error : std_logic := '0') is + constant expected_error : std_logic := '0') is variable full_address : std_logic_vector(bus_handle.p_bus_handle.p_address_length-1 downto 0) := (others => '0'); alias request_msg : msg_t is reference; begin diff --git a/vunit/vhdl/verification_components/test/tb_apb_requester.vhd b/vunit/vhdl/verification_components/test/tb_apb_requester.vhd index 9ea03b2d5..71da9ffd4 100644 --- a/vunit/vhdl/verification_components/test/tb_apb_requester.vhd +++ b/vunit/vhdl/verification_components/test/tb_apb_requester.vhd @@ -126,6 +126,25 @@ begin wait_until_idle(net, bus_handle); check_expected_was_written(memory); + elsif run("pslverror_during_read") then + buf := allocate(memory => memory, num_bytes => 2, permissions => read_only); + write_word(memory, base_address(buf), x"1234"); + mock(get_logger("check"), error); + read_bus(net, bus_handle, base_address(buf), data, '1'); + wait_until_idle(net, bus_handle); + check_only_log(get_logger("check"), + "Unexpected pslverror response for read request. - Got 0. Expected 1.", error); + unmock(get_logger("check")); + + elsif run("pslverror_during_write") then + buf := allocate(memory => memory, num_bytes => 2, permissions => write_only); + mock(get_logger("check"), error); + write_bus(net, bus_handle, base_address(buf), x"1122", '1'); + wait_until_idle(net, bus_handle); + check_only_log(get_logger("check"), + "Unexpected pslverror response for write request. - Got 0. Expected 1.", error); + unmock(get_logger("check")); + end if; wait for 100 ns; From 514a7d8b6bf4027b6ff355ff2fbc6350f49f32e8 Mon Sep 17 00:00:00 2001 From: c-thaler Date: Fri, 8 Nov 2024 23:42:09 +0200 Subject: [PATCH 18/22] fix instance names --- vunit/vhdl/verification_components/test/tb_apb_requester.vhd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vunit/vhdl/verification_components/test/tb_apb_requester.vhd b/vunit/vhdl/verification_components/test/tb_apb_requester.vhd index 71da9ffd4..9051a32e8 100644 --- a/vunit/vhdl/verification_components/test/tb_apb_requester.vhd +++ b/vunit/vhdl/verification_components/test/tb_apb_requester.vhd @@ -154,7 +154,7 @@ begin end process; test_runner_watchdog(runner, 100 us); - U_DUT_MASTER: entity work.apb_requester + U_DUT_REQUESTER: entity work.apb_requester generic map ( bus_handle => bus_handle ) @@ -170,7 +170,7 @@ begin pready_i => pready ); - U_DUT_SLAVE: entity work.apb_completer + U_DUT_COMPLETER: entity work.apb_completer generic map ( bus_handle => slave_handle ) From e2e00237d85bf3ef3ce68e2c1952a74b66ac3ac2 Mon Sep 17 00:00:00 2001 From: c-thaler Date: Sat, 9 Nov 2024 00:28:54 +0200 Subject: [PATCH 19/22] add id and unexpected message policy parameter Implementing rules 5 and 10. The logger name is set according to the id field. --- .../src/apb_requester.vhd | 5 ++++- .../src/apb_requester_pkg.vhd | 21 +++++++++++++++++-- .../test/tb_apb_requester.vhd | 9 ++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/vunit/vhdl/verification_components/src/apb_requester.vhd b/vunit/vhdl/verification_components/src/apb_requester.vhd index fba759ceb..eedd67c09 100644 --- a/vunit/vhdl/verification_components/src/apb_requester.vhd +++ b/vunit/vhdl/verification_components/src/apb_requester.vhd @@ -15,6 +15,7 @@ use work.com_types_pkg.all; use work.queue_pkg.all; use work.sync_pkg.all; use work.logger_pkg.all; +use work.vc_pkg.all; use work.runner_pkg.all; use work.run_pkg.all; use work.run_types_pkg.all; @@ -74,7 +75,9 @@ begin elsif msg_type = wait_for_time_msg then push(message_queue, request_msg); else - unexpected_msg_type(msg_type); + if bus_handle.p_unexpected_msg_type_policy = fail then + unexpected_msg_type(msg_type); + end if; end if; end loop; end process; diff --git a/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd b/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd index 88e532476..e50de5024 100644 --- a/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd +++ b/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd @@ -13,6 +13,8 @@ use work.com_pkg.all; use work.com_types_pkg.all; use work.logger_pkg.all; use work.sync_pkg.all; +use work.id_pkg.all; +use work.vc_pkg.all; use work.memory_pkg.memory_t; use work.memory_pkg.to_vc_interface; @@ -20,16 +22,20 @@ package apb_requester_pkg is type apb_requester_t is record -- Private + p_id : id_t; p_bus_handle : bus_master_t; p_drive_invalid : boolean; p_drive_invalid_val : std_logic; + p_unexpected_msg_type_policy : unexpected_msg_type_policy_t; end record; impure function new_apb_requester( + id : id_t := null_id; data_length : natural; address_length : natural; logger : logger_t := null_logger; actor : actor_t := null_actor; + unexpected_msg_type_policy : unexpected_msg_type_policy_t := fail; drive_invalid : boolean := true; drive_invalid_val : std_logic := 'X' ) return apb_requester_t; @@ -129,10 +135,12 @@ end package; package body apb_requester_pkg is impure function new_apb_requester( + id : id_t := null_id; data_length : natural; address_length : natural; logger : logger_t := null_logger; actor : actor_t := null_actor; + unexpected_msg_type_policy : unexpected_msg_type_policy_t := fail; drive_invalid : boolean := true; drive_invalid_val : std_logic := 'X' ) return apb_requester_t is @@ -146,16 +154,25 @@ package body apb_requester_pkg is ); end function; variable logger_tmp : logger_t := null_logger; + variable id_tmp : id_t := null_id; + constant parent : id_t := get_id("vunit_lib:apb_requester"); begin + if id = null_id then + id_tmp := get_id(to_string(num_children(parent) + 1), parent); + else + id_tmp := id; + end if; if logger = null_logger then - logger_tmp := bus_logger; + logger_tmp := get_logger(id_tmp); else logger_tmp := logger; end if; return ( + p_id => id_tmp, p_bus_handle => create_bus(logger_tmp), p_drive_invalid => drive_invalid, - p_drive_invalid_val => drive_invalid_val + p_drive_invalid_val => drive_invalid_val, + p_unexpected_msg_type_policy => unexpected_msg_type_policy ); end; diff --git a/vunit/vhdl/verification_components/test/tb_apb_requester.vhd b/vunit/vhdl/verification_components/test/tb_apb_requester.vhd index 9051a32e8..d78fe11f5 100644 --- a/vunit/vhdl/verification_components/test/tb_apb_requester.vhd +++ b/vunit/vhdl/verification_components/test/tb_apb_requester.vhd @@ -54,6 +54,8 @@ begin variable buf : buffer_t; variable data, data2 : std_logic_vector(prdata'range); variable bus_ref1, bus_ref2 : bus_reference_t; + constant unexpected_message_type : msg_type_t := new_msg_type("unexpected message"); + variable unexpected_message : msg_t := new_msg(unexpected_message_type); begin show(get_logger("apb slave"), display_handler, debug); @@ -145,6 +147,13 @@ begin "Unexpected pslverror response for write request. - Got 0. Expected 1.", error); unmock(get_logger("check")); + elsif run("unexpected_msg_type_policy_fail") then + mock(get_logger("vunit_lib:com"), failure); + send(net, bus_handle.p_bus_handle.p_actor, unexpected_message); + check_only_log(get_logger("vunit_lib:com"), + "Got unexpected message unexpected message", failure); + unmock(get_logger("vunit_lib:com")); + end if; wait for 100 ns; From 9d79889b10f5ceeb93460f7750da0d0957670a8c Mon Sep 17 00:00:00 2001 From: c-thaler Date: Thu, 30 Jan 2025 00:20:31 +0100 Subject: [PATCH 20/22] Started with switching to std_cfg (WIP) --- .../verification_components/src/apb_requester_pkg.vhd | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd b/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd index e50de5024..86da1ebdf 100644 --- a/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd +++ b/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd @@ -27,6 +27,7 @@ package apb_requester_pkg is p_drive_invalid : boolean; p_drive_invalid_val : std_logic; p_unexpected_msg_type_policy : unexpected_msg_type_policy_t; + p_std_cfg : std_cfg_t; end record; impure function new_apb_requester( @@ -156,7 +157,14 @@ package body apb_requester_pkg is variable logger_tmp : logger_t := null_logger; variable id_tmp : id_t := null_id; constant parent : id_t := get_id("vunit_lib:apb_requester"); + variable std_cfg : std_cfg_t; begin + std_cfg := create_std_cfg( + id => get_id(to_string(num_children(parent) + 1), parent), + provider => "vunit_lib", + vc_name => "apb_requester", + unexpected_msg_type_policy => unexpected_msg_type_policy + ); if id = null_id then id_tmp := get_id(to_string(num_children(parent) + 1), parent); else @@ -172,7 +180,8 @@ package body apb_requester_pkg is p_bus_handle => create_bus(logger_tmp), p_drive_invalid => drive_invalid, p_drive_invalid_val => drive_invalid_val, - p_unexpected_msg_type_policy => unexpected_msg_type_policy + p_unexpected_msg_type_policy => unexpected_msg_type_policy, + p_std_cfg => std_cfg ); end; From 3c036e3a02d0f7689897bfec12fd2a002b0e692d Mon Sep 17 00:00:00 2001 From: c-thaler Date: Wed, 5 Feb 2025 22:17:27 +0100 Subject: [PATCH 21/22] update copyright header --- vunit/vhdl/verification_components/src/apb_completer.vhd | 2 +- vunit/vhdl/verification_components/src/apb_completer_pkg.vhd | 2 +- vunit/vhdl/verification_components/src/apb_requester.vhd | 2 +- vunit/vhdl/verification_components/src/apb_requester_pkg.vhd | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/vunit/vhdl/verification_components/src/apb_completer.vhd b/vunit/vhdl/verification_components/src/apb_completer.vhd index c4d17d6f0..ef4b229d7 100644 --- a/vunit/vhdl/verification_components/src/apb_completer.vhd +++ b/vunit/vhdl/verification_components/src/apb_completer.vhd @@ -2,7 +2,7 @@ -- License, v. 2.0. If a copy of the MPL was not distributed with this file, -- You can obtain one at http://mozilla.org/MPL/2.0/. -- --- Copyright (c) 2014-2024, Lars Asplund lars.anders.asplund@gmail.com +-- Copyright (c) 2014-2025, Lars Asplund lars.anders.asplund@gmail.com library ieee; use ieee.std_logic_1164.all; diff --git a/vunit/vhdl/verification_components/src/apb_completer_pkg.vhd b/vunit/vhdl/verification_components/src/apb_completer_pkg.vhd index 7564646a1..6f1767dbf 100644 --- a/vunit/vhdl/verification_components/src/apb_completer_pkg.vhd +++ b/vunit/vhdl/verification_components/src/apb_completer_pkg.vhd @@ -2,7 +2,7 @@ -- License, v. 2.0. If a copy of the MPL was not distributed with this file, -- You can obtain one at http://mozilla.org/MPL/2.0/. -- --- Copyright (c) 2014-2024, Lars Asplund lars.anders.asplund@gmail.com +-- Copyright (c) 2014-2025, Lars Asplund lars.anders.asplund@gmail.com library ieee; use ieee.std_logic_1164.all; diff --git a/vunit/vhdl/verification_components/src/apb_requester.vhd b/vunit/vhdl/verification_components/src/apb_requester.vhd index eedd67c09..444b241fd 100644 --- a/vunit/vhdl/verification_components/src/apb_requester.vhd +++ b/vunit/vhdl/verification_components/src/apb_requester.vhd @@ -2,7 +2,7 @@ -- License, v. 2.0. If a copy of the MPL was not distributed with this file, -- You can obtain one at http://mozilla.org/MPL/2.0/. -- --- Copyright (c) 2014-2024, Lars Asplund lars.anders.asplund@gmail.com +-- Copyright (c) 2014-2025, Lars Asplund lars.anders.asplund@gmail.com library ieee; use ieee.std_logic_1164.all; diff --git a/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd b/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd index 86da1ebdf..d65a1c894 100644 --- a/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd +++ b/vunit/vhdl/verification_components/src/apb_requester_pkg.vhd @@ -2,7 +2,7 @@ -- License, v. 2.0. If a copy of the MPL was not distributed with this file, -- You can obtain one at http://mozilla.org/MPL/2.0/. -- --- Copyright (c) 2014-2024, Lars Asplund lars.anders.asplund@gmail.com +-- Copyright (c) 2014-2025, Lars Asplund lars.anders.asplund@gmail.com library ieee; use ieee.std_logic_1164.all; From bb9c297345f9397836ce56fe0272d78ad32f0f5f Mon Sep 17 00:00:00 2001 From: Christian Thaler Date: Mon, 17 Feb 2025 15:35:38 +0100 Subject: [PATCH 22/22] Fix date in testbench copyright header --- vunit/vhdl/verification_components/test/tb_apb_requester.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vunit/vhdl/verification_components/test/tb_apb_requester.vhd b/vunit/vhdl/verification_components/test/tb_apb_requester.vhd index d78fe11f5..800dae7af 100644 --- a/vunit/vhdl/verification_components/test/tb_apb_requester.vhd +++ b/vunit/vhdl/verification_components/test/tb_apb_requester.vhd @@ -2,7 +2,7 @@ -- License, v. 2.0. If a copy of the MPL was not distributed with this file, -- You can obtain one at http://mozilla.org/MPL/2.0/. -- --- Copyright (c) 2014-2024, Lars Asplund lars.anders.asplund@gmail.com +-- Copyright (c) 2014-2025, Lars Asplund lars.anders.asplund@gmail.com library ieee; use ieee.std_logic_1164.all;