I'm new to VHDL and I'm trying to use code off a teacher's slide that doesn't seem to work as is, and I can't tell what's wrong:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Add4 is port (
  Data1, Data2 : in std_logic_vector(3 downto 0);
  Cin : in std_logic;
  Cout : out std_logic;
  Sum : out std_logic_vector(3 downto 0) );
end entity Add4; 

architecture RTL of Add4 is
  signal Out5bit : unsigned(4 downto 0);
  Out5bit <= ('0' & Data1) + ('0' & Data2) + Cin;
  Sum <= Out5bit(3 downto 0);
  Cout <= Out5bit(4);
end architecture RTL;

The error I'm getting is:

add4.vhd:15:28: no function declarations for operator "+"
add4.vhd:16:17: can't match slice with type array type "std_logic_vector"

The first error goes away if I comment out the assignment of Out5bit and the second goes away if I comment out the assignment of Sum. What am I doing wrong? Would this code have worked without being modified on some older version of VHDL or did my instructor just give me bogus code?

  • \$\begingroup\$ The example doesn't provide valid VHDL semantics. ghdl is correct here and defaults to revision -1993 with relaxed rules for semantics corrected in -2002. A teacher who provides an invalid example should be willing to field questions. \$\endgroup\$ – user8352 Jan 4 at 21:18

Your ports are of "std_logic_vector" type but the internal signal Out5bit is unsigned.

Numeric_std doesn't provide an "+" operator that adds the first type and returns the other, so no matching "+" operator is visible.

Three approaches to fix this: 1) Type conversions from std_logic_vector to unsigned and back again. Ugly, but clearly describes what you are doing - interpreting a std_logic_vector (essentially a bag of bits) as an unsigned number.

2) "use" certain non-standard libraries that provide such operators. Can cause ambiguities especially if you also have signed data...

3) Declare the ports unsigned. In addition to just working, it clarifies the design intent - this unit operates on unsigned data (not signed, or arrays of boolean flags, or character data etc)

You also have to coerce "Cin" to an unsigned number as Elliot points out...

Cin is a std_logic

(0 => cin) is a 1-bit array of std_logic (which should be compatible with unsigned). Note the syntax uses "named association" ... the "positional association" version of a 1 bit vector would be (Cin) which the compiler cannot detect as a vector unlike the 3 bit vector (Cin,Cin,Cin)

unsigned'(0 => cin) is explicitly unsigned.

| improve this answer | |
  • \$\begingroup\$ Thanks, if I change Data1, Data2, Cin and Sum to unsigned it works. But just for learning I decided to also try the type conversion way but I can't seem to make the compiler happy. unsigned(Cin) gives the error conversion allowed only between closely related types when Cin is std_logic. unsigned(std_logic_vector(Cin)) doesn't work either. Thoughts? \$\endgroup\$ – Joseph Garvin Jan 4 at 20:52
  • \$\begingroup\$ Thanks again the conversion works now too. I'm sorry to keep asking stuff but I'm at the stage where it's unclear what the terms to Google even are -- I can't find documentation for a => operator, only <=. Is it library defined? Also why is the apostrophe necessary? \$\endgroup\$ – Joseph Garvin Jan 4 at 21:01
  • \$\begingroup\$ => isn't an operator, it's the "named association" token. Used in array aggregates (here) but also record aggregates, port maps, and it can be used to make argument lists in procedure calls crystal clear... \$\endgroup\$ – Brian Drummond Jan 4 at 21:06
  • \$\begingroup\$ Providing a composite value for cin can be through concatenation to a null string whose type is determined by context. Shown here with a -2008 (--std=08) solution, note the declaration of Out5bit as std_logic_vector as well as creating the composite value with cin through concatenation). \$\endgroup\$ – user8352 Jan 4 at 21:12
  • \$\begingroup\$ Out5bit <= ('0' & Data1) + ('0' & Data2) + (0 => Cin); works where the aggregate associating element 0 (the default letfmost element) of a composite element takes it's type from context (the entire statement, here the type of the target Out5bit). No qualified expression is necessary here (--std=08 using package numeric_std_unsigned). \$\endgroup\$ – user8352 Jan 4 at 21:17

VHDL is a strongly typed language and you are mixing the datatypes. In line 15 you are adding std_logic to std_logic_vector. In line 16 you are trying to take a slice of an unsigned and assign it to a std_logic_vector. I'm not sure, but I suspect this is where your problems are coming from.

| improve this answer | |

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.