Patrick
Patrick

Reputation: 39

Passing Variables to procedure in VHDL

I have the following simple procedure adding two numbers:

  procedure add_elements
  (
    x : in  std_logic_vector(31 downto 0);
    y : in  std_logic_vector(31 downto 0);   
    r : out std_logic_vector(31 downto 0)
  )
  is

  begin

   r := a + b;

  end;

I wanna make the use of this procedure in a process which looks as follows:

  test: process (....)
    variable inp1 : std_logic_vector(31 downto 0);
    variable inp2 : std_logic_vector(31 downto 0);
    variable res : std_logic_vector(31 downto 0);
  begin

    ...
    inp1  := some_value_a;
    inp2  := some_value_b;
    add_elements(inp1, inp2, res);
    ...
  end

However, when trying to compile, Modelsim tells me No feasable entries for subprogram "add_elements"

Anyone an idea what went wrong here, is something wrong with the signature of the add_elements procedure?

Many thanks!

Upvotes: 1

Views: 7979

Answers (3)

Jan Decaluwe
Jan Decaluwe

Reputation: 2445

Actually, the problem is with the signature of "+". In standard VHDL, there is no arithmetic defined with std_logic_vector.

As others have almost suggested, consider using unsigned or signed from IEEE.numeric_std instead.

For completeness, it seems that VHDL-2008 adds standard packages to do arithmetic on std_logic_vector. However, as with the non-standard packages, the numeric interpretation (signed or unsigned) depends on what package is used. I don't like that.

Upvotes: 1

Hendrik
Hendrik

Reputation: 1247

Why do you need a procedure to add two numbers? Why don't you just add them immediately?

--Note that I make the assumption that the std_logic_vectors represent numbers.--

I recommend to cast the std_logic_vectors to unsigned or signed first (use ieee.numeric_std.all) and use the "+" operator. You should never use ieee.std_logic_unsigned.all, it will only give you problems.

Upvotes: 3

Josh
Josh

Reputation: 3655

I think you are going to want a setup like this (I noticed a few typos).

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

I will throw in the obligatory note here that you might want to avoid using std_logic_unsigned and move to using numeric_std instead... Moving on... Nothing interesting here:

entity top is
    port (
    clk : in std_logic;
    x : in std_logic_vector(31 downto 0);
    y : in std_logic_vector(31 downto 0)
    );
end top;

In the architecture, we declare the procedure. I think you had a typo. (x and y vs a and b).

architecture top_arch of top is
 procedure add_elements
  (
    x : in  std_logic_vector(31 downto 0);
    y : in  std_logic_vector(31 downto 0);   
    r : out std_logic_vector(31 downto 0)
  )
  is
  begin
   r := x + y;
  end;

begin

Now the actual process:

  test: process (clk)
    variable inp1 : std_logic_vector(31 downto 0);
    variable inp2 : std_logic_vector(31 downto 0);
    variable res : std_logic_vector(31 downto 0);
  begin
    inp1  := x;
    inp2  := y;
    add_elements(inp1, inp2, res);
  end process;
end architecture top_arch;

And that's it. I think you were really close, just possibly missing a library and/or having some typos.

Edit: I should also mention that you could (and likely should) put the procedure in a separate package if you wanted for the purposes of re-use. Then you would need to include the package using the "use" statements.

Upvotes: 3

Related Questions