I know that in VHDL each function call is instantiated as a separate combinational circuit. I am writing a function that takes in a 4 bit value and returns a 7 bit value from a look up table. The declaration in the package head looks like this:

function my_function(lv: std_logic_vector(3 downto 0)) return std_logic_vector(6 downto 0);

The compiler is generating error. It seems to me that the function declaration cannot include the size of the logic vector. Why? Does the same apply to integers where the range of integer value be given?

  • \$\begingroup\$ You are only allowed to provide a type mark for the return value of a function and not a subtype indication. Note that a type mark can also be the name of a subtype which does supply a constraint. Specifying an return index constraint isn't needed. Where ever the result is used it will be bounds checked (if required), particularly for assignment. See IEEE Std 2076-2008 4.2 Subprogram declarations, 6.3 Subtype declarations. \$\endgroup\$ – user8352 Dec 20 '15 at 14:50

This is mostly for Jonathan Drolet but there's also a lesson here. Note that parameter argument to my_function supplies a type mark with a subtype indication. This is valid in VHDL.

library ieee;
use ieee.std_logic_1164.all;

entity myfunc is
end entity;

architecture foo of myfunc is
    function my_function(lv: std_logic_vector(3 downto 0)) 
            return std_logic_vector is  
    return lv & "000";
    end function;

    constant fumble:  std_logic_vector (3 downto 0) := x"E";
    signal humble:    std_logic_vector (6 downto 0);
    humble <= my_function(fumble);

end architecture;

This code analyzes, elaborates and simulates.

Note that the return mark is an unconstrained subtype and the result value is assigned to a declared signal with a subtype indication (supplying an index constraint).

There are rules specifically for determining the effective value of a signal that require the bounds be checked after an implicit subtype conversion. Providing a return value that doesn't match the bounds of humble would result in a run time error causing simulation to end without successfully completing.

In other words a constraint isn't necessary here. The return value subtype indication is derived internally, and as is shown in this from the input parameter.


I can't tell you why, but I can tell you that this is correct, you can't specify the size of std_logic_vector in function.

Either create a subtype of the appropriate size:

subtype my_function_input is std_logic_vector(3 downto 0);

function my_function(lv: my_function_input) return std_logic_vector;

or verify the input range when you enter the function. Something like:

function my_function(lv : std_logic_vector) return std_logic_vector is
    assert lv'high = 3 and lv'low = 0
    report "Wrong input size, my_function requires 3 downto 0."
    severity failure;

Xilinx's compiler check assertions at synthesis, and stop it if the severify is failure (and probably error). I would expect other synthesizer to have the same behaviour.

  • \$\begingroup\$ You can specify a constraint in an interface parameter declaration via a subtype indication. You can't specify anything but the type mark for the return value. \$\endgroup\$ – user8352 Dec 20 '15 at 15:06
  • \$\begingroup\$ OK, I will keep that in mind. \$\endgroup\$ – quantum231 Dec 20 '15 at 15:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.