Модуль - основной объект иерархии проекта в языке Verilog. Из модулей различного уровня собирается устройство проекта, это происходит в модуле самого верхнего уровня. В принципе, проект может состоять из одного модуля, но большие проекты целесообразно разбить на отдельные модули, т.е. создать структуру проектируемого устройства (иерархия). Простая структура показана на рисунке 1. Здесь в модуле верхнего уровня (модуль 1) соединяются модули нижнего уровня (модули 2 и 3).
Общий синтаксис описаниями модуля:
Рассмотрим структуру и принцип написания модуля на примере логического элемента «NAND2».
Создадим на базе модуля «MY_NAND» более сложное устройство:
В приведенном выше примере №6, мы собрали устройство из трех модулей типа MY_NAND - D1, D2, D3. Структура устройства MY_MODULE показана на рисунке 2. Здесь мы использовали позиционное назначение портов, т.е. порты назначаются в соответствии с их положением в листе портов модуля MY_NAND. Теперь перепишем Verilog - код и посмотрим, как можно непосредственно назначать порты, не используя листа портов:
Мы не будем уже пользоваться позиционным назначением портов. Посмотрите, как выглядит непосредственное назначение в языке Verilog. Видите, порты назначаются в любой последовательности независимо от их расположения в листе портов модуля MY_NAND.
Мы можем, используя схожий механизм Verilog, переименовать порты интерфейса модуля, не изменяя внутри модуля ничего. Это может быть полезным, когда мы хотим иметь более информативные названия портов в уже написанном модуле и не переписывать при этом внутренности:
А теперь давайте рассмотрим два оператора присваивания в примерах на Verilog. Сначала рассмотрим блочное присваивание:
На рисунке 3 показано, какую схему мы получим в результате синтеза кода с применением блочного присваивания.
Рисунок 3. Результат блочного присвоения
А теперь пример внеблочного присваивания:
На рисунке 4 показано, какую схему мы получим в результате синтеза кода с применением внеблочного присваивания.
Рисунок 4. Результат внеблочного присвоения
Порт – порты в Verilog бывают трёх типов:
- ‘Input’ - входной;
- ‘Output’ - выходной;
- ‘Inout’ - двунаправленный.
Список портов описывается в начале модуля см. пример 12.
Имена входных и выходных портов по умолчанию типа ‘wire’.
Цепи. Цепи на схеме соответствуют физическим проводам, которые подключаются ко всем компонентам схемы. Разрядность цепей по умолчанию — один бит. Цепи не хранят значения сигнала, и для того чтобы состояние сигнала в цепи было определено, какой-либо источник сигнала должен непрерывно управлять ею. Если цепь имеет несколько источников сигнала — драйверов (например, два выхода вентилей подключены к одной цепи), то значение результирующего сигнала в цепи имеет значение, согласно тому, какой тип цепи используется. Названия цепей и выполняемые ими функции приведены в таблице 1.
Таблица 1.
Название |
Функция |
Описание |
|||||||||||||||||||||||||
wire |
|
Для этой цепи, если все драйверы имеют одно и то же значение, тогда wire принимает это же значение. Если все драйверы, кроме одного, имеют значение Z, тогда wire принимает значение того драйвера, который имеет значение выходного сигнала, не равное Z. Если два или больше не5Z драйвера имеют различную мощность выходного каскада, то wire принимает значение более сильного драйвера. Если два драйвера равной силы имеют различные значения, то wire принимает значение x. |
|||||||||||||||||||||||||
wand |
AND |
Проводное «И»
|
|||||||||||||||||||||||||
wor |
OR |
Проводное «ИЛИ»
|
|||||||||||||||||||||||||
tri |
Tri |
Цепь с третьим состоянием |
|||||||||||||||||||||||||
triand |
Tri + AND |
Цепь с третьим состоянием, выполняющая проводное «И»
|
|||||||||||||||||||||||||
trior |
Tri + OR |
Цепь с третьим состоянием, выполняющая проводное «ИЛИ»
|
|||||||||||||||||||||||||
tri0 |
Tri + pulldown |
Когда эта цепь не управляется, тогда ее значение — 0. Моделируется функция pulldown |
|||||||||||||||||||||||||
tri1 |
Tri + pullup |
Когда эта цепь не управляется, тогда ее значение — 1. Моделируется функция pullup |
|||||||||||||||||||||||||
trireg |
|
Цепь ведет себя как wire, за исключением того, что, когда все драйверы сети находятся в высоком импедансе — Z5состоянии, тогда цепь сохраняет свое последнее значение, которое было, когда эта цепь управлялась. trireg используются для того, чтобы моделировать емкость в данной цепи |
|||||||||||||||||||||||||
supply0 |
|
Моделируют цепи, которые связаны с «землей» |
|||||||||||||||||||||||||
supply1 |
|
Моделируют сети, которые связаны с питанием |
Цепь объявляется следующим образом:
тип[разрядность] имя цепи ;
Разрядность целесообразно указывать для векторов, а для одноразрядного провода указывается только тип и имя.
Цепи типа trireg объявляются по следующим синтаксическим правилам:
charge_strength - емкость источника (для моделирования).
Емкость источника может принимать следующие значения: small, medium, large. По умолчанию используется medium.
Ниже приведены примеры объявления цепей:
Далее рассмотрим типы из группы переменных.
Таблица 2
Тип |
Описание |
reg |
переменная без знака |
integer |
переменная со знаком, размерность в 32 разряда |
time |
переменная в 64 разряда без знака |
real |
переменная с плавающей точкой |
realtime |
переменная с плавающей точкой |
Регистры в языке Verilog определяются по следующим синтаксическим правилам:
Примеры объявления переменных на языке Verilog:
Для структуризации данных используется константа - parametr (параметр). Параметры не принадлежат к какому-либо регистру или группе цепей. Параметры не переменные, они — константы. Параметры могут быть как местные, локальные, так и глобальные. Синтаксис для объявлений параметров
::= parameter
Примечание: в некоторых случаях при использовании параметров можно определять диапазон при объявлении параметра.