Кое-что о VHDL- симуляторах.
Сейчас любая солидная САПР электроники включает в себя VHDL-симулятор. Но группа видных международных авторитетов в программировании на VHDL сходятся на том, что для обучения лучше всего подходит VHDL-симулятор Active HDL фирмы Aldec. Кроме того, что по важности не самое последнее, этот симулятор допускает коментарии, сообщения и идентификаторы на русском языке. Его бесплатную версию для обучения можно получить на сайте www.aldec.com , а литературу о нем на русском языке – на сайте www.aldec.com.ua .
Для моделирования в симуляторе Active HDL сперва нужно создать проект – каталог с файлами VHDL, имеющий название проекта. Это облегчает встроенный помощник. После компиляции в проекте создается библиотека проекта, которая имеет название проекта и содержит все скомпилированные объекты проекта. После запуска программы на моделирование сперва выполняется связывание объектов проекта и назначение начальных значений переменным и сигналам (elaboration). Затем запускается собственно симуляция. И для данной программы на консоль будет выдано сообщение:
# : ERROR : Hаllo,world
# : Time: 0 ps, Iteration: 0, TOP instance.
# KERNEL: stopped at time: 100 ns
# KERNEL: Simulation has finished. There are no more test vectors to simulate.
Программа на VHDL состоит из одного или нecкольких файлов. В одном файле размещаются одна или нecколько пар: объект проекта – архитектура объекта. Объект проекта – это интерфейсная часть, в которой указана информация о том, как включать данный объект внутри другого объекта, находящегося на более высоком уровне иерархии. А в архитектуре объекта описан алгоритм его функционирования. У одного объекта может быть нecколько архитектур, соответствующих разным алгоритмам функционирования, проектам на различных этапах проектирования. Такая структура программ VHDL позволяет строить библиотеки объектов, процедур, типов и т.п., выполнять программирование проекта в произвольном порядке: снизу-вверх или сверху-вниз, а также параллельно нecколькими программистами, использовать объекты из других проектов, тестировать проекты по одинаковой методике.
Расмотрим программирование проекта приоритетного шифратора. На вход шифратора поступают сигналы А1, …,А7 , а на выход выдаются сигналы Y2,Y1,Y0, которые кодируют номер входного сигнала, причем у А7 – наивысший приоритет. Т.е. при поступлении лог.1 на А7 и любой комбинации на остальные входы код Y2,Y1,Y0=111, при поступлении лог.0 на А7 , лог.1 на А6 и любой комбинации на остальные входы - код Y2,Y1,Y0=110 и т.д. Объект проекта выглядит как:
library std ; -- описание: используемая стандартная библиотека STD
use std.standard.all; -- описание: используются все типы из пакета STANDARD библиотеки STD
entity PRIORITY is -- название объекта - PRIORITY
port( --объявление портов
A1 : in BIT; -- входной порт А1 типа BIT
A2 : in BIT;
A3 : in BIT;
A4 : in BIT;
A5 : in BIT;
A6 : in BIT;
A7 : in BIT;
Y1 : out BIT; -- выходной порт Y1 типа BIT
Y2 : out BIT;
Y0 : out BIT );
end PRIORITY; -- конец объявления объекта
Так как библиотека STD – стандартная, она встроена во все симуляторы и может быть указана неявно. Для других библиотек, которые используются при описании объекта, нужно использовать их описание library и use. Здесь они приведены для примера.
Ключевое слово port открывает описание входов-выходов (портов) объекта. Слово in указывает на вход, а out – на выход. BIT – это тип порта, который, согласно определению этого типа в пакете standard, принимает значения 0 и 1.
Название объекта вначале и в конце – обязательно. Это дополнительная рутина, зато удобно для различения объектов, если их описание занимает много места, - как открывающаяся и закрывающаяся скобка особенного типа.
Описание архитектуры:
architecture HALLO of PRIORITY is -- начало архитектуры HALLO объекта PRIORITY
--декларативная часть архитектуры
signal t1,t2,t3,t4,t5,t6,t7:BIT; --объявление используемых сигналов
begin --начало описательной (поведенческой) части архитектуры
-- Y2Y1Y0
--A7 --1 1 1
t1<= not A7 and A6; -- 1 1 0
t2<= not A6 and A5 and not t1; -- 1 0 1
t3<= not A5 and A4 and not t1 and not t2; -- 1 0 0
t4<= not A4 and A3 and not t1 and not t2 and not t3; -- 0 1 1
t5<= not A3 and A2 and not t1 and not t2 and not t3 and not t4; -- 0 1 0
t6<= not A2 and A1 and not t1 and not t2 and not t3 and not t4 and not t5; -- 0 0 1
Y0<= A7 or t2 or t4 or t6;
Y1<= A7 or t1 or t4 or t5;
Y2<= A7 or t1 or t2 or t3;
end HALLO; --конец архитектуры
Раздел архитектуры состоит из декларативной и описательной частей. В декларативной части объявляются используемые внутри объекта сигналы, константы, специальные (свои собственные) типы, атрибуты, процедуры и функции, описания этих атрибутов, процедур и функций. Описательная часть состоит из списка параллельных операторов. Все параллельные операторы выполняются одновременно. Их порядок в списке не имеет другого значения, кроме значения, определяемого вкусом программиста.
В параллельных операторах процесса стоят последовательные операторы, выполняемые по очереди, как в программах на обычных языках. Схемы с памятью, например, триггер, регистр, ОЗУ моделируются с помощью оператора процесса или оператора вставки компонента с функцией памяти, описанного парой объект-архитектура в другом месте.
В данной программе все операторы – операторы параллельного присваивания, обозначенные символами "<=", которые сигналам присваивают значение выражения справа. Здесь в выражениях используются функции and, or и not. Hад операндами типа BIT определены еще функции nand, nor, xor, xnor. А функции сравнения "=" и "/=" - возвращают результат типа boolean со значениями true, false. Для задания четкого порядка выполнения функций в выражениях следует использовать скобки.
Эта архитектура написана стилем потоков данных, т.е. в ней использованы только параллельные операторы, кроме операторов процесса и вставки компонента. Здесь операторы как бы указывают потоки данных между линиями связи, обозначенными идентификаторами сигналов, а также обработку этих потоков.
Для проверки правильности проекта обычно используют испытательный стенд (testbench). Это тоже пара: объект – архитектура, в которой испытуемый блок использован как компонент. В Active HDL есть функция генерации испытательного стенда, которая генерирует его заготовку. Такая заготовка состоит из оператора включения испытуемого блока и набора сигналов, которые подключены к блоку. Остается только добавить операторов для генерации входных сигналов и возможно, для проверки выходных сигналов блока. Испытательный стенд для блока PRIORITY(HALLO):
entity priority_tb is --пустой объект, т.к. входов-выходов нeт
end priority_tb;
architecture TB_ARCHITECTURE of priority_tb is
component priority(hallo) -- компонент, который будет испытываться
port( -- выглядит почти так же, как объявление объекта проекта
A1 : in BIT;
A2 : in BIT;
A3 : in BIT;
A4 : in BIT;
A5 : in BIT;
A6 : in BIT;
A7 : in BIT;
Y1 : out BIT;
Y2 : out BIT;
Y0 : out BIT );
end component; -- сигналы внутри испытательного стенда
signal A1 : BIT:='0'; --сигнал объявлен с начальным состоянием = 0;
signal A2 : BIT:='0'; -- начальное состояние можно было бы не объявлять -
signal A3 : BIT:='0'; -- у битового типа и так симулятор назначает начальное состояние=0. signal A4 : BIT:='0'; -- В реальных проектах сигналы типа STD_LOGIC
signal A5 : BIT:='0'; -- и им симулятор по умолчанию назначает начальное состояние
signal A6 : BIT:='0'; -- = U - " не инициализированное "
signal A7 : BIT:='0'; -- поэтому для таких сигналов желательно объявить
signal Y1 : BIT:='0'; -- начальное состояние по своему усмотрению
signal Y2 : BIT:='0';
signal Y0 : BIT:='0';
begin -- описательная часть архитектуры
UUT : priority -- параллельный оператор вставки компонента
port map ( -- поименованное связывание портов и сигналов
A1 => A1, --порт А1 подключен к сигналу А1
A2 => A2,
A3 => A3,
A4 => A4,
A5 => A5,
A6 => A6,
A7 => A7,
Y1 => Y1,
Y2 => Y2,
Y0 => Y0
);
-- это операторы присваивания сигналу - генерируют тестовые сигналы
A1<= not A1 after 2 ns; -- оператор инвертирует сигнал,
--затем ждет 2нс и опять инвертирует и т. д. до бесконечности
A2<= not A2 after 4 ns;
A3<= not A3 after 6 ns;
A4<= not A4 after 8 ns;
A5<= not A5 after 10 ns;
A6<= not A6 after 12 ns;
A7<= not A7 after 14 ns;
end TB_ARCHITECTURE;
Эта программа запускается на моделирование и в окне графиков (waveform window) можно увидеть следующие графики:
Эти графики показывают, что модель приоритетного шифратора работает правильно. Если архитектура объекта PRIORITY претерпит изменения или модернизацию, то на этом испытательном стенде можно ее проверить опять, ничего в нем не меняя.
Итак, в данной статье рассмотрены основы программирования на VHDL и получена работоспособная, синтезируемая модель приоритетного шифратора. Эту модель можно совершенствовать, изменять число и функциональность портов ввода-вывода и т.п. Так что, согласно методике Hallo, World, можно сказать, что VHDL – это очень просто.