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);
begin
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– user83522020年01月04日 21:18:25 +00:00Commented Jan 4, 2020 at 21:18
2 Answers 2
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.
-
\$\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 errorconversion allowed only between closely related types
when Cin is std_logic.unsigned(std_logic_vector(Cin))
doesn't work either. Thoughts? \$\endgroup\$Joseph Garvin– Joseph Garvin2020年01月04日 20:52:37 +00:00Commented Jan 4, 2020 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– Joseph Garvin2020年01月04日 21:01:32 +00:00Commented Jan 4, 2020 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\$user16324– user163242020年01月04日 21:06:00 +00:00Commented Jan 4, 2020 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 ofOut5bit
as std_logic_vector as well as creating the composite value withcin
through concatenation). \$\endgroup\$user8352– user83522020年01月04日 21:12:54 +00:00Commented Jan 4, 2020 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 targetOut5bit
). No qualified expression is necessary here (--std=08 using package numeric_std_unsigned). \$\endgroup\$user8352– user83522020年01月04日 21:17:38 +00:00Commented Jan 4, 2020 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.