Упрощение кода vhdl: тип данных std_logic_vector

Упрощение кода vhdl: тип данных std_logic_vector
Упрощение кода vhdl: тип данных std_logic_vector
Anonim

Упрощение кода VHDL: тип данных Std_Logic_Vector

В этой статье будет рассмотрен тип данных «std_logic_vector», который является одним из наиболее распространенных типов данных в VHDL.

В предыдущей статье на языке описания аппаратного обеспечения VHDL мы обсудили базовую структуру кода VHDL через несколько вводных примеров. В этой статье будет рассмотрен один из наиболее распространенных типов данных в VHDL, т. Е. Тип данных «std_logic_vector».

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

Почему нам нужны векторные типы данных "// www.allaboutcircuits.com/technical-articles/hardware-description-langauge-getting-started-vhdl-digital-circuit-design/" target = "_ blank"> статья

Image
Image

Рисунок 1. Простая цифровая схема

Вот код VHDL для этой схемы:


1 library ieee; 2 use ieee.std_logic_1164.all; 3 entity circuit_1 is 4 Port (a: in STD_LOGIC; 5 b: in STD_LOGIC; 6 out1: out STD_LOGIC); 7 end circuit_1; ----------------------------------------------------- 8 architecture Behavioral of circuit_1 is 9 begin 10 out1 <= (a and b); 11 end Behavioral;

Теперь предположим, что нам нужно написать код VHDL для схемы на рисунке 2.

Image
Image

Фигура 2

Мы можем расширить предыдущий код, чтобы получить описание VHDL, показанное на рисунке 2, как


1 library ieee; 2 use ieee.std_logic_1164.all; 3 entity circuit_2 is 4 Port (a0: in STD_LOGIC; 5 a1: in STD_LOGIC; 6 a2: in STD_LOGIC; 7 b0: in STD_LOGIC; 8 b1: in STD_LOGIC; 9 b2: in STD_LOGIC; 10 out0: out STD_LOGIC; 11 out1: out STD_LOGIC; 12 out2: out STD_LOGIC); 13 end circuit_2; ----------------------------------------------------- 14 architecture Behavioral of circuit_2 is 15 begin 16 out0 <= (a0 and b0); 17 out1 <= (a1 and b1); 18 out2 <= (a2 and b2); 19 end Behavioral;

Вышеприведенный код верен; однако мы увидим, что для этой схемы возможно иметь более компактное и легко читаемое описание VHDL. Недостатком вышеуказанного кода является то, что он представляет каждый из портов ввода / вывода в виде отдельных сигналов и не устанавливает никакой связи между ними.

Рассмотрим альтернативный способ отображения схемы на рисунке 2.

Image
Image

Рисунок 3

На рисунке 3 показано, что мы можем рассматривать a0, a1 и a2 как трехбитовый входной порт, называемый, например, a_vec. Аналогично, входные порты b0, b1 и b2 могут быть сгруппированы как еще один трехбитовый входной порт, называемый b_vec. То, что делает схема, - это И элемент a_vec с соответствующим элементом b_vec. Это может показаться простой идеей, но через минуту мы увидим, как этот способ мышления делает код более удобочитаемым.

Тип данных Std_Logic_Vector

Чтобы представить группу сигналов, VHDL использует векторные типы данных. Чтобы получить доступ к элементу вектора, нам нужно определить индекс. Например, предположим, что, как показано на рисунке 4, мы используем вектор длиной три, a_vec, чтобы представить три значения: val_0, val_1 и val_2. Чтобы получить доступ к значению элемента из этого вектора, мы можем использовать номера индексов. Например, a_vec (2) даст значение самого правого элемента вектора на рисунке 4, которое равно val_2.

Image
Image

Рисунок 4. Трехэлементный вектор a_vec

Ключевое слово VHDL «std_logic_vector» определяет вектор элементов типа std_logic. Например, std_logic_vector (от 0 до 2) представляет собой трехэлементный вектор типа std_logic, причем диапазон индексов простирается от 0 до 2.

Давайте используем тип данных «std_logic_vector» для описания схемы на рисунке 3. Мы будем использовать три вектора a_vec, b_vec и out_vec для представления голубых, красных и черных портов на рисунке 3 соответственно. С новым названием для портов мы получим следующий рисунок.

Image
Image

Рисунок 5

Код VHDL для рисунка 5 приведен ниже.


1 library ieee; 2 use ieee.std_logic_1164.all; 3 entity circuit_2 is 4 Port (a_vec: in STD_LOGIC_VECTOR(0 to 2); 5 b_vec: in STD_LOGIC_VECTOR(0 to 2); 6 out_vec: out STD_LOGIC_VECTOR(0 to 2)); 7 end circuit_2; ----------------------------------------------------- 8 architecture Behavioral of circuit_2 is 9 begin 10 out_vec <= (a_vec and b_vec); 11 end Behavioral;

