Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions vunit/vhdl/check/src/checker_pkg-body.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -312,4 +312,14 @@ package body checker_pkg is
")");
end function;

impure function to_integer(checker : checker_t) return integer is
begin
return to_integer(checker.p_data);
end;

impure function to_checker(value : integer) return checker_t is
begin
return (p_data => to_integer_vector_ptr(value));
end;

end package body;
3 changes: 3 additions & 0 deletions vunit/vhdl/check/src/checker_pkg.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ package checker_pkg is
procedure get_checker_stat(checker : checker_t;
variable stat : out checker_stat_t);

impure function to_integer(checker : checker_t) return integer;
impure function to_checker(value : integer) return checker_t;

-- Private
impure function p_has_unhandled_checks return boolean;
impure function p_register_unhandled_check(checker : checker_t) return unhandled_check_id_t;
Expand Down
5 changes: 5 additions & 0 deletions vunit/vhdl/check/test/tb_checker.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ begin
assert_true(stat1 + stat2 = (31, 16, 15), "Expected sum = (31, 16, 15)");
passed := to_string(stat1) = "checker_stat'(n_checks => 20, n_failed => 13, n_passed => 7)";
assert_true(passed, "Format error of checker_stat_t. Got:" & to_string(stat1));

elsif run("Test checker to/from integer conversion") then
assert_true(to_checker(to_integer(my_checker)) = my_checker);
assert_true(to_checker(to_integer(null_checker)) = null_checker);

end if;
end loop;

Expand Down
18 changes: 18 additions & 0 deletions vunit/vhdl/com/src/com_types.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,12 @@ package com_types_pkg is
alias push_dict_t_ref is push_ref[msg_t, dict_t];
alias pop_dict_t_ref is pop_ref[msg_t return dict_t];

-- Misc
impure function to_integer(actor : actor_t) return integer;
impure function to_actor(value : integer) return actor_t;

-- Private
impure function is_valid(code : integer) return boolean;
end package;

package body com_types_pkg is
Expand Down Expand Up @@ -870,5 +876,17 @@ package body com_types_pkg is
return pop_ref(msg.data);
end;

-----------------------------------------------------------------------------
-- Misc
-----------------------------------------------------------------------------
impure function to_integer(actor : actor_t) return integer is
begin
return actor.p_id_number;
end;

impure function to_actor(value : integer) return actor_t is
begin
return (p_id_number => value);
end;

end package body com_types_pkg;
5 changes: 5 additions & 0 deletions vunit/vhdl/com/test/tb_com.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -1384,6 +1384,11 @@ begin

unmock(com_logger);

elsif run("Test actor to/from integer conversion") then
actor := new_actor;
check(to_actor(to_integer(actor)) = actor);
check(to_actor(to_integer(null_actor)) = null_actor);

-- Deprecated APIs
elsif run("Test that use of deprecated API leads to an error") then
mock(com_logger);
Expand Down
5 changes: 5 additions & 0 deletions vunit/vhdl/logging/src/logger_pkg-body.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ package body logger_pkg is
return to_integer(logger.p_data);
end;

impure function to_logger(value : integer) return logger_t is
begin
return (p_data => to_integer_vector_ptr(value));
end;

procedure add_child(logger : logger_t; child : logger_t) is
constant children : integer_vector_ptr_t := to_integer_vector_ptr(get(logger.p_data, children_idx));
begin
Expand Down
7 changes: 7 additions & 0 deletions vunit/vhdl/logging/src/logger_pkg.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -427,4 +427,11 @@ package logger_pkg is
-- Return the number of unchecked messages in the mock queue
impure function mock_queue_length return natural;

-----------------------------------------------------------------------------
-- Misc
-----------------------------------------------------------------------------
impure function to_integer(logger : logger_t) return integer;
impure function to_logger(value : integer) return logger_t;


