0
\$\begingroup\$

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?

asked Jan 4, 2020 at 20:28
\$\endgroup\$
1
  • \$\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\$ Commented Jan 4, 2020 at 21:18

2 Answers 2

1
\$\begingroup\$

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.

answered Jan 4, 2020 at 20:42
\$\endgroup\$
5
  • \$\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\$ Commented 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\$ Commented 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\$ Commented 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 of Out5bit as std_logic_vector as well as creating the composite value with cin through concatenation). \$\endgroup\$ Commented 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 target Out5bit). No qualified expression is necessary here (--std=08 using package numeric_std_unsigned). \$\endgroup\$ Commented Jan 4, 2020 at 21:17
0
\$\begingroup\$

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.

answered Jan 4, 2020 at 20:41
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.