在VHDL中将二进制5位数乘以2

时间:2014-02-15 01:32:16

标签: vhdl

我遇到的问题是在VHDL中将二进制5位数乘以2。错误是:

** 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

这是我的计划:

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;

拜托,我真的需要了解这个问题背后的概念。这是因为我总是遇到这样的错误。

2 个答案:

答案 0 :(得分:4)

在ieee.std_logic_1164中没有定义乘法运算符,它定义了std_(u)逻辑和std_(u)logic_vector。这是第一条消息试图告诉你的内容。

下一个语句告诉您它不知道如何处理变量赋值,因为无法解析右侧运算符。第三行只是告诉你HDL编译器在那之后退出(完成)。

现在,您已经使用了ieee.numeric_std。因此,您应该使用未签名和签名的numeric_std类型。

variable a : unsigned(4 downto 0);

将变量定义为无符号,然后乘以整数

a := a * 2; --Read on, this does not work!

但是,运算符“*”的定义如下:

-- 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.

结果将是结果(5 + 5-1 downto 0)==&gt; vector'length == 10,而不是'length(== 5)。因此,我们需要调整结果的大小,即关闭高位:

a := resize(a * 2, a'length);

您还可以乘以另一个无符号:

variable a : unsigned(4 downto 0);
variable b : unsigned(2 downto 0);

这里的结果将是结果(5 + 3 - 1 downto 0)==&gt;结果'长度== 8.再次,重新调整到救援:

a := resize(a * b, a'length);

您似乎遇到的基本问题是VHDL是一种强类型语言。这意味着,您需要跟踪表达式中的类型以及是否为这些类型定义了所需的函数。您只是假设为std_logic_vector定义了乘法运算符“*” - 事实并非如此。

只是一句警告:确实有一个包为std_logic_vector定义了一个运算符“*”。但是,它已弃用,尽管其名称不属于ieee(see here)。

你应该避免使用它,因为它已经过时而且没有标准化,或者在供应商之间也是如此。

答案 1 :(得分:0)

FROB涵盖了您遇到的类型问题。但是,乘以常数2的另一个答案是:只需将向量移到左边一位。同样,除以2也可以向右移动。

BTW:该函数似乎将std_logic_vector转换为整数。所以,你可以这样做:

my_slv <= std_logic_vector(to_unsigned(my_integer, my_slv'length));

在你的情况下,改变:

b<=binary1(int);

为:

b <= std_logic_vector(to_unsigned(int, b'length));

无需编写自己的功能。但是,如果这是一个学习练习,你可以尝试转变来学习另一种方法。