- 3.1 Лексические единицы
- 3.2 Разделительные символы (white spaces)
- 3.3 Комментарии
- 3.4 Операторы
- 3.5 Числа
- 3.5.1 Целочисленные константы
- 3.5.2 Вещественные константы
- 3.5.3 Преобразование
- 3.6 Строки
- 3.6.1 Объявление строковой переменной
- 3.6.2 Работа со строками
- 3.6.3 Специальные символы в строках
- 3.7 Идентификаторы, ключевые слова и системные имена
- 3.7.1 Экранированные идентификаторы
- 3.7.2 Ключевые слова
- 3.7.3 Задачи и функции системы
- 3.7.4 Директивы компилятора
- 3.8 Атрибуты
- 3.8.1 Примеры
- 3.8.2 Синтаксис

3.1 Лексические единицы
Текстовые файлы исходных текстов Verilog HDL должны представлять собой поток лексических единиц. Лексическая единица должна состоять из одного или нескольких символов. Расположение лексем в исходном файле должно быть свободного формата, то есть пробелы и новые строки не должны быть синтаксически значимыми, кроме как разделителями лексем, за исключением экранированных идентификаторов (см. 3.7.1).
Типы лексических единиц в языке следующие:
- Разделительные символы (white spaces)
- Комментарий
- Оператор
- Число
- Строка
- Идентификатор
- Ключевое слово
3.2 Разделительные символы (white spaces)
Разделительные символы должно содержать символы пробела, табуляции, новой строки и подачи формы. Эти символы игнорируются, за исключением случаев, когда они служат для разделения других лексических единиц. Однако пробелы и табуляции должны считаться значимыми символами в строках (см. 3.6).
3.3 Комментарии
В Verilog HDL есть две формы комментариев. Однострочный комментарий начинается с двух символов // и заканчивается новой строкой. Блочный комментарий начинается с /* и заканчивается */. Блочные комментарии не должны быть вложенными. Маркер однострочного комментария // внутри блочного комментария не имеет какого-либо специального значения
3.4 Операторы
Операторы — это одно-, двух- или трехсимвольные последовательности, которые используются в выражениях. В пункте 5 рассматривается использование операторов в выражениях.
Унарные операторы должны располагаться слева от операнда. Бинарные операторы должны располагаться между операндами. Условный оператор должен иметь два символа оператора, которые разделяют три операнда.
3.5 Числа
Числовые константы могут быть заданы как целочисленные (определены в разделе 3.5.1) или вещественные константы.
number ::=
decimal_number
| octal_number
| binary_number
| hex_number
| real_number
real_numbera ::=
unsigned_number . unsigned_number
| unsigned_number [ . unsigned_number ] exp [ sign ] unsigned_number
exp ::= e | E
decimal_number ::=
unsigned_number
| [ size ] decimal_base unsigned_number
| [ size ] decimal_base x_digit { _ }
| [ size ] decimal_base z_digit { _ }
binary_number ::=
[ size ] binary_base binary_value
octal_number ::=
[ size ] octal_base octal_value
hex_number ::=
[ size ] hex_base hex_value
sign ::= + | -
size ::= non_zero_unsigned_number
non_zero_unsigned_numbera ::= non_zero_decimal_digit { _ | decimal_digit}
unsigned_numbera ::= decimal_digit { _ | decimal_digit }
binary_valuea ::= binary_digit { _ | binary_digit }
octal_valuea ::= octal_digit { _ | octal_digit }
hex_valuea ::= hex_digit { _ | hex_digit }
decimal_basea ::= '[s|S]d | '[s|S]D
binary_basea ::= '[s|S]b | '[s|S]B
octal_basea::= '[s|S]o | '[s|S]O
hex_basea ::= '[s|S]h | '[s|S]H
non_zero_decimal_digit ::= 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
decimal_digit ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
binary_digit ::= x_digit | z_digit | 0 | 1
octal_digit ::= x_digit | z_digit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
hex_digit ::=
x_digit | z_digit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
| a | b | c | d | e | f | A | B | C | D | E | F
x_digit ::= x | X
z_digit ::= z | Z | ?
3.5.1 Целочисленные константы
Целочисленные константы могут быть заданы в десятичном, шестнадцатеричном, восьмеричном или двоичном формате.
Существует две формы для выражения целочисленных констант. Первая форма — это простое десятичное число, которое задается как последовательность цифр от 0 до 9, по выбору начинающаяся с унарного оператора плюс или минус. Вторая форма определяет константу с основанием, которая должна состоять максимум из трех лексем — необязательной константы размера, символа апострофа (‘, ASCII 0x27), за которым следует символ формата основания, и цифр, представляющих значение числа. Макрозамена этих трех лексем должна быть законной.
Первый маркер, константа размера, определяет размер константы в виде точного количества битов. Он должен быть указан как ненулевое беззнаковое десятичное число. Например, спецификация размера для двух шестнадцатеричных цифр равна 8, поскольку одна шестнадцатеричная цифра требует 4 бита.
Второй маркер, base_format, должен состоять из нечувствительной к регистру буквы, указывающей основание для числа, опционально перед ней должен стоять одиночный символ s (или S) для указания знакового числа, перед которым ставится символ апострофа. Разрешенные спецификации оснований: d, D, h, H, o, O, b или B для десятичного, шестнадцатеричного, восьмеричного и двоичного оснований соответственно.
Символ апострофа и символ формата основания не должны разделяться пробелами.
Третий маркер, беззнаковое число, должен состоять из цифр, которые являются разрешенными для указанного формата основания. Маркер беззнакового числа должен следовать непосредственно за форматом основания, перед которым по желанию может быть пробел. Шестнадцатеричные цифры от a до f не чувствительны к регистру.
Простые десятичные числа без указания размера и формата основания рассматриваются как знаковые целые числа, тогда как числа, указанные с форматом основания, рассматриваются как знаковые целые числа, если включен обозначитель s, или как беззнаковые целые числа, если используется только формат основания. Обозначение s не влияет на указанный битовый шаблон, только на его интерпретацию.
Оператор плюс или минус, предшествующий константе размера, является унарным оператором плюс или минус. Оператор плюс или минус между базовым форматом и числом является недопустимым синтаксисом.
Отрицательные числа должны быть представлены в двухкомпонентной форме.
Символ x представляет неизвестное значение в шестнадцатеричной, восьмеричной и двоичной константах. Символ z представляет значение высокого импеданса. Обсуждение набора значений Verilog HDL см. в разделе 4.1. Символ x устанавливает 4 бита в неизвестное значение в шестнадцатеричном базисе, 3 бита в восьмеричном базисе и 1 бит в двоичном базисе. Аналогично, символ z устанавливает 4 бита, 3 бита и 1 бит, соответственно, в значение высокого импеданса.
Если размер беззнакового числа меньше размера, указанного для константы, то беззнаковое число заполняется слева нулями. Если крайний левый бит в беззнаковом числе — x или z, то для заполнения слева используется x или z соответственно. Если размер беззнакового числа больше размера, указанного для константы, то беззнаковое число усекается слева.
Количество битов, составляющих безразмерное число (которое является простым десятичным числом или числом без спецификации размера), должно быть не менее 32. Безразмерные беззнаковые константы, где старший бит неизвестен (X или x) или трехсоставной (Z или z), должны быть расширены до размера выражения, содержащего константу.
В стандарте IEEE Std 1364-1995 в безразмерных константах, где старший бит неизвестен или имеет третье состояние, x или z были расширены только до 32 бит. Использование x и z при определении значения числа не зависит от регистра.
Перевод Официального Стандарта Verilog HDL
При использовании в числе символ вопросительного знака (?) является альтернативой символу z в Verilog HDL. Он устанавливает 4 бита на высокоимпедансное значение в шестнадцатеричных числах, 3 бита в восьмеричных и 1 бит в двоичных. Знак вопроса может использоваться для улучшения читаемости в случаях, когда значение высокого импеданса является условием «не заботиться». См. обсуждение casez и casex в разделе 9.5.1. Символ вопросительного знака также используется в таблицах состояний примитивов, определяемых пользователем (UDP). См. таблицу 8-1 в разделе 8.1.6.
В десятичной константе символ беззнакового числа не должен содержать цифр x, z или ?, если только в третьей символьной последовательности, состоящий из цифр, нет ровно одной цифры, указывающей на то, что каждый бит в десятичной константе равен x или z.
Символ подчеркивания (_) может использоваться в любом месте числа, кроме первого символа. Символ подчеркивания игнорируется. Эта функция может быть использована для разбиения длинных чисел для удобства чтения.
Например:
659 // - десятичное число
'h837FF // шестнадцатеричное число
'o7460 // восьмеричное число
4af // является недопустимым (шестнадцатеричный формат требует 'h)
4'b1001 // - 4-битное двоичное число
5'D3 // - 5-битное десятичное число
3'b01x // - трехбитовое число с наименьшим значением
// значащий бит неизвестен
12'hx // это 12-битное неизвестное число
16'hz // - 16-битное высокоимпедансное число
8'd-6 // это незаконный синтаксис
-8'd6 // это определяет дополнение двойки к 6,
// хранится в 8 битах - эквивалентно -(8'd 6)
4'shf // это обозначает 4-битное число "1111", к
// интерпретируется как число с дополнением 2,
// или '-1'. Это эквивалентно -4'h 1
-4'sd15 //это эквивалентно -(-4'd 1), или '0001' 16'sd?
// то же самое, что 16'sbz
reg [11:0] a, b, c, d;
initial begin
a = 'h x; // yields xxx
b = 'h 3x; // yields 03x
c = 'h z3; // yields zz3
d = 'h 0z3; // yields 0z3
end
reg [84:0] e, f, g;
e = 'h5; // yields {82{1'b0},3'b101}
f = 'hx; // yields {85{1'hx}}
g = 'hz; // yields {85{1'hz}}
27_195_000
16'b0011_0101_0001_1111
32'h12ab_f001
Размерные отрицательные и знаковые числовые константы расширяются по знаку, когда присваиваются в тип данных reg, независимо от того, знаковый ли сам reg.
Длина x и z по умолчанию такая же, как длина целого числа по умолчанию.
3.5.2 Вещественные константы
Вещественные числовые константы должны быть представлены в соответствии со стандартом IEEE Std 754-1985, стандартом IEEE для чисел двойной точности с плавающей точкой. Вещественные числа могут быть заданы как в десятичной системе счисления (например, 14,72), так и в научной системе счисления (например, 39e8, что означает 39, умноженное на 10 в восьмой степени). Вещественные числа, выраженные с десятичной точкой, должны иметь по крайней мере по одной цифре с каждой стороны десятичной точки.
1.2
0.1
2394.26331
1.2E12
1.30e-2
0.1e-0
23E10
29E-2
236.123_763_e-12
.12
9.
4.E3
.2e-7
3.5.3 Преобразование
Вещественные числа должны преобразовываться в целые числа путем округления вещественного числа до ближайшего целого числа, а не путем его усечения. Неявное преобразование должно происходить, когда вещественное число присваивается целому числу. Связки округляются от нуля. Например:
- Действительные числа 35,7 и 35,5 при преобразовании в целое число становятся 36, а 35,2 в 35.
- Преобразование -1,5 в целое число дает -2, преобразование 1,5 в целое число дает 2.
3.6 Строки
Строка — это последовательность символов, заключенная в двойные кавычки («») и содержащаяся в одной строке. Строки, используемые в качестве операндов в выражениях и присваиваниях, должны рассматриваться как беззнаковые целочисленные константы, представленные последовательностью 8-битных значений ASCII, причем одно 8-битное значение ASCII представляет один символ.
3.6.1 Объявление строковой переменной
Строковые переменные — это переменные типа reg (см. 4.2) с шириной, равной количеству символов в строке, умноженному на 8.
Например:
reg [8*12:1] stringvar;
initial begin
stringvar = "Hello world!";
end
3.6.2 Работа со строками
Строками можно манипулировать с помощью операторов Verilog HDL. Значение, которым манипулирует оператор, представляет собой последовательность 8-битных значений ASCII.
module string_test;
reg [8*14:1] stringvar;
initial begin
stringvar = "Hello world";
$display("%s is stored as %h", stringvar,stringvar);
stringvar = {stringvar,"!!!"};
$display("%s is stored as %h", stringvar,stringvar);
end
endmodule
Hello world хранится как 00000048656c6c6f20776f726c64
Hello world!!! хранится как 48656c6c6f20776f726c64212121
Если переменная больше, чем требуется для хранения присваиваемого строкового значения, значение выравнивается вправо, а крайние левые биты заполняются нулями, как это делается для нестроковых значений. Если размер строки больше, чем размер целевой строковой переменной, строка выравнивается вправо, а крайние левые символы усекаются.
3.6.3 Специальные символы в строках
Некоторые символы могут использоваться в строках только в том случае, если им предшествует вводный символ, называемый экранирующим символом. В таблице 3-1 эти символы перечислены в правом столбце, а в левом столбце — последовательность экранирующих символов, которая представляет этот символ.
Спец. Символы | Символ, создаваемый управляющей строкой |
---|---|
\n | Newline character |
\t | Tab character |
\\ | \ character |
\» | » character |
\ddd | A character specified in 1–3 octal digits (0 ≤ d ≤ 7). If less than three characters are used, the following character shall not be an octal digit. |
3.7 Идентификаторы, ключевые слова и системные имена
Идентификатор используется для присвоения объекту уникального имени, чтобы на него можно было ссылаться. Идентификатор — это либо простой идентификатор, либо экранированный идентификатор (см. 3.7.1). Простой идентификатор представляет собой любую последовательность букв, цифр, знаков доллара ($) и подчеркивания (_).
Первый символ простого идентификатора не должен быть цифрой или $. Это может быть буква или знак подчеркивания. Идентификаторы должны быть чувствительны к регистру.
shiftreg_a
busa_index
error_condition
merge_ab
_bus3
n$657
Реализации могут устанавливать ограничение на максимальную длину идентификаторов, но это ограничение должно быть не менее 1024 символов. Если идентификатор превышает установленный реализацией предел длины, сообщается об ошибке.
3.7.1 Экранированные идентификаторы
Экранированные идентификаторы должны начинаться с символа обратной косой черты (\ и заканчиваться белым пробелом (пробел, табуляция, новая строка). Они позволяют включить в идентификатор любой из печатаемых символов ASCII (десятичные значения от 33 до 126, или от 21 до 7E в шестнадцатеричной системе).
Ни ведущий символ обратной косой черты, ни завершающий пробел не считаются частью идентификатора. Таким образом, экранированный идентификатор \cpu3 рассматривается так же, как и неэкранированный идентификатор cpu3.
\busa+index
\-clock
\***error-condition***
\net1/\net2
\{a,b}
\a*(b+c)
3.7.2 Ключевые слова
Ключевые слова — это предопределенные идентификаторы без кодировки, которые используются для определения конструкций языка. Ключевое слово Verilog HDL, которому предшествует управляющий символ, не интерпретируется как ключевое слово.
Все ключевые слова задаются только в нижнем регистре.
3.7.3 Задачи и функции системы
Знак доллара ($) представляет языковую конструкцию, которая позволяет разрабатывать определяемые пользователем системные задачи и функции. Системные конструкции не являются семантикой проектирования, а относятся к функциональности симулятора. Имя, следующее за $, интерпретируется как системная задача или системная функция.
system_task_enable ::=
system_task_identifier [ ( [ expression ] { , [ expression ] } ) ] ;
system_function_call ::=
system_function_identifier [ ( expression { , expression } ) ]
system_function_identifiera ::=
$[ a-zA-Z0-9_$ ]{ [ a-zA-Z0-9_$ ] }
system_task_identifiera ::=
$[ a-zA-Z0-9_$ ]{ [ a-zA-Z0-9_$ ] }
За знаком доллара ($) в идентификаторе функции системы или идентификаторе задачи системы не должен следовать пробел. Идентификатор функции системы или идентификатор задачи системы не должен экранироваться.
system_task_enable ::=
system_task_identifier [ ( [ expression ] { , [ expression ] } ) ] ;
system_function_call ::=
system_function_identifier [ ( expression { , expression } ) ]
system_function_identifiera::=
$[ a-zA-Z0-9_$ ]{ [ a-zA-Z0-9_$ ] }
system_task_identifiera
::=
$[ a-zA-Z0-9_$ ]{ [ a-zA-Z0-9_$ ] }
Задача/функция системы $identifier может быть определена в трех местах:
- Стандартный набор задач и функций системы $identifier, как определено в п. 17 и п. 18.
- Дополнительные задачи и функции системы $identifier, определенные с помощью PLI, как описано в п. 20.
- Дополнительные задачи и функции системы $identifier, определяемые программными реализациями.
В качестве имени системной задачи/функции может использоваться любой допустимый идентификатор, включая ключевые слова, уже используемые в контекстах, отличных от данной конструкции. Системные задачи и функции, описанные в п. 17 и п. 18, являются частью настоящего стандарта. Дополнительные системные задачи и функции с конструкцией $identifier не являются частью настоящего стандарта.
$display("display a message");
$finish;
3.7.4 Директивы компилятора
Символ ` (значение ASCII 0x60, называемое grave accent) представляет собой языковую конструкцию, используемую для реализации директив компилятора. Поведение компилятора, продиктованное директивой компилятора, вступает в силу, как только компилятор прочитает эту директиву. Директива остается в силе до конца компиляции, если в другой директиве компилятора не указано иное. Поэтому директива компилятора в одном файле описания может управлять поведением компилятора в нескольких файлах описания.
Директива компилятора `identifier может быть определена в двух местах:
- Стандартный набор директив компилятора `identifier, определенный в п. 19.
- Дополнительные директивы компилятора `identifier, определяемые программными реализациями.
В качестве имени директивы компилятора можно использовать любой допустимый идентификатор, включая ключевые слова, уже используемые в контекстах, отличных от данной конструкции.
Директивы компилятора, описанные в п. 19, являются частью настоящего стандарта. Дополнительные директивы компилятора с конструкцией `identifier не являются частью настоящего стандарта.
`define wordsize 8
3.8 Атрибуты
С распространением инструментов, помимо симуляторов, которые используют Verilog HDL в качестве источника, предусмотрен механизм для указания свойств объектов, утверждений и групп утверждений в источнике HDL, которые могут использоваться различными инструментами, включая симуляторы, для управления работой или поведением инструмента. Эти свойства будут называться атрибутами. Этот подпункт определяет синтаксический механизм, который должен использоваться для указания атрибутов, без стандартизации каких-либо конкретных атрибутов.
Синтаксис для указания атрибута показан в Синтаксис 3-3.
attribute_instance ::=
(* attr_spec { , attr_spec } *)
attr_spec ::=
attr_name [ = constant_expression ]
attr_name ::=
identifier
Attribute_instance может появиться в описании Verilog как префикс, прикрепленный к объявлению, элементу модуля, оператору или соединению порта. Он может появиться как суффикс к оператору или имени функции Verilog в выражении.
Если атрибуту не присвоено конкретное значение, то его значение должно быть равно 1. Если одно и то же имя атрибута определено более одного раза для одного и того же языкового элемента, то должно использоваться последнее значение атрибута, а инструмент может выдать предупреждение о том, что произошло дублирование спецификации атрибута.
Вложенность экземпляров атрибутов запрещена. Запрещается указывать значение атрибута с помощью константного выражения, содержащего экземпляр атрибута.
3.8.1 Примеры
(* full_case, parallel_case *)
case (foo)
<rest_of_case_statement>
(* full_case=1 *)
(* parallel_case=1 *) // Множественные экземпляры атрибутов также OK
case (foo)
<rest_of_case_statement>
//или
(* full_case, // Значение не присвоено
parallel_case=1 *)
case (foo)
<rest_of_case_statement>
(* full_case *) // parallel_case not specified
case (foo)
<rest_of_case_statement>
//или
(* full_case=1, parallel_case = 0 *)
case (foo)
<rest_of_case_statement>
(* optimize_power *)
module mod1 (<port_list>);
//или
(* optimize_power=1 *)
module mod1 (<port_list>);
(* optimize_power=0 *)
mod1 synth1 (<port_list>);
(* fsm_state *) reg [7:0] state1;
(* fsm_state=1 *) reg [3:0] state2, state3;
reg [3:0] reg1; // у этого reg НЕ установлен fsm_state
(* fsm_state=0 *) reg [3:0] reg2; // и у этого тоже
a = b + (* mode = "cla" *) c;
Это устанавливает значение атрибута mode как строку cla.
a = add (\* mode = "cla" \*) (b, c);
a = b ? (\* no_glitch \*) c : d;
3.8.2 Синтаксис
Синтаксис для разрешенных утверждений с атрибутами показан в Синтаксисе 3-4 — Синтаксисе 3-9. Синтаксис атрибутов объявления модуля приведен в Синтаксисе 3-4.
module_declaration ::=
{ attribute_instance } module_keyword module_identifier
[ module_parameter_port_list ] list_of_ports ;
{ module_item }
endmodule
| { attribute_instance } module_keyword module_identifier
[ module_parameter_port_list ] [ list_of_port_declarations ] ;
{ non_port_module_item }
endmodule
Синтаксис атрибутов объявления порта приведен в разделе Синтаксис 3-5.
port_declaration ::=
{attribute_instance} inout_declaration
| {attribute_instance} input_declaration
| {attribute_instance} output_declaration
Синтаксис для атрибутов элементов модуля приведен в Синтаксисе 3-6
module_item ::=
port_declaration ;
| non_port_module_item
module_or_generate_item ::=
{ attribute_instance } module_or_generate_item_declaration
| { attribute_instance } local_parameter_declaration ;
| { attribute_instance } parameter_override
| { attribute_instance } continuous_assign
| { attribute_instance } gate_instantiation
| { attribute_instance } udp_instantiation
| { attribute_instance } module_instantiation
| { attribute_instance } initial_construct
| { attribute_instance } always_construct
| { attribute_instance } loop_generate_construct
| { attribute_instance } conditional_generate_construct
non_port_module_item ::=
module_or_generate_item
| generate_region
| specify_block
| { attribute_instance } parameter_declaration ;
Синтаксис для атрибутов порта функции, задачи и блока приведен в Синтаксисе 3-7.
function_port_list ::=
{attribute_instance} input_declaration { , {attribute_instance } input_declaration}
task_item_declaration ::=
block_item_declaration
| { attribute_instance } input_declaration ;
| { attribute_instance } output_declaration ;
| { attribute_instance } inout_declaration ;
task_port_item ::=
{ attribute_instance } input_declaration
| { attribute_instance } output_declaration
| { attribute_instance } inout_declaration
block_item_declaration ::=
{ attribute_instance } reg [ signed ] [ range ] list_of_block_variable_identifiers ;
| { attribute_instance } integer list_of_block_variable_identifiers ;
| { attribute_instance } time list_of_block_variable_identifiers ;
| { attribute_instance } real list_of_block_real_identifiers ;
| { attribute_instance } realtime list_of_block_real_identifiers ;
| { attribute_instance } event_declaration
| { attribute_instance } local_parameter_declaration ;
| { attribute_instance } parameter_declaration ;
Синтаксис для атрибутов подключения к порту приведен в Синтаксисе 3-8.
ordered_port_connection ::= (From A.4.1)
{ attribute_instance } [ expression ]
named_port_connection ::=
{ attribute_instance } . port_identifier ( [ expression ] )
Синтаксис для атрибутов udp приведен в Синтаксисе 3-9.
udp_declaration ::=
{ attribute_instance } primitive udp_identifier ( udp_port_list ) ;
udp_port_declaration { udp_port_declaration }
udp_body
endprimitive
| { attribute_instance } primitive udp_identifier ( udp_declaration_port_list ) ;
udp_body
endprimitive
udp_output_declaration ::=
{ attribute_instance } output port_identifier
| { attribute_instance } output reg port_identifier [ = constant_expression ]
udp_input_declaration ::=
{ attribute_instance } input list_of_port_identifiers
udp_reg_declaration ::=
{ attribute_instance } reg variable_identifier