Error adding std_logic_vectors
Asked Answered
S

5

22

I wanna have a simple module that adds two std_logic_vectors. However, when using the code below with the + operator it does not synthesize.

library IEEE; 
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;

entity add_module is
        port(
  pr_in1   : in std_logic_vector(31 downto 0);
  pr_in2   : in std_logic_vector(31 downto 0);
  pr_out   : out std_logic_vector(31 downto 0)  
        );
end add_module;

architecture Behavior of add_module is

begin

    pr_out <= pr_in1 + pr_in2;

end architecture Behavior;

The error message I get from XST

Line 17. + can not have such operands in this context.

Do I miss a library? If possible, I do not wanna convert the inputs into natural numbers.

Many thanks

Sharpie answered 28/10, 2010 at 12:20 Comment(0)
T
28

How do you want the compiler to know if your std_logic_vectors are signed or unsigned ? Adder implementation is not the same in these two cases, so you need to explicitly tell the compiler what you want it to do ;-)

Note: VHDL syntax highlighting in StackOverflow is crappy. Copy/paste this code in your preferred VHDL editor to read it more easily.

library IEEE; 
use IEEE.std_logic_1164.all;
-- use IEEE.std_logic_arith.all; -- don't use this
use IEEE.numeric_std.all; -- use that, it's a better coding guideline

-- Also, never ever use IEEE.std_unsigned.all or IEEE.std_signed.all, these
-- are the worst libraries ever. They automatically cast all your vectors
-- to signed or unsigned. Talk about maintainability and strong typed language...

entity add_module is
  port(
    pr_in1   : in std_logic_vector(31 downto 0);
    pr_in2   : in std_logic_vector(31 downto 0);
    pr_out   : out std_logic_vector(31 downto 0)  
  );
end add_module;

architecture Behavior of add_module is
begin

  -- Here, you first need to cast your input vectors to signed or unsigned 
  -- (according to your needs). Then, you will be allowed to add them.
  -- The result will be a signed or unsigned vector, so you won't be able
  -- to assign it directly to your output vector. You first need to cast
  -- the result to std_logic_vector.

  -- This is the safest and best way to do a computation in VHDL.

  pr_out <= std_logic_vector(unsigned(pr_in1) + unsigned(pr_in2));

end architecture Behavior;
Tubule answered 28/10, 2010 at 12:30 Comment(0)
H
5

Don't use std_logic_arith - I've written about this (at some length :).

Do use numeric_std - and do use the right type on your entity ports. If you are doing arithmetic, use numerical types (either integers, or (un)signed vectors, as appropriate). They'll synthesise perfectly well.

std_logic_vectors are good for

  • when you don't care about numerical values (a set of control bits, some random data bits)
  • when you don't know about the type of the input (say an adder which can operate on both signed and unsigned numbers based on a control flag).
Hartshorn answered 2/11, 2010 at 14:8 Comment(0)
R
0

Good advice from @Aurelien to use numeric_std.

Bear in mind that adding two 32 bit values can result in a 33 bit value and decide how you want to handle the overflow.

Regelate answered 28/10, 2010 at 13:2 Comment(0)
B
0

You cannot do an arithmetic operation with just std_logic_vector. Either you have to convert the std_logic_vector to signed/unsigned (depending on your code requirements) (see 1 below) or else convert them to integers (see 2 below)

  1.      pr_out = std_logic_vector(unsigned(pr_in1) + "01")
    
  2.      pr_out = std_logic_vector(integer(pr_in1) + 99)
    

These are just examples. You can change them based on your requirements.

Bucolic answered 26/8, 2022 at 2:1 Comment(1)
The OP's account has been inactive for 11 years and isn't likely to now accept an answer, speaking of which your see 2 below contains two errors. pr_in1 is declared with a type mark of std_logic_vector which isn't closely related to type integer. They can't be type converted one to the other abs require conversion routines instead. Alternatively the OP could have used either Synopsys' package std_logic_unsigned or IEEE package numeric_std unsigned (-2008) both of which have "+" operators treating std_logic_vector values as unsigned.Redistrict
V
-1

The easy way to solve this error is:
Add library of unsign,
After that your code starts to work.

Use

ieee.std_logic_unsigned.all;
pr_out <= pr_in1 + pr_in2;
Venatic answered 21/9, 2016 at 7:13 Comment(4)
as @Martin Thompson said, the use of this library is not recommended.Arta
can you explain?Venatic
Everything is in the link in Martin Thompson answer. std_logic_arith``std_logic_unsigned and std_logic_signed are non-standard libraries developed by synopsis. numeric_std is the standard library.Arta
Also, my 2 cents on the topics : using numeric_std prevents several easy errors during code writing due to the use of signed and unsigned type instead of generic std_logic_vector when dealing with numbers.Arta

© 2022 - 2024 — McMap. All rights reserved.