Строки 4-6 этого кода используют тип данных «std_logic_vector» для портов ввода / вывода схемы. Обратите внимание, что операция И в строке 10 будет применена к соответствующим элементам двух векторов a_vec и b_vec, т. Е. A_vec (0) имеет AND с b_vec (0), и результат присваивается out_vec (0) и т. Д., Сравнивая это с предыдущим кодом, мы наблюдаем, что использование типа данных «std_logic_vector» позволяет нам иметь гораздо более компактный и читаемый код. Это преимущество становится особенно очевидным при работе с большими цепями; просто представьте, насколько громоздким будет код, если бы мы использовали отдельные инструкции присваивания сигналов для ANDing элементов из двух 32-битных векторов.

Моделирование ISE приведенного выше кода показано на рисунке 6.

Image
Image

Рисунок 6. Моделирование ISE схемы, показанной на рисунке 5

Интерпретация данных Std_Logic_Vector

Существует один важный момент, который требует дополнительного внимания. Как показано в приведенном выше примере, тип данных «std_logic_vector» - это способ представления группы сигналов или шины данных. Это просто строка из них и нули, и нет никакой другой интерпретации для этой строки из них и нулей. Другими словами, если мы назначим «011» a_vec, это не означает, что a_vec равно 3 (десятичный эквивалент «011»).

Мы не можем считать вес для разных позиций битов сигнала «std_logic_vector». Однако мы можем использовать функции преобразования типов и тип литья, чтобы интерпретировать строку из них и нули в данном сигнале «std_logic_vector» как число. Преобразование типов будет обсуждаться в следующей статье.

Восходящий или нисходящий индексный диапазон?

До сих пор мы использовали тип данных std_logic_vector при определении портов ввода / вывода. Аналогично, мы можем определить сигнал типа «std_logic_vector». В качестве примера рассмотрим следующие строки кода:


signal a: std_logic_vector(0 to 3); … a <= “0010”

Здесь первая строка определяет как сигнал типа «std_logic_vector». Индекс находится в диапазоне от 0 до 3. Затем «0010» присваивается значение a. С этим назначением, как показано на рисунке 7, мы будем иметь (0) = 0, a (1) = 0, a (2) = 1 и a (3) = 0.

Image
Image

Рисунок 7

Стиль индексации этого вектора, который использует ключевое слово «to», называется восходящим. Мы также можем использовать ключевое слово «downto» (вместо «to»), когда нам нужен нисходящий индексный диапазон:


signal a: std_logic_vector(3 downto 0); … a <= “0010”

В этом случае, как показано на рисунке 8, мы будем иметь (3) = 0, a (2) = 0, a (1) = 1 и a (0) = 0.

Image
Image

Рисунок 8

Выбор между восходящим и нисходящим порядком часто связан с предпочтениями дизайнера, хотя он может быть рассмотрен в руководстве по кодированию, принятом конкретной организацией. Самое главное - выбрать один стиль, а затем последовательно следовать ему; смешивание двух разных стилей в одном проекте может легко привести к неприятностям.

Например, рассмотрим таблицу истинности для 4-к-2 приоритетного кодировщика, как показано ниже. С приоритетным кодировщиком мы обычно рассматриваем самый левый бит входного вектора для наивысшего приоритета. Например, в следующей таблице истинности, когда самый левый входной бит x (3) высок, мы не заботимся о состоянии остальных трех входных битов и утверждаем выходы y и v, т. Е. Y = " 11 " и v = '1'.

Image
Image

Мы видим, что эта таблица истинности предполагает, что входной вектор x имеет нисходящий индексный диапазон, потому что элемент с самым высоким индексом помещается в крайнее левое положение. Предположим, что, несмотря на выбор нисходящего индекса в таблице истинности, мы используем возрастающий индексный диапазон при объявлении входного вектора x и присваиваем «0001» x. Другими словами, мы имеем:


signal x: std_logic_vector(0 to 3); … x <= “0001”

Так как самый правый бит x высок, учитывая общее определение для приоритетного кодера, мы ожидаем, что выходы y и v будут соответственно «00» и «1». Однако, если вышеприведенный код x (3) высок и, основываясь на приведенной выше таблице истинности, вывод будет y = "11" и v = '1'. Чтобы избежать таких проблем, мы должны последовательно использовать нисходящий индексный диапазон во всем коде.

Резюме

  • Тип данных «std_logic_vector» позволяет нам иметь более компактный и читаемый код. Этот тип данных предоставляет нам способ представления группы сигналов или шины данных.
  • Мы не можем считать вес для разных позиций битов сигнала «std_logic_vector». Однако мы можем использовать функции преобразования типов и тип литья, чтобы интерпретировать строку из них и нули в данном сигнале «std_logic_vector» как число.
  • Диапазон индексов, используемый в объявлении «std_logic_vector», может быть как по возрастанию, так и по убыванию. Первый использует ключевое слово «to», а последнее использует ключевое слово «downto».
  • Выбор между восходящим и нисходящим порядком часто является вопросом стиля, но важно последовательно применять этот выбор во всем конкретном проекте.

Чтобы просмотреть полный список моих статей, перейдите на эту страницу.

Рекомендуемое изображение любезно предоставлено Altera.