vhdlvhdl-2008

How to handle procedure overloads of signals in VHDL-2008


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.


Solution

  • 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?