VHDL: преобразование типа INTEGER в STD_LOGIC_VECTOR

28

Я построил счетчик mod-16, и результатом вывода является INTEGER (все примеры, которые я видел, использовали INTEGER).

Я построил декодер с шестнадцатеричным-7-сегментным дисплеем, и его вход представляет собой STD_LOGIC_VECTOR (записал его так, потому что было легко отобразить таблицу истинности).

Я хотел бы соединить выход счетчика со входом декодера, но я получаю ошибки «несоответствие типов» при попытке компиляции в QuartusII.

Есть ли способ преобразования из типа INTEGER в тип STD_LOGIC_VECTOR в листинге VHDL?

Дж. Полфер
источник

Ответы:

20

Как говорили другие, ieee.numeric_stdникогда не используйте ieee.std_logic_unsigned, что на самом деле не является пакетом IEEE.

Однако, если вы используете инструменты с поддержкой VHDL 2008, вы можете использовать новый пакет ieee.numeric_std_unsigned, который, по сути, std_logic_vectorведет себя как неподписанный.

Кроме того, так как я не видел этого явно, вот пример кода для преобразования целого числа (без знака) в std_logic_vector:

use ieee.numeric_std.all;
...
my_slv <= std_logic_vector(to_unsigned(my_int, my_slv'length));
WJL
источник
16

Как говорит LoneTech, use ieee.numeric_stdэто твой друг. Вы можете преобразовать a std_logic_vectorв a integer, но вам придется привести его как signedили unsignedсначала (так как компилятор понятия не имеет, что вы имеете в виду). VHDL - строго типизированный язык. Я написал больше на эту тему в своем блоге

По сути, я бы изменил ваш 7seg конвертер, чтобы он принимал integer(или фактически natural, учитывая, что он будет иметь дело только с положительными числами) - тогда преобразование - это простой поиск в массиве. Установите постоянный массив с преобразованиями в и просто внесите в него индекс с целым числом, которое вы используете для объекта в качестве входных данных.

Мартин Томпсон
источник
Спасибо за это. Я очень ценю ваши комментарии. Я был в некотором роде ТА, изучая VHDL, чтобы помочь начинающему специалисту, который немного шокировал концепциями программирования. Я передам вашу информацию ему - учебник, который мы использовали, не углублялся в вопросы морали VHDL.
Дж. Полфер
1
Это не столько вопрос «морали», сколько гарантия последовательности. Библиотека numeric_std - это настоящий стандарт, установленный IEEE, в то время как библиотека std_logic_unsigned была создана поставщиком и принята в отрасли без какого-либо реального формального определения. Нет гарантии совместимости между поставщиками с нестандартными библиотеками, хотя обычно она работает нормально. Впрочем, сейчас хорошо перейти на стандарт.
MattG
1

Допустим, у вашего 4-битного счетчика был выход INTEGER SOME_INTEGER, и вы хотели преобразовать его в 4-битный STD_LOGIC_VECTOR

SOME_VECTOR <= conv_std_logic_vector(SOME_INTEGER, 4);

Вы также можете использовать это для инициализации векторов со значимыми числами

SOME_VECTOR <= conv_std_logic_vector(9, 4); -- instead of "1001"

Я думаю, что вам может понадобиться добавить "use IEEE.STD_LOGIC_ARITH.ALL;" и / или STD_LOGIC_UNSIGNED.

Дополнительной операцией является conv_integer (vector). Мне нравится использовать это, когда я делаю сравнения. Так что я мог бы объявить

constant SOME_CONSTANT : integer := 999;

А потом, позже, я могу использовать это в операторе if

if (conv_integer(SOME_VECTOR)=SOME_CONSTANT)
  then OTHER_VECTOR <= (others => '0');
end if;

РЕДАКТИРОВАТЬ: вам не нужно объявлять переменную как целое число. Попробуйте вместо этого изменить объявление на std_logic_vector. Операторы + и - работают с std_logic_vectors.

ajs410
источник
3
Пожалуйста, не делай этого! Используйте numeric_std (см. LoneTech и мои ответы)
Мартин Томпсон
Если у вас есть лучший способ сделать это, это нормально, но мое предложение работает, поэтому я думаю, что ваш отрицательный голос был ненужным. Я использовал std_logic_arith в течение многих лет, и у меня никогда не было проблем с ним. Я думаю, что опасения по поводу того, что поставщики изменят свои реализации, необоснованны; какой поставщик в здравом уме рискнет сломать дизайн своих клиентов?
ajs410
1
У вас уже есть ответ на вопрос, какой поставщик умышленно поместит информацию о конкретном поставщике в пространство имен IEEE. Он остается грубым, особенно когда речь идет о знаковых и беззнаковых значениях.
Янн Вернье
«Операторы + и - работают на std_logic_vectors». AFAIK, они не работают, если я не понимаю ваше значение. обычно необходимо привести к типу, который сначала содержит данные со знаком или без знака.
станри
1

Вы можете быть заинтересованы в использовании типов unsignedи signedот ieee.numeric_std. Они совместимы с std_logic_vector, но имеют числовую интерпретацию (двоичную или двухкомпонентную). Есть также возможность поставить такую ​​интерпретацию std_logic_vector, но это не рекомендуется .

Ян Вернье
источник
0

Как говорится в основном ответе, рекомендуемый метод следующий:

use ieee.numeric_std.all;
...
my_slv <= std_logic_vector(to_unsigned(my_int, my_slv'length));

Тем не менее, я хотел бы уточнить, почему это рекомендуется и почему VHDL имеет такой, казалось бы, запутанный способ преобразования целых чисел в std_logic_vectors.

Все сводится к тому, как эти типы рассматриваются инструментами.

Standard_logic_vector - буквально группа 1 или 0. У меня 10001. Какой это номер? Смотря как. Это подписано или не подписано? Это SLV не знает или не заботится. Сколько бит? Ну, как долго твой SLV?

Целое число подписано и обычно 32 бита (если я правильно помню).

Этап 1: сделать мое целое число короче и без знака. Вот эта часть:

to_unsigned(my_int, my_slv'length));

«У меня есть это целое число, я хочу, чтобы оно было без знака, и я хочу, чтобы оно вписывалось в длину моего SLV».

Этап 2: Затем возьмите эти биты и используйте их для управления my_slv.

my_slv <= std_logic_vector(...)

«Возьми эти биты и используй их, чтобы управлять моим slv»

(Примечание по терминологии. A <= BВ VHDL читается вслух как «A управляется B»)

В сочетании это дает вам:

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

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

Бонусный совет: функции с префиксом to_ - это те, которые сокращают / меняют операнды. Они делают их без знака или определенной длины или обоих. Вот почему to_unsigned требует от вас указать длину. Функции без to_ (прямой std_logic_vector (...) в этом примере) используются, когда типы уже напрямую совместимы. Msgstr "Возьми эти биты и наполни их этим типом, никаких изменений не требуется" У них нет аргумента длины, потому что обе стороны уже одинаковы. Поэтому при создании таких вещей мне не нужно искать это, я просто думаю о том, как я изменяю данные.

stanri
источник
0

Чтобы преобразовать целое число в std_logic_vector, у вас есть несколько вариантов. Используя numeric_std:

vect <= std_logic_vector( to_unsigned( your_int, vect'length));

или

vect <= std_logic_vector( to_signed( your_int, vect'length));

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

vect <= conv_std_logic_vector( your_int, vect'length);

std_logic_arith не является стандартом ieee, но большинство инструментов компилирует его в библиотеку IEEE, и он широко используется.

Craig
источник