2010-10-28 3 views
16

Я хочу иметь простой модуль, который добавляет два 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. + не может иметь такие операнды в этом контексте.

Я пропустил библиотеку? Если возможно, я не хочу преобразовывать входные данные в натуральные числа.

Большое спасибо

ответ

19

Как вы хотите, чтобы компилятор знать, если ваш 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's 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; 
0

Полезные советы от @Aurelien использовать numeric_std.

Имейте в виду, что добавление двух 32-битных значений может привести к 33-битовому значению и решить, как вы хотите обработать переполнение.

4

Не используйтеstd_logic_arith - У меня есть written about this (на некоторой длине :).

Do use numeric_std - и используйте правильный тип на портах вашего объекта. Если вы делаете арифметику, используйте числовые типы (целые числа или (un) подписанные векторы, в зависимости от ситуации). Они прекрасно синтезируются.

std_logic_vector s хороши для

  • когда вы не заботитесь о числовых значениях (набор управляющих битов, некоторые случайные биты данных)
  • , когда вы не знаете о типе из ввод (например, сумматор, который может работать как с подписанными, так и с неподписанными номерами на основе флага управления).
+0

Я рекомендую проверить ссылку Мартина. – George

-1

Самый простой способ решить эту ошибку является:
Добавить библиотеку из unsign,
После этого ваш код начинает работать.

Использование

ieee.std_logic_unsigned.all; 
pr_out <= pr_in1 + pr_in2; 
+0

как @ Мартин Томпсон сказал, что использование этой библиотеки не рекомендуется. – grorel

+0

вы можете объяснить? –

+0

Все в ссылке в ответ Мартина Томпсона. 'std_logic_arith''std_logic_unsigned' и' std_logic_signed' являются нестандартными библиотеками, разработанными с помощью синопсиса. 'numeric_std' - стандартная библиотека. – grorel

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