Как передать значение переменной в макрос в SystemVerilog?

Я думаю, что вопрос довольно хорошо подводит итог тому, что я хочу: передать значение переменной в макрос в SystemVerilog.

Например, что я хочу: Скажем, есть 4 сигнала по имени abc_X_def и я хочу их все инициализировать в 0. Итак, без макросов:

abc_0_def = 4'b0000;
abc_1_def = 4'b0000;
abc
`define set_value(bit) abc_``bit``_def = 4'b0000

for (int i = 0; i < 4; i++) begin
  `set_value(i);
end
def = 4'b0000; abc_3_def = 4'b0000;

Теперь код, который я написал, имеет проблему:

`define set_value(bit) abc_``bit``_def = 4'b0000

for (int i = 0; i < 4; i++) begin
  `set_value(i);
end

Ошибка в том, что он пытается найти сигнал abc_i_def, что явно неверно. Просто интересно, можно ли передать фактическое значение переменной «i» в макрос.


person user2644151    schedule 02.08.2013    source источник


Ответы (2)


Директивы препроцессора оцениваются препроцессором и изменяют код, представляемый компилятору.

Цикл for — это конструкция Verilog, которая оценивается компилятором.

Таким образом, ваш препроцессор не оценивает цикл for. Он видит:

`define `set_value(bit) abc_``bit``_def = 4'b0000

[some verilog]
   `set_value(i);
[some verilog]

Так что «я» — это просто я. Он не становится числом до компиляции.

Почему бы вам не использовать локальные параметры с генерацией, чтобы локальные параметры создавались в цикле при разработке по мере развертывания цикла for?

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


Я копался в этом немного больше. Параметры и локальные параметры внутри генерации создаются как локальные параметры в области генерации. См. здесь: Системные параметры Verilog в блоке генерации. Мне пришлось вернуться к работе, прежде чем я смог проверить это.

Я бы просто использовал код и заполнил массив. Это компилируется в VCS:

module veritest  
    #(  
    parameter   MAX_X = 5,  
                MAX_Y = 3,  
                MAX_Z = 2  
    )  
    (); // empty port list  

logic [4:0] abc_def[1:MAX_X][1:MAX_Y][1:MAX_Z];  

always @*  
begin  
for (integer z=1; z<(MAX_X+1);z=z+1)  
   for (integer y=1; y<(MAX_Y+1);y=y+1)  
       for (integer x=1; x<(MAX_X+1);x=x+1)  
       begin  
            abc_def[x][y][z] = 4'b0000;  
       end  
end  
endmodule  
person David Johnston    schedule 02.08.2013
comment
См. здесь на стр. 18, как сделать эквивалент «для использования метапрограммирования макросов». Я думаю, что это ужасно, но это то, что есть: veripool.org/papers/Preproc_Good_Evil_SNUGBos10_paper.pdf - person David Johnston; 02.08.2013
comment
Спасибо, Дэвид. Я хотя бы понял, почему у меня не могут работать макросы. Можете ли вы привести пример, чтобы описать, что вы хотели сказать о localparam и генерировать операторы? Извините, я новичок в System Verilog. - person user2644151; 02.08.2013
comment
Кроме того, что касается этого документа, который вы разместили, было приятно узнать, что именно я хочу сделать, но я не могу использовать это, потому что я намерен использовать его для большего количества битов, чем то, что я упомянул в своем вопросе, и для многих больше переменных, таких как abc_X_def_Y_ghi_Z, где X, Y и Z — переменные разных размеров. Таким образом, жесткое кодирование ограничений было бы излишним. - person user2644151; 02.08.2013
comment
@user2644151 user2644151, если X, Y, Z предназначены для использования в качестве переменных, почему бы не использовать многомерные массивы? бывший bit [3:0] abc_def_ghi [X_max][Y_max][Z_max]; - person Greg; 02.08.2013
comment
Верхний совет. Системный верилог — ужасный, ужасный язык для параметрического или метапрограммирования. Я переключился на использование Python для создания системного verilog со всеми жестко закодированными параметрами и без генерации. Это делает жизнь намного проще. - person David Johnston; 02.08.2013
comment
@ Грег, ты прав, это должно было быть как abc_def_ghi [X_max][Y_max][Z_max], но оно было плохо спроектировано, и на самом деле это не в моей власти. - person user2644151; 02.08.2013

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

Вы можете получить код, созданный вашим предпочтительным программированием, а затем использовать оператор `include в вашем файле verilog. Или вы можете использовать встроенный маршрут.

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

person Greg    schedule 02.08.2013