Ошибка добавления std_logic_vectors
Я хочу иметь простой модуль, который добавляет два std_logic_vectors. Однако при использовании кода
ниже с оператором + он не синтезируется.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
entity add_module is
port(
pr_in1 : in std_logic_vector(31 downto 0);
pr_in2 : in std_logic_vector(31 downto 0);
pr_out : out std_logic_vector(31 downto 0)
);
end add_module;
architecture Behavior of add_module is
begin
pr_out <= pr_in1 + pr_in2;
end architecture Behavior;
Сообщение об ошибке, которое я получаю из XST
Строка 17. + не может иметь такие операнды в этом контексте.
Я пропустил библиотеку? Если возможно, я не хочу преобразовывать входы в натуральные числа.
Большое спасибо
Ответы
Ответ 1
Как вы хотите, чтобы компилятор знал, подписаны ли ваши std_logic_vectors или нет? Внедрение Adder в этих двух случаях не является одинаковым, поэтому вам нужно явно указать компилятору, что вы хотите, чтобы: -)
Примечание: подсветка синтаксиса VHDL в StackOverflow - дерьмовая. Скопируйте/вставьте этот код в свой предпочтительный редактор VHDL, чтобы читать его легче.
library IEEE;
use IEEE.std_logic_1164.all;
-- use IEEE.std_logic_arith.all; -- don't use this
use IEEE.numeric_std.all; -- use that, it a better coding guideline
-- Also, never ever use IEEE.std_unsigned.all or IEEE.std_signed.all, these
-- are the worst libraries ever. They automatically cast all your vectors
-- to signed or unsigned. Talk about maintainability and strong typed language...
entity add_module is
port(
pr_in1 : in std_logic_vector(31 downto 0);
pr_in2 : in std_logic_vector(31 downto 0);
pr_out : out std_logic_vector(31 downto 0)
);
end add_module;
architecture Behavior of add_module is
begin
-- Here, you first need to cast your input vectors to signed or unsigned
-- (according to your needs). Then, you will be allowed to add them.
-- The result will be a signed or unsigned vector, so you won't be able
-- to assign it directly to your output vector. You first need to cast
-- the result to std_logic_vector.
-- This is the safest and best way to do a computation in VHDL.
pr_out <= std_logic_vector(unsigned(pr_in1) + unsigned(pr_in2));
end architecture Behavior;
Ответ 2
Не используйте std_logic_arith
- я написал об этом (на некоторой длине:).
Использовать numeric_std - и использовать правильный тип на своих сущностях. Если вы делаете арифметику, используйте числовые типы (целые числа или (un) подписанные векторы, в зависимости от ситуации). Они прекрасно синтезируются.
std_logic_vector
хороши для
- когда вам не нужны численные значения (набор битов управления, некоторые бит случайных данных)
- когда вы не знаете о типе ввода (скажем, сумматор, который может работать как с подписанными, так и с неподписанными номерами на основе флага управления).
Ответ 3
Хороший совет от @Aurelien для использования numeric_std.
Помните, что добавление двух 32-битных значений может привести к 33-битовому значению и решить, как вы хотите обработать переполнение.
Ответ 4
Простой способ решить эту ошибку:
Добавить библиотеку unsign,
После этого ваш код начинает работать.
Использование
ieee.std_logic_unsigned.all;
pr_out <= pr_in1 + pr_in2;