Search code examples
vhdlvivado

actual s of formal sum must be a variable and type error


I'm working on xilinx student labs and trying to learn VHDL but and having some trouble fixing my errors. I'm mostly focused on getting the addition part to work for now.

The errors I'm getting are as below:

[Synth 8-1560] actual s of formal sum must be a variable ["C:/Nexys 4 >Projects/lab4_1_1/lab4_1_1.srcs/sources_1/new/add_two_values_procedure.vhd":54]

[Synth 8-2778] type error near a ; expected type std_ulogic ["C:/Nexys 4 >Projects/lab4_1_1/lab4_1_1.srcs/sources_1/new/add_two_values_procedure.vhd":56]

[Synth 8-2778] type error near b ; expected type std_ulogic ["C:/Nexys 4 >Projects/lab4_1_1/lab4_1_1.srcs/sources_1/new/add_two_values_procedure.vhd":56]

For the first error I read that if I don't use the procedure in a process, then I must pass the signal to the procedure in order to assign the variable total to it. Could someone please shed some light as to how to fix this error please?

For the second and third errors I was looking in the library for std_logic_1164 and saw this line

FUNCTION "and" ( l, r : std_logic_vector ) RETURN std_logic_vector;

To my knowledge (however small it is on this subject) line 56 uses std_logic_vector on either side of the and operator/function (?) and should return a std_logic_vector. So why is it asking me to use std_ulogic. EDIT: That line above I saw from this website http://www.csee.umbc.edu/portal/help/VHDL/packages/std_logic_1164.vhd but from my book, Designer's guide to VHDL, doesn't have that line in the package.

Below is my code

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_SIGNED.ALL;

entity add_two_values_procedure is
    Port ( a : in STD_LOGIC_VECTOR (3 downto 0);
           b : in STD_LOGIC_VECTOR (3 downto 0);
           operand : in STD_LOGIC;
           sum : out STD_LOGIC_VECTOR (3 downto 0);
           cout : out STD_LOGIC);
end add_two_values_procedure;

architecture Behavioral of add_two_values_procedure is
    signal s : STD_LOGIC_VECTOR (3 downto 0);
    procedure add_values (
        a : in STD_LOGIC_VECTOR (3 downto 0);
        b : in STD_LOGIC_VECTOR (3 downto 0);
        operand : in STD_LOGIC;
        sum : out STD_LOGIC_VECTOR (3 downto 0))
    is
        variable total : STD_LOGIC_VECTOR (3 downto 0);
    begin
        case operand is
            when '1' =>
                total := a + b;
            when '0' =>
                total := a - b;
        end case;
    sum := total;
    end procedure add_values;
begin
    add_values(a, b, operand, s);               54
    sum <= s;
    cout <= a and b;                            56
end Behavioral;

Solution

  • With regards to line 54:

    Quoting VHDL 2008:

    If the mode is inout or out, and no object class is explicitly specified, variable is assumed.

    So try:

    procedure add_values (
        a : in STD_LOGIC_VECTOR (3 downto 0);
        b : in STD_LOGIC_VECTOR (3 downto 0);
        operand : in STD_LOGIC;
        signal sum : out STD_LOGIC_VECTOR (3 downto 0))
    is
        variable total : STD_LOGIC_VECTOR (3 downto 0);
    begin
        case operand is
            ...
    

    With regards to line 56:

    Look at the type of cout. You are assigning a std_logic_vector(3 downto 0) to a std_logic.