19. Директивы компилятора Verilog HDL

Содержание

Всем директивам компилятора Verilog предшествует символ (`). Этот символ называется grave accent (ASCII 0x60). Он отличается от символа (), который является символом апострофа (ASCII 0x27). Область действия директивы компилятора распространяется с момента ее обработки на все обрабатываемые файлы до момента, когда другая директива компилятора заменяет ее или обработка завершается.

В этом пункте описаны следующие директивы компилятора:

19.1. `celldefine и `endcelldefine

Директивы `celldefine и `endcelldefine помечают модули как модули ячеек. Ячейки используются некоторыми процедурами PLI для приложений, таких как расчет задержек. Рекомендуется сопровождать каждую `celldefine директивой `endcelldefine, но это не обязательно. Последнее появление любой из этих директив в источнике определяет, будут ли модули помечены как модули ячеек. В одном описании источника может встречаться более одной из этих пар.

Эти директивы могут появиться в любом месте описания исходного текста, но рекомендуется, чтобы директивы были указаны вне определения модуля.

Директива `resetall включает эффекты директивы `endcelldefine.

19.2. `default_nettype

Директива `default_nettype управляет типом сети, создаваемым для неявных объявлений сетей (см. 4.5). Она может использоваться только вне определений модулей. Допускается использование нескольких директив `default_nettype. Последнее появление этой директивы в исходном тексте определяет тип сетей, которые будут неявно объявлены. Синтаксис 19-1 содержит синтаксис директивы.

Если директива `default_nettype отсутствует или если указана директива `resetall, неявные сети имеют тип wire. Когда `default_nettype установлен в none, все сети должны быть явно объявлены. Если сеть не объявлена явно, генерируется ошибка.

default_nettype_compiler_directive ::= `default_nettype default_nettype_value default_nettype_value ::= wire | tri | tri0 | tri1 | wand | triand | wor | trior | trireg | uwire | none
Синтаксис 19-1 — Синтаксис для директивы компилятора default_nettype

19.3. `define и `undef

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

На возможности текстового макроса не влияет директива компилятора `resetall.

19.3.1. `define

Директива `define создает макрос для подстановки текста. Эта директива может использоваться как внутри, так и вне определений модулей. После того, как текстовый макрос определен, его можно использовать в описании исходного текста с помощью символа (`), за которым следует имя макроса. Компилятор заменит текст макроса на строку `текстимямакроса` и любые фактические аргументы, которые следуют за ним. Все директивы компилятора считаются предопределенными именами макросов. Переопределение директивы компилятора как имени макроса является незаконным.

Текстовый макрос может быть задан с аргументами. Это позволяет настраивать макрос для каждого использования индивидуально.

Синтаксис текстовых макроопределений приведен в Синтаксисе 19-2.

text_macro_definition ::= `define text_macro_name macro_text text_macro_name ::= text_macro_identifier [ ( list_of_formal_arguments ) ] list_of_formal_arguments ::= formal_argument_identifier { , formal_argument_identifier } formal_argument_identifier ::= simple_identifier text_macro_identifier ::= identifier
Синтаксис 19-2 — Синтаксис для определения текстового макроса

Текст макроса может быть любым произвольным текстом, указанным в той же строке, что и имя текстового макроса. Если для указания текста требуется более одной строки, то перед новой строкой должен стоять обратный слеш (\). Первая новая строка, не предваряемая обратной косой чертой, должна завершать текст макроса. Новая строка, которой предшествует обратная косая черта, заменяется в расширенном макросе новой строкой (но без предшествующего символа обратной косой черты).

Когда формальные аргументы используются для определения текстового макроса, область видимости формального аргумента должна простираться до конца текста макроса. Формальный аргумент может использоваться в тексте макроса так же, как и идентификатор.

Если используются формальные аргументы, список имен формальных аргументов должен быть заключен в круглые скобки после имени макроса. Имена формальных аргументов должны быть простыми_идентификаторами, разделенными запятыми и, по желанию, пробелами. Левая скобка должна следовать сразу за именем текстового макроса, без пробела между ними.

Если в текст включен однострочный комментарий (то есть комментарий, заданный символами //), то комментарий не становится частью заменяемого текста. Текст макроса может быть пустым, в этом случае текстовый макрос определяется как пустой и при использовании макроса текст не подставляется.

Синтаксис для использования текстового макроса приведен в Синтаксис 19-3.

text_macro_usage ::= `text_macro_identifier [ ( list_of_actual_arguments ) ] list_of_actual_arguments ::= actual_argument { , actual_argument } actual_argument ::= expression
Синтаксис 19-3 — Синтаксис для использования текстового макроса

