2014-02-15 2 views
1

У меня проблема с умножением двоичного 5-битного числа на 2 в VHDL. Ошибка:Умножение двоичного 5-битного числа на 2 в VHDL

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

Пожалуйста, мне действительно нужно, чтобы понять концепцию за этой проблемы. Это связано с тем, что я всегда сталкиваюсь с такой ошибкой.

ответ

3

В 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) ==> vector'length == 10, а не длина (== 5). Поэтому нам нужно изменить размер результата, т.е. вырезать высокого порядка биты от:

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

Вы могли бы также умножить на другой без знака:

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

Здесь результат будет результат (5 + 3 - 1 Downto 0) ==> == result'length 8. Итак, еще раз, изменить размер на помощь:

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

Основная проблема, которую вы, кажется, что VHDL является строго типизированным языком. Это означает, что вам нужно отслеживать, какие типы есть в выражении, и определяет ли ваша желаемая функция для этих типов. Вы просто предположили, что оператор умножения «*» был определен для std_logic_vector - это не тот случай.

Только слово предупреждения: действительно существует пакет, который определяет оператор «*» для std_logic_vector. Однако он устарел и, несмотря на то, что его имя не является частью ieee (see here).

Вам следует избегать этого, потому что он устарел, а не стандартизирован или одинаково у всех поставщиков.

+0

Большое спасибо. Это действительно помогло. – user3300910

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)); 

Нет необходимости писать свою собственную функцию. Но если это учебное упражнение, вы можете попробовать переключение, чтобы изучить другой способ сделать это.

+0

Большое спасибо. Это действительно помогло. – user3300910

+0

Как учебное упражнение, может быть ... но зачем учиться писать путаный код? Если вы хотите умножить на 2, напишите 'a * 2'. Если вы действительно хотите * сдвинуть, то, во всяком случае, используйте сдвиг. Такая «оптимизация» принадлежит 80-м ИМХО. –

Смежные вопросы