Оглавление
Введение

Комментарии

Имена, константы, числа

Типы данных в Verilog

Операции язака Verilog

Процессы Verilog

Операторы язака Verilog

Модули и порты

Цепи в Verilog

Переменные в Verilog

Приложение А

ВВЕДЕНИЕ

Verilog HDL — это язык описания аппаратуры, используемый для описания и моделирования электронных систем. Этот язык (также известный как просто Verilog) позволяет проектировать, верифицировать и реализовывать (например, в виде СБИС) аналоговые, цифровые и смешанные электронные системы на различных уровнях абстракции.

Язык Verilog был создан в 1984 (по некоторым источникам в 1985) году в фирме Automated Integrated Design Systems (позднее переименованной в Gateway Design Automation) как собственное средство моделирования. Поэтому есть предположение, что название Verilog расшифровывается как VERIfy LOGic. Фирма Gateway в 1989 году была куплена крупной компанией Cadence Design Systems. А фирма Synopsys в это время создала программы синтеза на базе языка Verilog.

Синтаксис Verilog очень похож на синтаксис языка C, что упрощает его освоение. Препроцессор Verilog очень похож на препроцессор языка C, и основные управляющие конструкции «if», «while» и др. подобны одноимённым конструкциям языка C.

Международный стандарт — IEEE Std 1364 — 2003(стандарт на Verilog 2003).
Вообще говоря, по мнению авторов сайта, стандарт IEEE на Verilog, как документ, написан очень отвратительно и если бы не авторитет Cadence, вряд ли бы стал стандартом в принципе. Мы считаем, что это связано с желанием получать прибыль за счет всевозможных семинаров, обучающих программ и т. п. Но это наше личное мнение. А вот сам язык Verilog заслуживает высокой оценки и достоен внимания.

КОММЕНТАРИИ

Комментарии в Verilog похожи на комментарии языка программирования С и делятся на однострочные и блочные. Однострочные комментарии начинаются символами // и заканчиваются концом строки. Блочные комментарии начинаются символами /* и заканчиваются */

Блочные комментарии не могут быть вложенными. Но внутри блочных комментариев могут быть однострочные, хотя, кажется, что это не имеет смысла, но представьте, что Вам нужно временно закомментировать кусок Verilog-кода в котором есть однострочные комментарии. Если бы однострочные комментарии не допускались внутри блочных, то Вам пришлось бы удалять их, что совершенно нерационально.

  • // Пример однострочных комментариев
  • module mux (out, in1, in2, s0) // Мультиплексор
  • /*****************************
  • * Пример блочных комментариев *
  • ******************************/

Очень удобно сделано, больше нечего сказать.

ИМЕНА, КОНСТАНТЫ, ЧИСЛА

В Verilog имя (идентификатор) — последовательность букв и цифр, знаков «$" и «_", причем начинаться оно обязано не с цифры. Регистр имеет значение. Если начальный символ — «\", то следом за ним может идти любая последовательность символов. Все, что до пробела, будет считаться корректным именем. Например: «Character», «cHaracter», «$Character», «\c+Ha^racter».