Для макроса без аргументов, текст заменяется как есть для каждого вхождения `имятекстовогомакроса`. Однако, текстовый макрос с одним или несколькими аргументами должен быть расширен путем замены каждого формального аргумента выражением, используемым в качестве фактического аргумента при использовании макроса.

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

После определения имени текстового макроса его можно использовать в любом месте описания источника. То есть, ограничений по области видимости нет. Текстовые макросы можно определять и использовать интерактивно.

Текст, указанный для макротекста, не должен разбиваться на следующие лексические единицы:

  • Комментарии
  • Номера
  • Строки
  • Идентификаторы
  • Ключевые слова
  • Операторы

Например:

`define wordsize 8 reg [1:`wordsize] data; //define a nand with variable delay `define var_nand(dly) nand #dly `var_nand(2) g121 (q21, n10, n11); `var_nand(5) g122 (q22, n10, n11);
Приведенный ниже синтаксис является незаконным, так как он разделяет строку:
`define first_half "start of string $display(`first_half end of string");
Каждый фактический аргумент заменяется на соответствующий формальный аргумент буквально. Поэтому, когда выражение используется в качестве фактического аргумента, оно заменяется полностью. Это может привести к тому, что выражение будет оценено более одного раза, если формальный аргумент был использован в тексте макроса более одного раза. Например:
`define max(a,b)((a) > (b) ? (a) : (b)) n = `max(p+q, r+s);
будет расширяться по мере
n = ((p+q) > (r+s)) ? (p+q) : (r+s);

Здесь большее из двух выражений p + q и r + s будет вычислено дважды.

Слово define известно как ключевое слово директивы компилятора, и оно не входит в обычный набор ключевых слов. Таким образом, обычные идентификаторы в исходном описании Verilog HDL могут совпадать с ключевыми словами директив компилятора (хотя это не рекомендуется). Следует обратить внимание на следующие проблемы:

1) Имена текстовых макросов могут не совпадать с ключевыми словами директив компилятора.

2) Имена текстовых макросов могут повторно использовать имена, используемые в качестве обычных идентификаторов. Например, `name_signal и `signal_name отличаются.

3) Переопределение текстовых макросов разрешено. Последнее определение конкретного текстового макроса, прочитанное компилятором, превалирует, когда имя макроса встречается в исходном тексте.

Текст макроса может содержать использования других текстовых макросов. Такие употребления подставляются после подстановки исходного макроса, а не при его определении. Ошибкой является прямое или косвенное расширение макроса на текст, содержащий другое использование самого макроса (рекурсивный макрос).

19.3.2. `undef

Директива `undef не должна определять ранее определенный текстовый макрос. Попытка неопределения текстового макроса, который не был ранее определен с помощью директивы компилятора `define, может привести к предупреждению. Синтаксис для директивы компилятора `undef приведена в синтаксисе 19-4.

undefine_compiler_directive ::= `undef text_macro_identifier
Синтаксис 19-4 — Синтаксис для директивы компилятора undef

Неопределенный текстовый макрос не имеет никакого значения, как если бы он никогда не был определен.

19.4. `ifdef, `else, `elsif, `endif, `ifndef

Эти директивы компилятора условной компиляции используются для включения необязательных строк исходного описания Verilog HDL во время компиляции. Директива компилятора `ifdef проверяет определение имени макроса text_macro_name. Если имя text_macro_name определено, то строки, следующие за директивой `ifdef, включаются. Если text_macro_name не определено и существует директива `else, то исходный текст компилируется. Директива `ifndef компилятора проверяет определение имени text_macro_name. Если text_macro_name не определено, то включаются строки, следующие за директивой `ifndef. Если имя text_macro_name определено и существует директива `else, то этот исходный текст компилируется.

Если директива `elsif существует (вместо `else), компилятор проверяет определение имени text_macro_name. Если имя существует, то включаются строки, следующие за директивой `elsif. Директива `elsif эквивалентна последовательности директив компилятора `else `ifdef`endif. Эта директива не нуждается в соответствующей директиве `endif. Этой директиве должна предшествовать директива `ifdef или `ifndef.

