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

16

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

В принципі, я міняв би ваш 7seg конвертер, щоб взяти integer(або насправді a natural, враховуючи, що він має справу лише з додатними числами) - перетворення - це простий пошук масиву. Налаштуйте постійний масив із перетвореннями та просто індексуйте його цілим числом, яке ви використовуєте в об'єкті в якості вхідного даних.


Дякую за це Я дуже ціную ваші коментарі. Я був у своєму роді на посаді технічної допомоги, вивчаючи VHDL, щоб допомогти професору почати роботу, який трохи похитнувся в програмах концепцій. Я передам вам вашу інформацію - підручник, який ми використовували, не заглиблювався у питання VHDL "моралі".
Дж. Полфер

1
Це менше питання "моральності", ніж гарантія послідовності. Numeric_std lib - це справжній стандарт, створений 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"

Я думаю, вам може знадобитися додати "використовувати 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;

EDIT: Вам не потрібно буде оголошувати змінну цілим числом. Спробуйте замість цього змінити декларацію на std_logic_vector. Оператори + і - працюють на std_logic_vectors.


3
Будь ласка, не робіть цього! Використовуйте numeric_std (див. LoneTech і мої відповіді)
Мартін Томпсон,

Якщо у вас є кращий спосіб зробити це, це добре, але моя пропозиція працює, тому я вважаю, що ваш голосування було непотрібним. Я використовував std_logic_arith протягом багатьох років, і ніколи не мав проблем із цим. Я вважаю, що побоювання постачальників змінити їх реалізацію є безпідставними; який продавець, якщо їм здається, ризикне порушити дизайн своїх клієнтів?
ajs410

1
Ви вже маєте відповідь на те, який постачальник буде навмисно розміщувати конкретні дані про постачальника в просторі імен IEEE Він залишається грубим, особливо коли йдеться про підписані та непідписані цінності.
Yann Vernier

"Оператори + і - працюють на std_logic_vectors." AFAIK, вони не працюють, якщо я неправильно зрозумію ваше значення. зазвичай потрібно передати тип, який спочатку зберігає підписані / непідписані дані.
stanri

1

Можливо, вам буде цікаво використовувати типи unsignedта signedвід ieee.numeric_std. Вони сумісні з std_logic_vector, але мають числову інтерпретацію (двійкові або 2-доповнення). Існує також можливість застосовувати таке тлумачення 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 - це буквально купа 1s або 0s. У мене 10001. Яке це число? Ну, це залежить. Він підписаний чи непідписаний? Цей SLV не знає і не хвилює. Скільки бітів? Ну, як довго ваше SLV?

Ціле число підписується, і зазвичай 32 біти (якщо я правильно пам'ятаю).

Етап 1: Зробити моє ціле число скороченим і непідписаним. Ось ця частина:

to_unsigned(my_int, my_slv'length));

"У мене це ціле число, я хочу, щоб воно не було підписане, і я хочу, щоб воно вписувалося в довжину моєї SLV".

Етап 2: Потім візьміть ці біти і використовуйте їх для керування my_slv.

my_slv <= std_logic_vector(...)

"Візьміть ці шматочки та використовуйте їх для проїзду мого слізу"

(Примітка про термінологію. 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 "Візьміть ці біти та вставте їх у цей тип, не потребуючи жодних модифікацій". У них немає аргументу довжини, оскільки обидві сторони вже однакові. Отже, будуючи такі речі, мені не потрібно це шукати, я просто думаю про те, як я змінюю дані.


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, і він широко використовується.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.