Константы в Verilog имеют особую форму записи. Сначала идет разрядность числа, потом кавычка ('), за ним — основание системы счисления (b, o, d, h) и сами цифры. Примеры:

  • 7'h7F //семибитное число 127, записанное в шестнадцатеричной (h — hex) форме
  • 7'b1111_1111 //то же самое число, записанное в двоичной форме. Знак «_" игнорируется
  • 10'b1111_1111 // число 127, занимающее не 7 бит, а 10. То есть, равно 000_1111_1111
  • 18 // число, записанное в стандартной форме, будет приведено к десятичному Integer
  • 0.5 // будет приведено к типу real

ТИПЫ ДАННЫХ В VERILOG
Данные в Verilog могут принимать следующие значения:
  • 0 — логический ноль или значение «false»;
  • 1 — логическая единица или значение «true»;
  • x — неизвестное логическое значение;
  • z — состояние высокого импеданса
Эти значения уже включены в язык Verilog и каких-либо библиотек не требуют.

В языке Verilog все типы данных являются либо цепями, либо переменными. Цепи представляют собой связи между объектами и, исходя из этого, не могут хранить значения (за исключением цепей типа trireg). Цепи просто передают от источника (источников) его (их) значения на входы других объектов. Если цепь не подключена к какому-либо источнику (грубо говоря «обрыв»), то ее значение будет z, за исключением цепи trireg, которая передает предыдущее значение источника. Ниже приведены типы цепей.

Таблица 1

Тип цепиОписание
wire, tri простые линии связи
wor, trior линии связи с функцией монтажного или
wand, triand линии связи с функцией монтажного и
tri0, tri1 линии, подтянутые к 0 или 1
supply0, supply1 линии с заданным значением 0 или 1
trireg линии, сохраняющие последнее значение, когда источник перешел в z

На практике, самым применяемым типом цепей в языке Verilog является тип wire.

Цепи (кроме цепи trireg) объявляются по следующим синтаксическим правилам:

nettype [drive_strength] [expand_range] [delay] <list_of_variables>;

  • nettype — тип цепи;
  • drive_strength — мощность источника (для моделирования);
  • expand_range — разрядность цепи, по умолчанию цепь в один разряд. Разрядность задается так — [<msb>:<lsb>] или scalared[<msb>:<lsb>] или vectored[<msb>:<lsb>]. msb — старший бит, lsb — младший. Разрядность должна задаваться не отрицательными целыми константами или константными выражениями. lsb может быть больше или равно msb. scalared — разрешает доступ к отдельным битам или группе бит. vectored — доступ возможен только ко всем разрядом сразу. По умолчанию цепь определяется как scalared;
  • delay — задержка распространения сигнала (для моделирования).

Мощность источника задается так: (<strength1>,<strength0>) или (<strength0>,<strength1>). strength1 и strength0 задают мощность источника в соответствующих их названию логических состояниях и могут принимать следующие значения Таблица 2

supply1 strong1 pull1 weak1 highz1
supply0 strong0 pull0 weak0 highz0


Так как мощность источника используется только для моделирования, то мы не будем подробно рассматривать ее. Отметим лишь, что по умолчанию используется (strong1, strong0) и что комбинации (highz1, highz0) и (highz0, highz1) являются недопустимыми.

Цепи типа trireg объявляются по следующим синтаксическим правилам:

trireg [charge_strength] [expand_range] [delay] <list_of_variables>;

  • charge_strength — емкость источника (для моделирования).

Емкость источника может принимать следующие значения: small, medium, large. По умолчанию используется medium.

Ниже приведены примеры объявления цепей:

  • wire err1, err2; // Определили две одиночных цепи
  • wand err3, err4; // Определили две одиночных цепи с монтажным «и»
  • wire [7:0] bus1, bus2; // Определили две восьмиразрядных шины
  • wire vectored[0:7] bus3, bus4; // Определили две восьмиразрядных шины
  • wire (highz1, strong0) [0:7] opbus; // Определили шину с открытым коллектором
  • supply0 gnd;
  • supply1 power;

Теперь давайте посмотрим на типы из группы переменных. Давайте попробуем разобраться.

Таблица 3

ТипОписание
reg переменная без знака
integer переменная со знаком, размерность в 32 разряда
time переменная в 64 разряда без знака
real переменная с плавующей точкой
realtime переменная с плавующей точкой

Cамой распространенной переменной является переменная типа reg.

Регистры в языке Verilog определяются по следующим синтаксическим правилам:

reg [range] <list_of_reg_variables>;

reg — ключевое слово.

range — разрядность регистра, по умолчанию регистр одноразрядный. Разрядность задается так — [<msb>:<lsb>].

list_of_reg_variables — список переменных.

Примеры объявления переменных на языке Verilog:

  • reg x; //Однобитный регистр
  • reg a, b, c; //3 однобитных регистра
  • reg [7:0] q; // 8-битный регистр
  • integer d, e; // две переменных целого типа
  • integer f[9:0]; // массив из 10 переменных целого типа
  • real e; // вещественая переменная

Нужно отметить, что не все синтезаторы поддерживают тип real и realtime(Quartus II, например). Кроме того, есть ограничения на разрядность переменных.

Для структуризации данных используется такая константа, как parametr (параметр). Параметр должен быть проинициализирован перед его использованием числом или выражением, которое может содержать другие, ранее определенные параметры.

  • parametr TRUE=1, FALSE=0;
  • parametr [1:0] A0=1, A1=2, A2=3, A3=0;
  • parametr nbit=8;
  • wire [nbit-1:0] bus;



ОПЕРАЦИИ ЯЗЫКА VERILOG

Синтаксис операций Verilog похож на синтаксис операций языка С. Символы операций, их названия, а также применимость к вещественным переменным приведены в таблице 4.

Таблица 4
СимволОписание операцииПрименимость к real
{} Конкатенация Не допустимо
+ - * / Арифметические Допустимо
% Модуль Не допустимо
> >= < <= Отношения Допустимо
! Логическое отрицание Допустимо
&& Логическое И Допустимо
|| Логическое ИЛИ Допустимо
== Логическое равенство Допустимо
Логическое неравенство Допустимо
=== Идентичность Не допустимо
≠== Неидентичность Не допустимо
~ Побитовая инверсия Не допустимо
& Побитовое И Не допустимо
| Побитовое ИЛИ Не допустимо
^ Побитовое исключающее ИЛИ Не допустимо
{^~ ~^ Побитовая эквивалентность Не допустимо
& Редукционное И Не допустимо
~& Редукционное НЕ-И Не допустимо
| Редукционное ИЛИ Не допустимо
~| Редукционное НЕ-ИЛИ Не допустимо
^ Редукционное исключающее ИЛИ Не допустимо
~^ ^~ Редукционное НЕ исключающее ИЛИ Не допустимо
<< Сдвиг влево Не допустимо
>> Сдвиг вправо Не допустимо
<<< Циклический сдвиг влево Не допустимо
>>> Циклический сдвиг вправо Не допустимо
?: Условный оператор Допустимо

Теперь расположим операции Verilog в порядке убывания приоритета:

  • + - ! ~ (унарные) Наивысший приоритет
  • * / %
  • + - (бинарные)
  • << >> <<< >>>
  • < <= > >=
  • == ≠ === ≠==
  • & ~&
  • | ~|
  • &&
  • ||
  • ?: Низший приоритет

Операции с равным приоритетом выполняются слева направо, за исключением ?: который выполняется справа налево.



ПРОЦЕССЫ VERILOG

В Verilog процессы носят название процесс-блоков или always-блоков. Блоки подобного типа реализуют некий процесс, который может повторяться многократно. Синтаксис always-блоков приведен ниже:


always [<event_control>]
[begin|fork][:<block_name>]
<statements>;
[end|join]
где event_control — список чувствительности, который начинается с символа @ и далее в круглых скобках перечисляются переменные, при изменении которых должен запустится процесс. При этом для обозначения положительных и отрицательных фронтов используются ключевые слова — posedge и negedge соответственно. Например:
  • always @ (a or b)
  • begin
  • #10 s = a + b ;
  • #20 p = a ;
  • end
или
  • always @ (posedge CLK)
  • begin
  • end

В Verilog есть еще блоки начальной установки. Эти блоки выполняются один раз с нулевого момента времени и потому у них нет списка чувствительности. initial-блоки используются в основном при моделировании.


initial
[begin|fork][:<block_name>]
<statements>;
[end|join]

ОПЕРАТОРЫ ЯЗЫКА VERILOG

Операторы присваивания в Verilog делятся на блочное «=" и внеблочное «<=". Блочное присваивание выполняется сразу, в том месте, где оно встретилось, причем переменная меняет свое значение мгновенно и это может происходить неоднакратно в одной ветви алгоритма. Внеблочное присваивание изменяет значение переменной только в момент выхода из блока. В разделе «МОДУЛИ И ПОРТЫ» мы покажем какие различные результаты дают эти два вида присваивания Verilog.

Оператор ветвления if. Он похож на идентичные операторы из языков программирования. Если в ветви присутствует последовательные блоки, то они ограничиваются ключевыми словами begin — end. Ниже прведены примеры написания этого оператора на Verilog.

Пример1 (простая конструкция):
  • if (c)
  • x = a;
  • else
  • x = b;
Присутствие else необязательно.
Пример 2 (конструкция if. else if. else):
  • if (instruction == ADD)
  • begin
  • carry_in = 0;
  • complement_arg = 0;
  • end
  • else if (instruction == SUB)
  • begin
  • carry_in = 1;
  • complement_arg = 1;
  • end
  • else
  • illegal_instruction = 1;
Конструкций else if может быть несколько. Присутствие else необязательно.
Пример 3 (вложенные операторы if):
  • if (select[1])
  • begin
  • if (select[0]) out = in[3];
  • else out = in[2];
  • end
  • else
  • begin
  • if (select[0]) out = in[1];
  • else out = in[0];
  • end

Операторы выбора case, casex, casez. Очень похожи на оператор С switch. Синтаксис рассмотрим на операторе case:

  • case (expr)
  • case_item1: begin
  • … statements …
  • end
  • case_item2: begin
  • … statements …
  • end
  • case_itemN: begin
  • … statements …
  • end
  • default: begin
  • … statements …
  • end
  • endcase

В этом операторе результат expr по порядку сравнивается с костантными выражениями case_item. В случае совпадения expr с одним из выражений, то выполняется соответствующее ему statements. Если нет ни одного совпадения, то выполняется statements под ключевым словом default, если оно есть, в противном случае не выполняется ничего. Если statements — одиночное выражение, то begin — end ставить необязательно. statements может представлять из себя другие операторы. Приведем пример:

  • case (a)
  • 2'b11:
  • b = w ;
  • 2'b10:
  • b = x ;
  • 2'b01:
  • b = y ;
  • 2'b00:
  • b = z ;
  • endcase

Когда часть битов условия должна игнорироваться, используют операторы casex, casez. Оператор casex игнорирует биты в состоянии x и z.

  • reg [3:0] cond;
  • casex (cond)
  • 4'b100x: out = 1;
  • default: out = 0;
  • endcase

Оператор casez игнорирует биты в состоянии z.

  • casez (what_is_it)
  • 2'bz0: begin
  • it_is = even;
  • end
  • 2'bz1: begin
  • it_is = odd;
  • end
  • endcase

Операторы цикла в Verilog могут быть следующими:

  • оператор for — по переменной цикла;
  • оператор while — выполняет блок выражений пока его условие не примет значение false;
  • оператор repeat — выполняет блок выражений заданное число раз;
  • оператор forever — бесконечный цикл.

Далее приведем пример наиболее распрастраненного в Verilog цикла:

  • for (i=0; i < 8; i=i+1)
  • x[i] = a[i] & b[7-i];
Это равносильно если бы мы записали следующий Verilog-код
  • x[0] = a[0] & b[7];
  • x[1] = a[1] & b[6];
  • x[2] = a[2] & b[5];
  • x[3] = a[3] & b[4];
  • x[4] = a[4] & b[3];
  • x[5] = a[5] & b[2];
  • x[6] = a[6] & b[1];
  • x[7] = a[7] & b[0];
Примеры остальных циклов Verilog:
  • always
  • begin @ (posedge clock)
  • while (x <y)
  • begin
  • @ (posedge clock);
  • x = x + z;
  • end
  • end
  • always
  • forever
  • begin
  • @ (posedge clock);
  • x = x + z;
  • end

Оператор Verilog disable применяется для прерывания какого-либо процесса. Не поддерживается большинством синтезаторов.

Оператор Verilog wait применяется для ожидания какого-либо события. Не поддерживается большинством синтезаторов.



МОДУЛИ И ПОРТЫ

Модуль — основной объект иерархии проекта в языке Verilog. Из модулей различного уровня собирается устройство проекта, это происходит в модуле самого верхнего уровня. В принципе, проект может состоять из одного модуля, но большие проекты целесообразно разбить на отдельные модули, т. е. создать структуру проектируемого устройства. Простая структура показана на рисунке 1. Здесь в модуле верхнего уровня (модуль 1) соединяются модули нижнего уровня (модули 2 и 3).

Рисунок 1 - структура в Verilog



Синтаксис объявления модуля выглядит так:

  • module <module_name> [<port_list>];
  • <module_items>
  • endmodule

<port_list> - не обязательный элемент модуля. Он содержит список портов (интерфейс) модуля. Этот список используется для позиционного подключения портов модуля к внешнему миру. Порты модуля могут быть следующими:

  • input — входной порт;
  • output — выходной порт;
  • inout — двунаправленный порт.

Давайте напишем на Verilog простой модуль:

  • // Функциональное описание элемента NAND
  • module MY_NAND (A, B, C);
  • input A, B;// Входные порты
  • output C; // Выходной порт
  • assign C = ~(A & B); // Операция И-НЕ
  • endmodule

Теперь создадим на базе модуля my_nand более сложное устройство:

  • module MY_MODULE (S1, EN1, S2, EN2, OUT);
  • input S1, EN1, S2, EN2;
  • output OUT;
  • wire s1, s2;
  • MY_NAND D1 (S1, EN1, s1), D2 (S2, EN2, s2), D3 (s1, s2, OUT);
  • endmodule

Рисунок 2В приведенном выше листинге, мы собрали устройство из трех модулей типа MY_NAND — D1, D2, D3. Структура устройства MY_MODULE показана на рисунке 2. Здесь мы использовали позиционное назначение портов, т. е. порты назначаются в соответствии с их положением в листе портов модуля MY_NAND. Теперь перепишем Verilog-код и посмотрим, как можно непосредственно назначать порты, не используя листа портов:

  • // Функциональное описание элемента NAND
  • module MY_NAND (A, B, C);
  • input A, B;// Входные порты
  • output C; // Выходной порт
  • assign C = ~(A & B); // Операция И-НЕ
  • endmodule

Мы не будем уже пользоваться позиционным назначением портов. Посмотрите, как выглядит непосредственное назначение в языке Verilog. Видите, порты назначаются в любой последовательности независимо от их расположения в листе портов модуля MY_NAND.

  • module MY_MODULE (S1, EN1, S2, EN2, OUT);
  • input S1, EN1, S2, EN2;
  • output OUT;
  • wire s1, s2;
  • MY_NAND D1 (.A (S1), .B (EN1), .C (s1)), D2 (.C (s2), .A (S2), .B (EN2)), D3 (.A (s1), .C (OUT), .B (s2));
  • endmodule

Мы можем, используя схожий механизм Verilog, переименовать порты интерфейса модуля, не изменяя внутри модуля ничего. Это может быть полезным, когда мы хотим иметь более информативные названия портов в уже написанном модуле и не переписывать при этом внутренности:

  • // Внешне интерфейс выглядит теперь так — (ER1, EN1, ER2, EN2, ERR)
  • module MY_MODULE (.ER1 (S1), EN1, .ER2 (S2), EN2, .ERR (OUT));
  • input S1, EN1, S2, EN2;
  • output OUT;
  • wire s1, s2;
  • MY_NAND D1 (.A (S1), .B (EN1), .C (s1)), D2 (.C (s2), .A (S2), .B (EN2)), D3 (.A (s1), .C (OUT), .B (s2));
  • endmodule

А теперь давайте рассмотрим два оператора присваивания в примерах на Verilog. Cначала рассмотрим блочное присваивание:

  • module rtl (clk, data, rega, regb);
  • input data, clk;
  • output rega, regb;
  • reg rega, regb;
  • always @(posedge clk)
  • begin
  • rega = data; // блочное присваивание
  • regb = rega;
  • end
  • endmodule
На рисунке 3 показано, какую схему мы реально получим в результате блочного присваивания.

Рисунок 3 - блочное присваивание в Verilog


А теперь пример внеблочного присваивания:

  • module rtl (clk, data, rega, regb);
  • input data, clk;
  • output rega, regb;
  • reg rega, regb;
  • always @(posedge clk)
  • begin
  • rega <= data; // внеблочное присваивание
  • regb <= rega;
  • end
  • endmodule
На рисунке 4 показано, какую схему мы реально получим в результате внеблочного присваивания.

Рисунок 4 - внеблочное присваивание в Verilog


Рисунок 5 - память для проекта на VerilogТеперь давайте потихоньку создавать наш Verilog-проект. Ну для начала создадим память RAM 64X8, как показано на рисунке 5.

  • module ram (WE, CLK, DATA, Q, ADDR);
  • output [7:0] Q;
  • input [7:0] DATA;
  • input [5:0] ADDR;
  • input WE;
  • input CLK;
  • reg [7:0] ram_MEM [63:0];
  • always @(posedge CLK)
  • begin
  • if (WE == 1'b1)
  • ram_MEM[ADDR] <= DATA;
  • end
  • assign Q = ram_MEM[ADDR];
  • endmodule

ЦЕПИ В VERILOG

Теперь давайте более подробно рассмотрим цепи Verilog. Начнем с цепи типа wire. Verilog воспринимает цепь wire как физическую линию связи между элементами или модулями проекта. Язык Verilog позволяет считывать значения цепей wire внутри функций и блоков типа beginend, но запрещает присваивать там значения цепям типа wire. Цепь wire не хранит своего значения. Поэтому если она никуда не подключена, то ее значение будет z (обрыв). Чтобы цепь wire имела определенное значение, нужно сделать одно из двух:

  • соединить wire с выходом элемента или модуля;
  • непрерывно присваивать значение wire (continuous assignment).

Ниже приведены два способа непрерывного присваивания:

  • wire a; //объявление
  • assign a = b & c; //непрерывное присваивание
  • wire d = e & f; //объявление и непрерывное присваивание

Если произвести несколько присваиваний одной цепи wire, то это будет равносильно короткому замыканию.

Цепи типа wand (wired-AND) — цепи с функцией монтажного И. В примере, приведенном ниже, порт С = A & B.

  • // Пример цепи типа wand
  • module WAND_EX (A, B, C);
  • input A, B;
  • output C;
  • wand C;
  • assign C = A;
  • assign C = B;
  • endmodule

В остальном, цепи типа wand соответствуют всему сказанному о цепях типа wire. Тоже отноиться и к цепям типа wor, только результат будет уже С = A | B:

  • // Пример цепи типа wor
  • module WOR_EX (A, B, C);
  • input A, B;
  • output C;
  • wor C;
  • assign C = A;
  • assign C = B;
  • endmodule

Особенностью цепи типа tri является то, что все передатчики, присоединенные к таким цепям, должны иметь возможность переводить свои выходы в состояние z. В один момент времени только один передатчик может выставлять на свой выход логический уровень и задача разработчика заключается в том, чтобы не допускать одновременного выставления логических уровней несколькими передатчиками:

  • // Пример цепи типа tri
  • module TRI_EX (OUT, SEL);
  • input [1:0] SEL;
  • output OUT;
  • reg a, b, c;
  • tri OUT;
  • always @ (SEL) begin
  • a = 1'bz; //устанавливаем все переменные в состояние Z
  • b = 1'bz;
  • c = 1'bz;
  • case (SEL) //только одна переменная должна иметь лог. уровень
  • 2'b00: a = 1'b1;
  • 2'b01: b = 1'b0;
  • 2'b10: c = 1'b1;
  • endcase
  • end
  • assign OUT = a; // собираем цепь
  • assign OUT = b;
  • assign OUT = c;
  • endmodule

Цепь типа supply0 жестко заведена на 0. Цепь типа supply1 жестко заведена на 1. Больше об этих цепях сказать нечего.


ПЕРЕМЕННЫЕ В VERILOG

Основной переменной в языке Verilog является регистр reg. Регистр может состоять из одного бита или вектора бит. Регистр — это всегда переменная без знака и если мы запишем туда отрицательное число, то получим положительное число, соответствующее дополнительному коду. Очень часто, для симуляции (бывает и для синтеза) различной памяти, используется массив регистров:

  • reg [7:0] memory256 [0:255]; // память из 256 байт
  • reg [16:0] memory1K [0:511]; // память на 1 Кбайт

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

Переменные типа integer в языке Verilog носят вспомогательный характер. В принципе можно обойтись и без них, но при моделировании бывает удобней воспользоваться этой переменной, чем reg. Как отмечалось ранее, integer — 32-х разрядная переменная со знаком. Можно использовать массивы с элементами типа integer:

  • integer int[0:63];

Для моделирования временных интервалов, в Verilog добавлен еще один тип переменных — time. Это 64-х разрядная переменная без знака. Обычно time используется вместе с системной функцией $time. Можно использовать массивы с элементами типа time:

  • time t[1:10];

В стандарте Verilog допускается использовать вещественные числа и переменные типа time. Правда не все средства проектирования поддерживают данный тип. Перечислим особенности переменных типа real:

  • есть ограничения на операции Verilog с вещественными числами (см. таблицу 4);
  • у переменных типа real не может быть диапазона;
  • Verilog запрещает использовать массивы с элементами типа real;
  • вещественные числа не могут быть индексами;
  • дескрипторы фронта (posedge, negedge) не применяются к вещественным переменным.

Ниже приведены примеры написания вещественных чисел:

1.5

0.5

123.456

1.0

3.14e-2

10E10

0.123456_789

Вот в принципе и все о переменных в языке Verilog.


ПРИЛОЖЕНИЕ А

В таблице ниже приведен список зарезервированных слов языка Verilog.

Таблица 5

always or strong1
and for output supply0
assign force supply1
forever parametr
begin fork pmos table
buf function posedge task
bufif0 primitive time
bufif1 highz0 pull0 tran
highz1 pull1 tranif0
case pullup tranif1
casex if pulldown tri
casez initial tri0
cmos inout rcmos tri1
input real triand
deassign integer reg trior
default release trireg
defparam join repeat
disable rnmos vectored
large rpmos
edge rtran wait
else macromodule rtranif0 wand
end medium rtranif1 weak0
endcase module weak1
endmodule scalared while
endfunction nand small wire
endprimitive nor specify wor
endspecify not specparam &nbsp
endtable notif0 strength xnor
endtask notif1 strong0 xor
event
E-mailmail@allhdl.ru
© allhdl.ru, 2007 - 2015