Эти директивы могут появляться в любом месте описания источника.

Ситуации, в которых директивы компилятора `ifdef, `else, `elsif, `endif и `ifndef могут быть полезны, включают следующие:

  • Выбор различных представлений модуля, таких как поведенческий, структурный или уровень переключателей
  • Выбор различной временной или структурной информации
  • Выбор различных стимулов для данного запуска

Директивы компилятора `ifdef, `else, `elsif, `endif и `ifndef имеют синтаксис, показанный в Синтаксисе 19-5.

conditional_compilation_directive ::= ifdef_directive | ifndef_directive ifdef_directive ::= `ifdef text_macro_identifier ifdef_group_of_lines { `elsif text_macro_identifier elsif_group_of_lines } [ `else else_group_of_lines ] `endif ifndef_directive ::= `ifndef text_macro_identifier ifndef_group_of_lines { `elsif text_macro_identifier elsif_group_of_lines } [ `else else_group_of_lines ] `endif
Синтаксис 19-5 — Синтаксис для директив условной компиляции

Идентификатор text_macro_identifier — это идентификатор Verilog HDL. Группы строк ifdef_group_of_lines, ifndef_group_of_lines, elsif_group_of_lines и else_group_of_lines являются частями исходного описания Verilog HDL. Директивы компилятора `else и `elsif и все группы строк являются необязательными.

Директивы компилятора `ifdef, `else, `elsif и `endif работают вместе следующим образом:

  • Когда встречается `ifdef, идентификатор текстового макроса `ifdef проверяется на то, определен ли он как имя текстового макроса с помощью `define в исходном описании Verilog HDL.
  • Если определен текстовый макроидентификатор `ifdef, то группа строк `ifdef компилируется как часть описания. Если же имеются директивы компилятора `else или `elsif, то эти директивы компилятора и соответствующие группы строк игнорируются.
  • Если текстовый макроидентификатор `ifdef не был определен, группа строк `ifdef игнорируется.
  • Если есть директива компилятора `elsif, идентификатор текстового макроса `elsif проверяется на то, определен ли он как имя текстового макроса с помощью `define в исходном описании Verilog HDL.
  • Если определен текстовый макроидентификатор `elsif, то группа строк `elsif компилируется как часть описания. Если же имеются другие директивы компилятора `elsif или `else, то другие директивы `elsif или `else и соответствующие группы строк игнорируются.
  • Если первый текстовый макроидентификатор `elsif не был определен, первая группа строк `elsif игнорируется.
  • Если имеется несколько директив компилятора `elsif, они оцениваются как первая директива компилятора `elsif в порядке их записи в исходном описании Verilog HDL.
  • Если есть директива компилятора `else, то группа строк `else компилируется как часть описания.

Директивы компилятора `ifndef, `else, `elsif и `endif работают вместе следующим образом:

  • Когда встречается `ifndef, идентификатор текстового макроса `ifndef проверяется на то, определен ли он как имя текстового макроса с помощью `define в исходном описании Verilog HDL.
  • Если текстовый макроидентификатор `ifndef не определен, то группа строк `ifndef компилируется как часть описания. Если же имеются директивы компилятора `else или `elsif, то эти директивы компилятора и соответствующие группы строк игнорируются.
  • Если определен текстовый макроидентификатор `ifndef, то группа строк `ifndef игнорируется.
  • Если есть директива компилятора `elsif, идентификатор текстового макроса `elsif проверяется на то, определен ли он как имя текстового макроса с помощью `define в исходном описании Verilog HDL.
  • Если определен текстовый макроидентификатор `elsif, то группа строк `elsif компилируется как часть описания. Если же имеются другие директивы компилятора `elsif или `else, то другие директивы `elsif или `else и соответствующие группы строк игнорируются.
  • Если первый текстовый макроидентификатор `elsif не был определен, первая группа строк `elsif игнорируется.
  • Если имеется несколько директив компилятора `elsif, они оцениваются как первая директива компилятора `elsif в том порядке, в котором они записаны в исходном описании Verilog HDL.
  • Если есть директива компилятора `else, то группа строк `else компилируется как часть описания.

Хотя имена директив компилятора содержатся в том же пространстве имен, что и имена текстовых макросов, считается, что имена директив компилятора не определены `ifdef, `ifndef и `elseif.

Разрешается вложение директив компилятора `ifdef, `ifndef, `else, `elsif и `endif.

Любая группа строк, которую компилятор игнорирует, все равно должна соответствовать лексическим соглашениям(синтаксису) Verilog HDL для пробелов, комментариев, чисел, строк, идентификаторов, ключевых слов и операторов.

Например:

Пример 1 — Приведенный ниже пример показывает простое использование директивы `ifdef для условной компиляции. Если определен идентификатор behavioral, то будет скомпилировано непрерывное назначение сети, в противном случае будет объявлен экземпляр вентиля and.
module and_op (a, b, c); output a; input b, c; `ifdef behavioral wire a = b & c; `else and a1 (a,b,c); `endif endmodule
Пример 2 — В следующем примере показано использование вложенной директивы условной компиляции:
module test(out); output out; `define wow `define nest_one `define second_nest `define nest_two `ifdef wow initial $display("wow is defined"); `ifdef nest_one initial $display("nest_one is defined"); `ifdef nest_two initial $display("nest_two is defined"); `else initial $display("nest_two is not defined"); `endif `else initial $display("nest_one is not defined"); `endif `else initial $display("wow is not defined"); `ifdef second_nest initial $display("second_nest is defined"); `else initial $display("second_nest is not defined"); `endif `endif endmodule
Пример 3 — В следующем примере показано использование вложенных друг в друга директив условной компиляции:
module test; `ifdef first_block `ifndef second_nest initial $display("first_block is defined"); `else initial $display("first_block and second_nest defined"); `endif `elsif second_block initial $display("second_block defined, first_block is not"); `else `ifndef last_result initial $display("first_block, second_block," last_result not defined."); `elsif real_last initial $display("first_block, second_block not defined," last_result and real_last defined."); `else initial $display("Only last_result defined!"); `endif `endif endmodule

19.5. `include

Директива включения файлов (`include) компилятора используется для вставки всего содержимого исходного файла в другой файл во время компиляции. В результате содержимое включенного исходного файла появляется вместо файла директивы компилятора `include. Директива компилятора `include может быть использована для включения глобальных или часто используемых определений и задач без инкапсуляции повторяющегося кода в границы модуля.

Преимущества использования директивы компилятора `include включают следующее:

  • Обеспечение неотъемлемой части управления конфигурацией
  • Улучшение организации исходных описаний Verilog HDL
  • Облегчение сопровождения исходных описаний Verilog HDL

Синтаксис директивы компилятора `include приведен в синтаксисе 19-6.

include_compiler_directive ::= `include "filename"
Синтаксис 19-6 — Синтаксис для директивы компилятора include

Директива компилятора `include может быть указана в любом месте описания Verilog HDL.

filename — это имя файла, который должен быть включен в исходный файл. Имя файла может быть полным или относительным именем пути.

В одной строке с директивой компилятора `include может находиться только пробел, пропуск, табуляция или комментарий.

Файл, включенный в исходный текст с помощью директивы компилятора `include, может содержать другие директивы компилятора `include. Количество уровней вложенности для включаемых файлов должно быть конечным.

Например:

Ниже приведены примеры директив компилятора `include:
`include "parts/count.v" `include "fileB" `include "fileB" // включенный fileB

Реализации могут ограничивать максимальное количество уровней, на которых могут быть вложены включаемые файлы, но это ограничение должно быть не менее 15.

19.6. `resetall

Когда во время компиляции встречается директива компилятора `resetall, все директивы компилятора устанавливаются в значения по умолчанию. Это полезно для обеспечения того, чтобы активными были только те директивы, которые необходимы при компиляции конкретного исходного файла.

Рекомендуется использовать `resetall в начале каждого исходного текстового файла, за которым сразу следуют желаемые директивы в файле.

Указание директивы `resetall в объявлении модуля или UDP является незаконным.

19.7. `line

Для инструментов Verilog важно отслеживать имена файлов исходных текстов Verilog и номера строк в этих файлах. Эта информация может использоваться для сообщений об ошибках или отладки исходного кода и может быть доступна в Verilog PLI.

Однако во многих случаях исходный текст Verilog подвергается предварительной обработке другим инструментом, и информация о строках и файлах исходного файла может быть потеряна, поскольку препроцессор может добавить дополнительные строки в файл исходного кода, объединить несколько строк исходного кода в одну строку, скомпоновать несколько исходных файлов и так далее.

Директива компилятора `line может быть использована для указания номера строки исходного кода и имени файла. Это позволяет сохранить местоположение исходного файла, если другой процесс изменит исходный текст. После указания номера новой строки и имени файла компилятор может корректно ссылаться на местоположение исходного кода. Однако для создания директив `line инструмент не требуется. Эти директивы не предназначены для вставки в код вручную, хотя и могут быть вставлены.

Компилятор должен сохранять текущий номер строки и имя файла компилируемого файла. Директива `line должна установить номер строки и имя файла следующей строки на те, которые указаны в директиве. Директива может быть указана в любом месте исходного описания Verilog HDL. Однако на одной строке с директивой `line может находиться только пробел, пропуск и табуляция. Комментарии не допускаются на той же строке, что и директива `line. Все параметры в директиве `line являются обязательными. На результаты этой директивы не влияет директива `resetall.

Синтаксис директивы компилятора `line приведен в Синтаксис 19-7.

line_compiler_directive ::= `line number "filename" level
Синтаксис 19-7 — Синтаксис для директивы компилятора строк
  • number — параметр, который должен быть положительным целым числом, задающим номер новой строки следующего текста.
  • filename — параметр, который должен быть строковой константой, которая рассматривается как новое имя файла. Имя файла также может быть полным или относительным именем пути.
  • level — параметр, который должен быть равен 0, 1 или 2. Значение 1 указывает на то, что следующая строка является первой строкой после ввода включаемого файла. Значение 2 указывает на то, что следующая строка является первой строкой после выхода из включаемого файла. Значение 0 указывает на любую другую строку.
Например:
`line 3 "orig.v" 2 // Эта строка является строкой 3 файла orig.v после выхода из включаемого файла

Когда компилятор обрабатывает оставшуюся часть файла и новые файлы, номер строки увеличивается по мере чтения каждой строки, а имя обновляется до нового текущего обрабатываемого файла. В начале каждого файла номер строки должен быть сброшен на 1. Когда начинается чтение включаемых файлов, текущая строка и имя файла сохраняются для восстановления при завершении включаемого файла. Обновленная информация о номере строки и имени файла должна быть доступна для доступа к PLI. На механизм поиска в библиотеке не влияет действие директивы компилятора `line.

19.8. `timescale

Эта директива определяет единицу времени и точность времени для следующих за ней модулей. Единица времени — это единица измерения для таких временных величин, как время моделирования и величина задержки.

Для использования модулей с разными единицами времени в одном проекте полезны следующие конструкции временных шкал:

  • Директива компилятора `timescale для указания единицы измерения времени и точности времени в модулях в проекте
  • Системная задача $printtimescale для отображения единицы времени и точности модуля
  • Системные функции $time и $realtime, системная задача $timeformat и спецификация формата %t для указания способа представления информации о времени.

Директива компилятора `timescale определяет единицу измерения для значений времени и задержки и степень точности для задержек во всех модулях, следующих за этой директивой, пока не будет прочитана другая директива компилятора `timescale. Если директива `timescale не указана или она была сброшена директивой `resetall, единицы измерения времени и точность зависят от симулятора. Ошибкой будет, если в некоторых модулях указана `timescale, а в других нет.

Синтаксис для директивы `timescale приведен в Синтаксис 19-8.

timescale_compiler_directive ::= `timescale time_unit / time_precision
Синтаксис 19-8 — Синтаксис для директивы компилятора шкалы времени
  • time_unit — аргумент, который задает единицу измерения времени и задержки.
  • time_precision — аргумент, который определяет, как округляются значения задержки перед использованием в моделировании. Используемые значения точны в пределах указанной здесь единицы времени, даже если в другом месте проекта аргумент time_precision меньше. Наименьший аргумент time_precision из всех аргументов директивы компилятора `timescale в дизайне определяют точность единицы времени симуляции.

Аргумент time_precision должен быть, по крайней мере, таким же точным, как аргумент time_unit. Он не может указывать более длинную единицу времени, чем time_unit.

Целые числа в этих аргументах задают порядок величины для размера значения. Допустимыми целыми числами являются 1, 10 и 100. Символьные строки представляют единицы измерения. Допустимые символьные строки: s, ms, us, ns, ps и fs.

Единицы измерения, задаваемые этими символьными строками, приведены в таблице 19-1.

ПРИМЕЧАНИЕ: Хотя s, ms, ns, ps и fs являются обычными символами единиц СИ для секунды, миллисекунды, наносекунды, пикосекунды и фемтосекунды, из-за отсутствия греческой буквы μ (mu) в наборах кодирующих символов, «us» представляет символ единицы СИ для микросекунды, правильно ms.

Таблица 19-1 — Аргументы функции time_precision

Строка символовЕдиница измерения
sсекунды
msмиллисекунды
usмикросекунды
nsнаносекунды
psпикосекунды
fsфемтосекунды

Например:

В следующем примере показано, как используется эта директива:
`timescale 1 ns / 1 ps

Здесь все значения времени в модулях, следующих за директивой, кратны 1 ns, поскольку аргумент time_unit равен «1 ns». Задержки округляются до действительных чисел с тремя знаками после запятой или с точностью до одной тысячной наносекунды, поскольку аргумент time_precision равен «1 ps», или одной тысячной наносекунды.

Рассмотрим следующий пример:
`timescale 10 us / 100 ns

Значения времени в модулях, следующих за этой директивой, кратны 10 us, потому что аргумент time_unit равен «10 us». Задержки округляются с точностью до одной десятой микросекунды, поскольку аргумент time_precision равен «100 ns», или одной десятой микросекунды.

Следующий пример показывает директиву `timescale в контексте модуля:
`timescale 10 ns / 1 ns module test; reg set; parameter d = 1.55; initial begin #d set = 0; #d set = 1; end endmodule

Директива компилятора `timescale 10 ns / 1 ns указывает, что единицей времени для тестирования модуля является 10 нс. В результате значения времени в модуле кратны 10 нс, округленные до ближайшего 1 нс. Поэтому значение, хранящееся в параметре d, масштабируется до задержки в 16 нс. Другими словами, значение 0 присваивается набору reg при времени моделирования 16 нс (1,6 × 10 нс), а значение 1 — при времени моделирования 32 нс.

Параметр d сохраняет свое значение независимо от того, какая шкала времени действует.

Это время моделирования определяется следующим образом:

  1. Значение параметра d округляется от 1,55 до 1,6 в соответствии с точностью времени.
  2. Единица времени модуля составляет 10 нс, а точность — 1 нс. Поэтому задержка параметра d масштабируется от 1,6 до 16.
  3. Назначение 0 на reg set запланировано на время моделирования 16 нс, а назначение 1 — на время моделирования 32 нс. Значения времени не округляются при планировании назначений.

19.9. `unconnected_drive и `nounconnected_drive

Все неподключенные входные порты модуля, появляющиеся между директивами `unconnected_drive и `nounconnected_drive подтягиваются или оттягиваются вниз вместо обычного значения по умолчанию.

Директива `unconnected_drive принимает один из двух аргументов — pull1 или pull0. При указании pull1 все неподключенные входные порты автоматически подтягиваются вверх. При указании pull0 неподключенные порты подтягиваются вниз. Желательно, чтобы каждый `unconnected_drive был соединен с `nounconnected_drive, но это не обязательно. Последнее появление любой из директив в источнике управляет тем, что происходит с неподключенными портами. Эти директивы должны быть указаны парами вне объявлений модулей.

Директива `resetall включает эффекты директивы `nounconnected_drive.

19.10. `pragma

Директива `pragma — это структурированная спецификация, которая изменяет интерпретацию исходного текста Verilog. Спецификация, вводимая этой директивой, называется прагмой. Действие прагм, отличных от указанных в настоящем стандарте, определяется реализацией. Синтаксис директивы `pragma приведен в Синтаксисе 19-9.

pragma ::= `pragma pragma_name [ pragma_expression { , pragma_expression } ] pragma_name ::= simple_identifier pragma_expression ::= pragma_keyword | pragma_keyword = pragma_value | pragma_value pragma_value ::= ( pragma_expression { , pragma_expression } ) | number | string | identifier pragma_keyword ::= simple_identifier
Синтаксис 19-9 — Синтаксис для директивы компилятора pragma

Спецификация прагмы идентифицируется именем pragma_name, которое следует за директивой `pragma. За именем pragma_name следует необязательный список выражений pragma_expressions, которые определяют измененную интерпретацию, указанную именем pragma_name. Если не указано иное, директивы pragma для имен pragma_name, которые не распознаются реализацией, не влияют на интерпретацию исходного текста Verilog.

19.10.1. Стандартные прагмы

Прагмы reset и resetall должны восстановить значения по умолчанию и состояние pragma_keywords, связанных с затронутыми прагмами. Эти значения по умолчанию должны быть значениями, которые инструмент определяет до обработки любого текста Verilog. Прагма reset сбрасывает состояние для всех имен pragma_name, которые появляются как ключевые слова pragma_keywords в директиве. Прагма resetall сбрасывает состояние всех имен pragma_name, распознанных реализацией.

19.11. `begin_keywords, `end_keywords

Пара директив, `begin_keywords и `end_keywords, может быть использована для указания того, какие идентификаторы зарезервированы в качестве ключевых слов в блоке исходного кода, на основе конкретной версии IEEE Std 1364. Директивы `begin_keywords и `end_keywords определяют только набор идентификаторов, зарезервированных в качестве ключевых слов. Эти директивы не влияют на семантику, лексемы и другие аспекты языка Verilog.

Синтаксис директив `begin_keywords и `end_keywords приведен в Синтаксисе 19-10.

keywords_directive ::= `begin_keywords "version_specifier" version_specifier ::= 1364-1995 | 1364-2001 | 1364-2001-noconfig | 1364-2005 endkeywords_directive ::= `end_keywords
Синтаксис 19-10-Синтаксис для директив компилятора begin keywords и end keywords

Реализациям и другим стандартам разрешается расширять директиву `begin_keywords с помощью пользовательских спецификаторов версии. Будет ошибкой, если реализация не распознает спецификатор версии, используемый с директивой `begin_keywords.

Директивы `begin_keywords и `end_keywords могут быть указаны только вне элемента проектирования (module, primitive или config). Директива `begin_keywords влияет на весь исходный код, который следует за директивой, даже через границы файлов исходного кода, пока не встретится соответствующая директива `end_keywords.

Каждая директива `begin_keywords должна быть сопряжена с директивой `end_keywords. Пара директив определяет область исходного кода, к которой применяется указанный спецификатор версии.

Пара директив `begin_keywords…`end_keywords может быть вложенной. Каждая вложенная пара складывается таким образом, что когда встречается директива `end_keywords, реализация возвращается к использованию спецификатора version_specifier, который действовал до появления соответствующей директивы `begin_keywords.

Если директива `begin_keywords не указана, то список зарезервированных ключевых слов должен быть набором ключевых слов по умолчанию в реализации. Набор зарезервированных ключевых слов по умолчанию, используемый реализацией, зависит от реализации. Например, реализация, основанная на IEEE Std 1364-2005, скорее всего, будет использовать по умолчанию набор зарезервированных ключевых слов 1364-2005, тогда как реализация, основанная на IEEE Std 1364-2001, скорее всего, будет использовать по умолчанию набор зарезервированных ключевых слов 1364-2001. Реализации могут предоставлять другие механизмы для указания набора зарезервированных ключевых слов, которые будут использоваться по умолчанию. Одной из возможных моделей использования может быть использование опций вызова для указания набора зарезервированных ключевых слов по умолчанию. Другой возможной моделью использования может быть использование расширений имен исходных файлов для определения набора зарезервированных ключевых слов по умолчанию, который будет использоваться для каждого исходного файла.

Std 1364-1995 считаются зарезервированными словами. Эти идентификаторы перечислены в списке 19-2.

Списке 19-2 — IEEE 1364-1995 зарезервированные ключевые слова

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

Спецификатор version_specifier «1364-2001» указывает, что зарезервированными словами считаются только идентификаторы, перечисленные в IEEE Std 1364-2001 как зарезервированные ключевые слова. Эти идентификаторы перечислены в списке19-3.

Список 19-3 — IEEE 1364-2001 зарезервированные ключевые слова

always, and, assign, automatic, begin, buf, bufif0, bufif1, case, casex, casez, cell, cmos, config, deassign, default, defparam, design, disable, edge, else, end, endcase, endconfig, endfunction, endgenerate, endmodule, endprimitive, endspecify, endtable, endtask, event, for, force, forever, fork, function, generate, genvar, highz0, highz1, if, ifnone, incdir, include, initial, inout, input, instance, integer, join, large, liblist, library, localparam, macromodule, medium, module, nand, negedge, nmos, nor, noshowcancelled, not, notif0, notif1, or, output, parameter, pmos, posedge, primitive, pull0, pull1, pulldown, pullup, pulsestyle_onevent, pulsestyle_ondetect, rcmos, real, realtime, reg, release, repeat, rnmos, rpmos, rtran, rtranif0, rtranif1, scalared, showcancelled, signed, small, specify, specparam, strong0, strong1, supply0, supply1, table, task, time, tran, tranif0, tranif1, tri, tri0, tri1, triand, trior, trireg, unsigned, use, vectored, wait, wand, weak0, weak1, while, wire, wor, xnor, xor.

version_specifier «1364-2001-noconfig» ведет себя аналогично спецификатору версии «1364-2001», за исключением того, что следующие идентификаторы исключены из зарезервированного списка в таблице 19-3: cell, config, design, endconfig, incdir, include, instance, liblist, library, use.

Поскольку эти идентификаторы не зарезервированы при использовании спецификатора версии «1364-2001-noconfig», они могут использоваться как обычные идентификаторы Verilog в соответствующей области `begin_keywords…`end_ keywords.

Std 1364-2005 считаются зарезервированными словами. Эти идентификаторы перечислены в списке19-4.

Список 19-4 — IEEE 1364-2005 зарезервированные ключевые слова

always, and, assign, automatic, begin, buf, bufif0, bufif1, case, casex, casez, cell, cmos, config, deassign, default, defparam, design, disable, edge, else, end, endcase, endconfig, endfunction, endgenerate, endmodule, endprimitive, endspecify, endtable, endtask, event, for, force, forever, fork, function, generate, genvar, highz0, highz1, if, ifnone, incdir, include, initial, inout, input, instance, integer, join, large, liblist, library, localparam, macromodule, medium, module, nand, negedge, nmos, nor, noshowcancelled, not, notif0, notif1, or, output, parameter, pmos, posedge, primitive, pull0, pull1, pulldown, pullup, pulsestyle_onevent, pulsestyle_ondetect, rcmos, real, realtime, reg, release, repeat, rnmos, rpmos, rtran, rtranif0, rtranif1, scalared, showcancelled, signed, small, specify, specparam, strong0, strong1, supply0, supply1, table, task, time, tran, tranif0, tranif1, tri, tri0, tri1, triand, trior, trireg, unsigned, use, uwire, vectored, wait, wand, weak0, weak1, while, wire, wor, xnor, xor.

В примере ниже предполагается, что определение модуля m1 не содержит директивы `begin_keywords, указанной перед определением модуля. Без этой директивы набор зарезервированных ключевых слов, действующий для этого модуля, будет набором зарезервированных ключевых слов по умолчанию в реализации.
module m1; // модуль объявлен без директивы ‘begin_keywords ... endmodule
Следующий пример определяет директиву `begin_keywords «1364-2001». В исходном коде модуля в качестве имени сети используется идентификатор uwire. Директива `begin_keywords была бы необходима в этом примере, если бы реализация использовала IEEE Std 1364-2005 в качестве набора ключевых слов по умолчанию, поскольку uwire является зарезервированным ключевым словом в этом стандарте. Указание, что следует использовать списки ключевых слов Verilog «1364-1995», также подойдет для этого примера.
‘begin_keywords "1364-2001" // использует ключевые слова IEEE Std 1364-2001 Verilog module m2 (...); wire [63:0] uwire; // OK: "uwire" не является ключевым словом в 1364-2001 ... endmodule ‘end_keywords
Следующий пример представляет собой тот же код, что и предыдущий, за исключением того, что в нем явно указано, что следует использовать ключевые слова IEEE Std 1364-2005 Verilog. Этот пример приведет к ошибке, так как uwire зарезервировано как ключевое слово в этом стандарте.
‘begin_keywords "1364-2005" // использует ключевые слова IEEE Std 1364-2005 Verilog module m2 (...); wire [63:0] uwire; // ОШИБКА: "uwire" являетcя ключевым словом в 1364-2005 ... endmodule ‘end_keywords