Включить охранников в SystemVerilog - PullRequest
1 голос
/ 21 февраля 2020

У меня есть заголовочный файл verilog, включенный в include guard. Он содержит некоторые функции, которые я использую для определения локальных параметров в других файлах RTL. Этот включаемый файл упоминается в описании модуля (модуль (создание порта) `include .... (body) endmodule). Я всегда думал, что когда verilog компилирует каждый модуль, область этого включения будет локальной для этого модуля, и это будет только обеспечивать защиту внутри модуля. Сейчас я собираю все модули в проекте, и похоже, что во второй раз ссылка на включение указана в другом модуле, на котором все еще включена защита. Это как-то связано с поведением препроцессора для systemverilog?

Ответы [ 3 ]

2 голосов
/ 21 февраля 2020

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

av

`include "h.vh"
`define A_V 1

bv

`include "h.vh"
...
assign A = `A_V;

Итак, макрос A_V доступен в файле bv, если вы скомпилируете их в следующем порядке: a.v, b.v.

В результате, если h.vh использует защитные макросы, он будет проанализирован только как включенный в AV и будет охраняться в BV и не анализируется.

Теперь предположим, что вы содержите определения параметров функций в h.vh:

`ifndef H_VH
`defien H_VH
paremeter I = 10;
`endif

и получите включение в тело модуля:

av

module A;
`include "h.vh"
assign A = I;
endmodule

bv

module B;
`include "h.vh"
assign B = I;
endmodule

Теперь, когда файл сначала включается в модуль A, параметр теперь определяется внутри модуля A. Но макрос H_VH также определен. Включаемый файл не будет проанализирован во второй раз в файле 'bv'. Таким образом, включение его в модуль не расширится до определения параметра, и компиляция не удастся, поскольку I недоступно.

Защитные макросы в verilog полезны, если файл включен в глобальную область за пределами модулей. Они создают много проблем, если включены в области видимости. Правило большого пальца состоит в том, чтобы использовать их для глобально включенных заголовков и никогда не использовать их, если заголовок включен в область действия. Никогда не смешивайте глобальные и объемные включения.

И да, как все уже упоминали, в системном Verilog лучше использовать пакеты для этого. В обычном verilog у вас нет другого выбора для определения общих деклараций.

1 голос
/ 21 февраля 2020

На самом деле вам не нужны средства компиляции в SystemVerilog. При правильном использовании пакетов ваши скрипты компиляции должны компилировать все в правильном порядке. Единственным исключением может быть включение текстовых макросов.

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

compile file1 file2

В режиме компиляции одного файла, это то же самое, что если вы ввели

compile file1
compile file2

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

В режиме многофайловой компиляции любые `define s в файле1 переносятся в файл2. Так что порядок файлов имеет значение.

0 голосов
/ 21 февраля 2020

Когда вы говорите охранник, я предполагаю, что вы имеете в виду что-то вроде:

`ifndef MY_GUARD
`define MY_GUARD
// ... definitions for parameters, functions, etc. ...
`endif // MY_GUARD

`ifdef, `ifndef, `define и другие связанные ` операции зависят от порядка компиляции , Определения макросов существуют в глобальном пространстве с момента их определения до тех пор, пока они не будут определены. В приведенном выше примере после определения MY_GUARD любой `ifndef MY_GUARD будет оцениваться как ложный, пока он не будет определен (`undef MY_GUARD).

Если вы хотите включить один и тот же файл в несколько модулей, удалите охранники.


Поскольку вы используете SystemVerilog. Попробуйте поместить общий код в пакет, а затем импортировать его в каждый модуль.

...