I have a general question regarding the calling of procedures with other types. In the general sense, what is the correct way to declare an overload of a procedure so it may be called later using multiple types?
Consider the dummy case of a simple procedure that should work the same for both std_logic_vector
/ unsigned
/ std_logic
. The unsigned
variant in my example will fail bc of a looped call to itself, and the std_logic
variant will fail because of an ambiguous call. However, directly converting in the procedure call is not allowed and will cause an error as well (ref: IEEE Std 1076-2008 section 4.2.2.3 "Signal parameters"). Creating an intermediate signal is also not an option, as signals cannot be declared in a procedure's declarative part.
What is the best practice for making overloads when knowing the core procedure will handle all cases the same way (as with my dummy case of using the "=" operator)?
package body dummy_pkg is
procedure dummy_procedure(
signal value_1 : std_logic_vector;
signal value_2 : std_logic_vector
) is
begin
assert value_1 = value_2
report "dummy_procedure: value_1 and value_2 are not equal"
severity error;
wait until value_1'event or value_2'event;
end procedure dummy_procedure;
procedure dummy_procedure(
signal value_1 : unsigned;
signal value_2 : unsigned
) is
begin
dummy_procedure(
value_1 => value_1,
value_2 => value_2
);
end procedure dummy_procedure;
procedure dummy_procedure(
signal value_1 : std_logic;
signal value_2 : std_logic
) is
begin
dummy_procedure(
value_1(0) => value_1,
value_2(0) => value_2
);
end procedure dummy_procedure;
end package body dummy_pkg;
I understand I can work around this by simply writing the procedure out for each type, but if I am missing an obvious solution, it would be nice to learn for future use.
I think I figured it out! (But I will keep the question open if there are other thoughts on the matter). From page 17 of "VHDL-2008; Just the new stuff", I found that I can declare a generic type as the generic of a procedure. From that, I can declare any new with the generic map locked to a specific type. The example becomes then (note we lose all but one procedure body)
package dummy_pkg is
-- Procedure declaration for procedure
procedure dummy_procedure
generic(type gt_generic_type)
parameter(
signal value_1 : gt_generic_type;
signal value_2 : gt_generic_type
);
procedure dummy_procedure is new dummy_procedure
generic map (gt_generic_type => std_logic_vector);
procedure dummy_procedure is new dummy_procedure
generic map (gt_generic_type => unsigned);
procedure dummy_procedure is new dummy_procedure
generic map (gt_generic_type => std_logic);
end package dummy_pkg;
package body dummy_pkg is
procedure dummy_procedure
generic(type gt_generic_type)
parameter(
signal value_1 : gt_generic_type;
signal value_2 : gt_generic_type
)
is
begin
assert value_1 = value_2
report "dummy_procedure: value_1 and value_2 are not equal"
severity error;
wait until value_1'event or value_2'event;
end procedure dummy_procedure;
end package body dummy_pkg;
See also how to pass functions to the procedure so that may use type specific functions (e.g to_string
): Can the VHDL image attribute be invoked on a generic type?