SystemVerilog $fdisplay 不会打印看起来像格式说明符的字符串
SystemVerilog $fdisplay won't print strings that appear like format specifiers
我维护一个 SystemVerilog 库,在使用此代码的 3 年中从未遇到过这个问题。
我只能假设用户 compiling/running 使用某些特殊版本的 VCS。
Compiler version L-2016.06-SP2-7_Full64; Runtime version L-2016.06-SP2-7_Full64
----------------------------------------------------------------
OVM-2.1.2
以及准确的错误:
Error-[STASKE_NEAFFS] Insufficient number of arguments
my_model/my_source_file.sv, 659
Number of arguments (2) passed to substitute format specifiers in the string
are less than the number of format specifiers.
Please check the call stack shown above and pass number of arguments equal
to number of format specifiers.
是否有某种方法可以强制 $fdisplay
在某些格式说明符未“填写”的情况下进行打印?
或者有什么方法可以让 VCS 忽略这些问题?
目前我唯一的调试方法是尝试添加一个 $display
相同的字符串,看看我是否注意到了什么。
这是为 UVM 编写的一段非常相似 的代码...错误的实际代码对内部开发的 OVM RAL 层执行相同的操作。在接近尾声时调用 $fdisplay
是等效的错误行:
task save_uvm_accesses();
uvm_reg_block model_reg_blocks[$];
uvm_reg regs_of_block[$];
uvm_reg_field fields_of_reg[$];
uvm_reg sub_block;
uvm_reg_file uvm_file;
uvm_reg_backdoor backdoor_access;
uvm_reg_frontdoor front_access;
int fd;
string output_file_name = "UVM_info.csv";
string current_line="";
string frontdoors = "";
string fieldnames = "";
reg_model.get_blocks(model_reg_blocks);
fd = $fopen({output_file_name}, "w");
$fdisplay(fd,"reg_name,reg_full_name,unique_file_name,reg_file,backdoor_access,front_access,access methods,fieldnames");
$display("**************** UVM dump regs *******************");
// go through each sub-block
foreach (model_reg_blocks[sub_block]) begin
// go through each reg in sub-block
regs_of_block = {};
model_reg_blocks[sub_block].get_registers(regs_of_block);
foreach (regs_of_block[rreg]) begin
uvm_reg_map reg_map[$];
frontdoors = "\"";
fieldnames = "\"";
fields_of_reg = {};
current_line ="";
uvm_file = regs_of_block[rreg].get_regfile();
regs_of_block[rreg].get_maps(reg_map);
//backdoor_access = regs_of_block[rreg].get_backdoor(1);
backdoor_access = model_reg_blocks[sub_block].get_backdoor(1);
// enumerate any available frontdoor accesses
foreach (reg_map[map]) begin
front_access = regs_of_block[rreg].get_frontdoor(reg_map[map]);
if(front_access != null)
frontdoors = {frontdoors, $sformatf("%s,", front_access.get_name())};
end
frontdoors = {frontdoors, "\""};
regs_of_block[rreg].get_fields(fields_of_reg);
foreach (fields_of_reg[current_fieldname]) begin
fieldnames = {fieldnames, $sformatf("%s, ", fields_of_reg[current_fieldname].get_name())};
end
fieldnames = {fieldnames, "\""};
// current_line = {current_line, $sformatf("%s,", rreg}; r
current_line = {current_line, $sformatf("%s,", regs_of_block[rreg].get_name())};
current_line = {current_line, $sformatf("%s,", regs_of_block[rreg].get_full_name())};
current_line = {current_line, $sformatf("%s,", model_reg_blocks[sub_block].get_name())};
if(uvm_file == null)
current_line = {current_line, "null,"};
else
current_line = {current_line, $sformatf("%s,", uvm_file.get_name())};
if(backdoor_access == null)
current_line = {current_line, "null,"};
else
current_line = {current_line, $sformatf("%s,", backdoor_access.get_name())};
current_line = {current_line, $sformatf("%s,", frontdoors)};
current_line = {current_line,"backdoor,"};
current_line = {current_line, fieldnames};
$fdisplay(fd, current_line);
end
end
$fclose(fd);
endtask: save_uvm_accesses
我最后只是更改了最后的 fdisplay 行:
$fdisplay(fd, current_line);
至
$fdisplay(fd, "%s", current_line);
我维护一个 SystemVerilog 库,在使用此代码的 3 年中从未遇到过这个问题。 我只能假设用户 compiling/running 使用某些特殊版本的 VCS。
Compiler version L-2016.06-SP2-7_Full64; Runtime version L-2016.06-SP2-7_Full64
----------------------------------------------------------------
OVM-2.1.2
以及准确的错误:
Error-[STASKE_NEAFFS] Insufficient number of arguments
my_model/my_source_file.sv, 659
Number of arguments (2) passed to substitute format specifiers in the string
are less than the number of format specifiers.
Please check the call stack shown above and pass number of arguments equal
to number of format specifiers.
是否有某种方法可以强制 $fdisplay
在某些格式说明符未“填写”的情况下进行打印?
或者有什么方法可以让 VCS 忽略这些问题?
目前我唯一的调试方法是尝试添加一个 $display
相同的字符串,看看我是否注意到了什么。
这是为 UVM 编写的一段非常相似 的代码...错误的实际代码对内部开发的 OVM RAL 层执行相同的操作。在接近尾声时调用 $fdisplay
是等效的错误行:
task save_uvm_accesses();
uvm_reg_block model_reg_blocks[$];
uvm_reg regs_of_block[$];
uvm_reg_field fields_of_reg[$];
uvm_reg sub_block;
uvm_reg_file uvm_file;
uvm_reg_backdoor backdoor_access;
uvm_reg_frontdoor front_access;
int fd;
string output_file_name = "UVM_info.csv";
string current_line="";
string frontdoors = "";
string fieldnames = "";
reg_model.get_blocks(model_reg_blocks);
fd = $fopen({output_file_name}, "w");
$fdisplay(fd,"reg_name,reg_full_name,unique_file_name,reg_file,backdoor_access,front_access,access methods,fieldnames");
$display("**************** UVM dump regs *******************");
// go through each sub-block
foreach (model_reg_blocks[sub_block]) begin
// go through each reg in sub-block
regs_of_block = {};
model_reg_blocks[sub_block].get_registers(regs_of_block);
foreach (regs_of_block[rreg]) begin
uvm_reg_map reg_map[$];
frontdoors = "\"";
fieldnames = "\"";
fields_of_reg = {};
current_line ="";
uvm_file = regs_of_block[rreg].get_regfile();
regs_of_block[rreg].get_maps(reg_map);
//backdoor_access = regs_of_block[rreg].get_backdoor(1);
backdoor_access = model_reg_blocks[sub_block].get_backdoor(1);
// enumerate any available frontdoor accesses
foreach (reg_map[map]) begin
front_access = regs_of_block[rreg].get_frontdoor(reg_map[map]);
if(front_access != null)
frontdoors = {frontdoors, $sformatf("%s,", front_access.get_name())};
end
frontdoors = {frontdoors, "\""};
regs_of_block[rreg].get_fields(fields_of_reg);
foreach (fields_of_reg[current_fieldname]) begin
fieldnames = {fieldnames, $sformatf("%s, ", fields_of_reg[current_fieldname].get_name())};
end
fieldnames = {fieldnames, "\""};
// current_line = {current_line, $sformatf("%s,", rreg}; r
current_line = {current_line, $sformatf("%s,", regs_of_block[rreg].get_name())};
current_line = {current_line, $sformatf("%s,", regs_of_block[rreg].get_full_name())};
current_line = {current_line, $sformatf("%s,", model_reg_blocks[sub_block].get_name())};
if(uvm_file == null)
current_line = {current_line, "null,"};
else
current_line = {current_line, $sformatf("%s,", uvm_file.get_name())};
if(backdoor_access == null)
current_line = {current_line, "null,"};
else
current_line = {current_line, $sformatf("%s,", backdoor_access.get_name())};
current_line = {current_line, $sformatf("%s,", frontdoors)};
current_line = {current_line,"backdoor,"};
current_line = {current_line, fieldnames};
$fdisplay(fd, current_line);
end
end
$fclose(fd);
endtask: save_uvm_accesses
我最后只是更改了最后的 fdisplay 行:
$fdisplay(fd, current_line);
至
$fdisplay(fd, "%s", current_line);