Строковая переменная systemverilog как спецификатор формата для $ display / $ write

Я пытаюсь создать описатель переменного формата для использования в $ display / $ write. Я перепробовал множество вещей, но вот то, что у меня есть на данный момент.

В итоге я хочу получить: $ display (format_var, data_1, data_2), где строка формата предварительно вычисляется с использованием $ sformatf или другого.

Код:

module test;
function void pprint(input int data_1,input int field_1,input int data_2,input int field_2);
string  format;
begin 
    format = $sformatf("%0d'h%%%0dx,%0d'h%%%0dx",field_1,field_1/4,field_2,field_2/4);
    $display("format = %s",format);
    $display(format,data_1,data_2);
end
endfunction

initial 
begin
    pprint(5,8,73737229,128);
    $stop;
end
endmodule

Ожидаемый результат:

format = 8'h%2x,128'h%32x
8'h05,128'h000000000000000000000000465240D

Я получаю следующий результат:

format = 8'h%2x,128'h%32x
8'h%2x,128'h%32x          5   73737229

Что мне нужно сделать? Симулятор Vivado 2020.3

Позже:

Попробую еще раз, следующая функция делает то, что я хочу. Я пришел к выводу, что $ display / $ write не может принимать переменную в качестве строки формата, а $ sformatf может.

function void pprint(input int data_1,input int field_1,input int data_2,input int field_2);
string  format;
string  outstr;
begin 
    format = $sformatf("%0d'h%%%0dx,%0d'h%%%0dx",field_1,field_1/4,field_2,field_2/4);
    $display("format = %s",format);
    $display("%s",$sformatf(format,data_1,data_2));
end
endfunction

person MichaelL    schedule 27.05.2021    source источник
comment
Попробуйте свой код на edaplayground на разных симуляторах (например, vcs). См. Также Как я могу автоматически масштабировать ширину столбца $ display? < / а>   -  person toolic    schedule 27.05.2021


Ответы (2)


Пытаться:

function void pprint(
    input logic [4095:0] data_1,
    input int field_1,
    input logic [4095:0] data_2,
    input int field_2 );
  string  format; 
  format = $sformatf("%0d'h%%%0dh,%0d'h%%%0dh",
    field_1, (field_1+3)/4,
    field_2, (field_2+3)/4 );
  $display("format = %s",format);
  $display($sformatf(format,data_1,data_2));
endfunction

Это должно дать вам результат:

format = 8'h%02h,128'h%032h
8'h05,128'h000000000000000000000000465240D

Добавление нуля между % и цифрой может указывать симулятору заполнить верхние биты нулями.
По какой-то причине $display(format,data_1,data_2) не использовал формат на симуляторах на edaplayground, но он работал с $sformatf, поэтому я просто вложил его.
Мне нужно было увеличить разрядность входных данных, иначе будут отображаться ведущие нули более 8 цифр. При необходимости отрегулируйте.
Добавление 3 в поле предназначено для обработки не кратных 4. После деления оно всегда будет округляться в меньшую сторону.

person Greg    schedule 27.05.2021
comment
В моем случае мне нужен нулевой отступ. до ближайшего байта. Я не рассматривал для своего варианта использования число, не кратное четырем, но мне нравится возможность справиться с этим. Спасибо! Этот $ display не работает, мне это интересно, и мне интересно, является ли это частью спецификации, что он не обрабатывает строковую переменную, или он ускользнул из-за трещин. - person MichaelL; 27.05.2021

Согласно разделу 21.3.3 Форматирование данных в строку SystemVerilog LRM, только $sformat и $sformatf имеют определенный аргумент форматирования, который может быть строковым литералом или строковой переменной. Все другие задачи вывода, такие как $display, обрабатывают любой строковый литерал как спецификатор формата и не интерпретируют строки внутри строковых переменных для форматирования.

person dave_59    schedule 27.05.2021