end package;
4 changes: 4 additions & 0 deletions vunit/vhdl/logging/test/tb_log.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,10 @@ begin
check_log_file(file_handlers(i), log_file_name & integer'image(i), entries);
end loop;

elsif run("Test logger to/from integer conversion") then
assert_true(to_logger(to_integer(logger)) = logger);
assert_true(to_logger(to_integer(null_logger)) = null_logger);

end if;

test_runner_cleanup(runner);
Expand Down
1 change: 1 addition & 0 deletions vunit/vhdl/verification_components/src/vc_context.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ context vc_context is
use vunit_lib.stream_slave_pkg.all;
use vunit_lib.sync_pkg.all;
use vunit_lib.uart_pkg.all;
use vunit_lib.vc_pkg.all;
use vunit_lib.wishbone_pkg.all;
context vunit_lib.com_context;
end context;
178 changes: 178 additions & 0 deletions vunit/vhdl/verification_components/src/vc_pkg.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
-- 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 [email protected]
--
-- This package contains common functionality for VCs.

context work.vunit_context;
context work.com_context;

package vc_pkg is
type unexpected_msg_type_policy_t is (fail, ignore);

type std_cfg_t is record
p_data : integer_vector_ptr_t;
end record;

constant null_std_cfg : std_cfg_t := (
p_data => null_integer_vector_ptr
);

-- Creates a standard VC configuration with an id, an actor, a logger, a
-- checker, and an unexpected message type policy.
--
-- If id = null_id, the id will be assigned the name provider:vc_name:n where n is 1
-- for the first instance and increasing with one for every additional instance.
--
-- The id must not have an associated actor before the call as that may indicate
-- several users of the same actor.
--
-- If a logger exist for the id, it will be reused. If not, a new logger is created.
-- A new checker is created that reports to the logger.
impure function create_std_cfg(
id : id_t := null_id;
provider : string := "";
vc_name : string := "";
unexpected_msg_type_policy : unexpected_msg_type_policy_t := fail
) return std_cfg_t;

-- Used to create enumerated ids from a parent id. The first created
-- id will be <parent name>:1, the second <parent name>:2 and so on
impure function enumerate(parent : id_t) return id_t;

-- These functions extracts information from the standard VC configuration
impure function get_id(std_cfg : std_cfg_t) return id_t;
impure function get_actor(std_cfg : std_cfg_t) return actor_t;
impure function get_logger(std_cfg : std_cfg_t) return logger_t;
impure function get_checker(std_cfg : std_cfg_t) return checker_t;
impure function unexpected_msg_type_policy(std_cfg : std_cfg_t) return unexpected_msg_type_policy_t;

-- Handle messages with unexpected message type according to the standard configuration
procedure unexpected_msg_type(msg_type : msg_type_t; std_cfg : std_cfg_t);

end package;

package body vc_pkg is
constant vc_pkg_logger : logger_t := get_logger("vunit_lib:vc_pkg");
constant vc_pkg_checker : checker_t := new_checker(vc_pkg_logger);

constant id_idx : natural := 0;
constant actor_idx : natural := 1;
constant logger_idx : natural := 2;
constant checker_idx : natural := 3;
constant unexpected_msg_type_policy_idx : natural := 4;
constant std_cfg_length : natural := unexpected_msg_type_policy_idx + 1;

impure function enumerate(parent : id_t) return id_t is
begin
return get_id(to_string(num_children(parent) + 1), parent => parent);
end;

impure function create_std_cfg(
id : id_t := null_id;
provider : string := "";
vc_name : string := "";
unexpected_msg_type_policy : unexpected_msg_type_policy_t := fail
) return std_cfg_t is
variable std_cfg : std_cfg_t;
variable provider_id : id_t;
variable vc_id : id_t;
variable instance_id : id_t;
variable actor : actor_t;
variable logger : logger_t;
begin
std_cfg.p_data := new_integer_vector_ptr(std_cfg_length);

if id /= null_id then
instance_id := id;
else
if provider = "" then
check_failed(vc_pkg_checker, "A provider must be provided.");

-- Simplifies testing when vc_pkg_checker logger is mocked
return null_std_cfg;
end if;

if vc_name = "" then
check_failed(vc_pkg_checker, "A VC name must be provided.");

-- Simplifies testing when vc_pkg_checker logger is mocked
return null_std_cfg;
end if;

provider_id := get_id(provider);
vc_id := get_id(vc_name, parent => provider_id);
instance_id := enumerate(vc_id);
end if;
set(std_cfg.p_data, id_idx, to_integer(instance_id));

if find(instance_id, enable_deferred_creation => false) /= null_actor then
check_failed(vc_pkg_checker, "An actor already exists for " & full_name(instance_id) & ".");

-- Simplifies testing when vc_pkg_checker logger is mocked
return null_std_cfg;
else
actor := new_actor(instance_id);
end if;
set(std_cfg.p_data, actor_idx, to_integer(actor));

logger := get_logger(instance_id);
set(std_cfg.p_data, logger_idx, to_integer(logger));

set(std_cfg.p_data, checker_idx, to_integer(new_checker(logger)));

set(
std_cfg.p_data,
unexpected_msg_type_policy_idx,
unexpected_msg_type_policy_t'pos(unexpected_msg_type_policy)
);

return std_cfg;
end;

impure function get_id(std_cfg : std_cfg_t) return id_t is
begin
return to_id(get(std_cfg.p_data, id_idx));
end;

impure function get_actor(std_cfg : std_cfg_t) return actor_t is
begin
return to_actor(get(std_cfg.p_data, actor_idx));
end;

impure function get_logger(std_cfg : std_cfg_t) return logger_t is
begin
return to_logger(get(std_cfg.p_data, logger_idx));
end;

impure function get_checker(std_cfg : std_cfg_t) return checker_t is
begin
return to_checker(get(std_cfg.p_data, checker_idx));
end;

impure function unexpected_msg_type_policy(std_cfg : std_cfg_t) return unexpected_msg_type_policy_t is
begin
return unexpected_msg_type_policy_t'val(get(std_cfg.p_data, unexpected_msg_type_policy_idx));
end;

procedure unexpected_msg_type(msg_type : msg_type_t;
std_cfg : std_cfg_t) is
constant code : integer := msg_type.p_code;
begin
if is_already_handled(msg_type) or unexpected_msg_type_policy(std_cfg) = ignore then
null;
elsif is_valid(code) then
check_failed(
get_checker(std_cfg),
"Got unexpected message " & to_string(to_string_ptr(get(p_msg_types.p_name_ptrs, code)))
);
else
check_failed(
get_checker(std_cfg),
"Got invalid message with code " & to_string(code)
);
end if;
end procedure;
end package body;
Loading