Search code examples
vhdl

ignore returned value procedure/function VHDL


I have several functions and procedures in a VHDL package. I wanted to ask if there is a way of ignore the out items of these. I know the open keyword for port maps. I am using dummy signals assigned to the procedure out. But it might be more efficient way to do this.

¿Is there such a thing for VHDL? If I set the out signals to open I get the following error: "Formal e5 of mode out must have an associated actual"

Thanks in advance, Antonio

EDITED: code

procedure reg2ind
 (signal reg : in std_logic_vector(15 downto 0);
  signal e1,e2,e3,e4,e5,e6,e7,e8 : out std_logic;
  signal e9,e10,e11,e12,e13,e14,e15,e16 : out std_logic) is 
begin
  e1 <= reg(0);
  e2 <= reg(1);      
  e3 <= reg(2);
  e4 <= reg(3);
  e5 <= reg(4);
  e6 <= reg(5);
  e7 <= reg(6);
  e8 <= reg(7);
  e9 <= reg(8);
  e10 <= reg(9);
  e11 <= reg(10);
  e12 <= reg(11);
  e13 <= reg(12);
  e14 <= reg(13);
  e15 <= reg(14);
  e16 <= reg(15);
end reg2ind;

When I use it:

reg2ind(val183,ord_p.err.err_17,ord_p.err.err_18,
ord_p.err.err_19,ord_p.err.err_20,open,open,open,open,open,open,
open,open,open,open, open,open);

Solution

  • The lack of an MCVE isn't critical to understanding the analysis error.

    See IEEE Std 107-2008, 10.7 Procedure call statement, para 4:

    For each formal parameter of a procedure, a procedure call shall specify exactly one corresponding actual parameter. This actual parameter is specified either explicitly, by an association element (other than the actual open) in the association list or, in the absence of such an association element, by a default expression (see 6.5.2).

    See 4.2 Subprogram declarations, 4.2.2.3 Signal parameters para 1:

    For a formal parameter of class signal, references to the signal, the driver of the signal, or both, are passed into the subprogram call.

    and para 6:

    If an actual signal is associated with a signal parameter of any mode, the actual shall be denoted by a static signal name. It is an error if a conversion function or type conversion appears in either the formal part or the actual part of an association element that associates an actual signal with a formal signal parameter.

    Also see 14.6 Dynamic elaboration, para 2, b) (in part):

    Execution of a subprogram call involves the elaboration of the parameter association list. ...

    Dynamic elaboration is incompatible with open which removes drivers that other calls to the same procedure might require.

    So the rule as shown in 4.2 Subprogram declarations, 4.2.2.3 Signal parameters paragraph 6 requires the actual be a static signal name.

    This particular example of a procedure is uninteresting, simply assigning elements of an array input to signal outputs.

    An MCVE:

    library ieee;
    use ieee.std_logic_1164.all;
    
    entity foo is
    end entity;
    
    architecture fum of foo is   
        procedure reg2ind
         (signal reg : in std_logic_vector(15 downto 0);
          signal e1,e2,e3,e4,e5,e6,e7,e8 : out std_logic;
          signal e9,e10,e11,e12,e13,e14,e15,e16 : out std_logic) is 
        begin
          e1 <= reg(0);
          e2 <= reg(1);      
          e3 <= reg(2);
          e4 <= reg(3);
          e5 <= reg(4);
          e6 <= reg(5);
          e7 <= reg(6);
          e8 <= reg(7);
          e9 <= reg(8);
          e10 <= reg(9);
          e11 <= reg(10);
          e12 <= reg(11);
          e13 <= reg(12);
          e14 <= reg(13);
          e15 <= reg(14);
          e16 <= reg(15);
        end procedure reg2ind;
    
        signal val183:  std_logic_vector (15 downto 0);
        type err_record is
            record
                err_17: std_logic;
                err_18: std_logic;
                err_19: std_logic;
                err_20: std_logic;
            end record;
        type some_record is 
            record
            err: err_record;
            end record;
    
        signal ord_p: some_record;
    
        signal open5, open6, open7,
               open8, open9, open10,
               open11, open12, open13,
               open14, open15, open16:      std_logic;
    begin
    
        reg2ind(val183,ord_p.err.err_17,ord_p.err.err_18,
        ord_p.err.err_19,ord_p.err.err_20,open5,open6,open7,open8,open5,open6,
        open7,open8,open9,open10, open11,open12);  -- with dummy outputs
    
        -- reg2ind(val183,ord_p.err.err_17,ord_p.err.err_18,
        -- ord_p.err.err_19,ord_p.err.err_20,open,open,open,open,open,open,
        -- open,open,open,open, open,open);  -- as presented  FAILS
    
    
    end architecture;
    

    The interested reader can explore the limitations of using signal based parameters.

    The simplest solution might be to use an aggregate assignment target with elements re-arranged to match the actual's ordering instead of a procedure call:

        (ord_p.err.err_20, ord_p.err.err_19, ord_p.err.err_18, ord_p.err.err_17) <=
            val183(3 downto 0);
    

    Re-arranging the target allows the right hand side to be a slice name instead of an aggregate that would also required a qualified expression. This is less textual complexity than a procedure call.

    Any impetus for hiding detail by using a procedure call could be accompanied by providing a procedure with fewer parameters.

    Function calls are expressions and it's not semantically possible to ignore their result value. You could enclose a statement containing a function call or a procedure call statement in a conditionally executed statement (e.g. if statement, case statement).