Reputation: 19
I am facing a problem regarding A multiplication of a binary 5 bit number by 2 in VHDL. The error is:
** Error: C:/altera/13.1/binary.vhd(29): No feasible entries for infix operator "*".
** Error: C:/altera/13.1/binary.vhd(29): Bad right hand side (infix expression) in variable assignment.
** Error: C:/altera/13.1/binary.vhd(34): VHDL Compiler exiting
Here is my program:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.numeric_std.all;
entity binary is
port( int: in integer;
b: out std_logic_vector(4 downto 0));
end binary;
Architecture Behavior1 of binary is
function binary1 (int1:integer) return std_logic_vector is
variable int2: integer;
variable a:std_logic_vector(4 downto 0);
variable i: integer;
begin
int2:=int1;
i:=0;
while (i<a'length) loop
int2:=int2/2;
if (int2 mod 2 = 0) then
a(i):='0';
else
a(i):='1';
end if;
i:=i+1;
end loop;
a:=a * "00010";
return a;
end binary1;
begin
b<=binary1(int);
end Behavior1;
Please, I really need to understand the concept behind this problem. This is because I always encounter to such error.
Upvotes: 1
Views: 11051
Reputation: 16
FRob covered the type issue you are having. However, another answer to multiplying by constant 2 is: just shift the vector to the left one bit. Also, the divide by 2, likewise, can be shifted to the right.
BTW: The function seems to convert an std_logic_vector to an integer. So, you could just do this:
my_slv <= std_logic_vector(to_unsigned(my_integer, my_slv'length));
in your case, change:
b<=binary1(int);
to:
b <= std_logic_vector(to_unsigned(int, b'length));
No need to write your own function. But, if this is a learning exercise, you can try the shifting to learn another way of doing it.
Upvotes: 0
Reputation: 4041
There is no multiplication operator defined in ieee.std_logic_1164, which defines std_(u)logic and std_(u)logic_vector. This is what the first message is trying to tell you.
The next statement tells you that it doesn't know what to do with the variable assignment, because the right hand side operator could not be resolved. Third line just tells you that the HDL compiler exited (finished) after that.
Now, you already use ieee.numeric_std. Therefore, you should make use of the numeric_std types unsigned and signed.
variable a : unsigned(4 downto 0);
Define your variable as unsigned, then multiply by an integer
a := a * 2; --Read on, this does not work!
However, operator "*" is defined like this:
-- Id: A.17
function "*" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
-- Result subtype: UNSIGNED((L'LENGTH+L'LENGTH-1) downto 0).
-- Result: Multiplies an UNSIGNED vector, L, with a non-negative
-- INTEGER, R. R is converted to an UNSIGNED vector of
-- SIZE L'LENGTH before multiplication.
The result will be a result(5+5-1 downto 0) ==> vector'length == 10, not a'length (==5). Therefore, we need to resize the result, i.e. cut the high-order bits off:
a := resize(a * 2, a'length);
You could also multiply by another unsigned:
variable a : unsigned(4 downto 0);
variable b : unsigned(2 downto 0);
Here the result will be result(5 + 3 - 1 downto 0) ==> result'length == 8. So again, resize to the rescue:
a := resize(a * b, a'length);
The fundamental problem you seem to have is that VHDL is a strongly typed language. This means, you need to keep track of what types there are in an expression and whether or not your desired function is defined for those types. You just assumed that the multiplication operator "*" was defined for std_logic_vector -- this is not the case.
Just a word of warning: There is indeed a package that defines an operator "*" for std_logic_vector. However, it is deprecated and despite its name not part of ieee (see here).
You should avoid it, because it is old and not standardized or the same across vendors.
Upvotes: 4