$sformat()与$psprintf()
在使用SystemVerilog进行测试平台设计或者RTL设计时,经常需要对特定的字符串进行拼接输出,而$sformatf()和$psprintf()是实现特定字符串按照指定格式拼接经常会被使用到的两个函数,而且在实践过程两种的用法基本一致,有时会难免奇怪为什么会存在两个功能完全一致的函数呢?而且在IEEE1800中仅有关于$sformatf()的描述,并没有$psprintf()的描述,那么这到底这是怎么回事?
$psprintf()是Vera遗留下来的古董,在Vera菁华被SystemVerilog吸收的过程中也被包含了进来,唯一可惜的是在IEEE1800发布时其并没有成为标准的一部分($sformatf()成为了IEEE1800的一部分),并且在刚开始只用Synopsys的VCS支持$psprintf(),随着现在仿真工具对于各种语言特性的兼容,$psprintf()也被其他的EDA公司的仿真工具所支持。虽然其用法与$sformatf()一样,但是在实际的使用过程中,建议还是使用IEEE1800所支持的函数。也许以后的将来$psprintf()会成为标准的一部分。
本文将以示例展示$sformatf()的用法,$psprintf()的使用格式与$sformatf()一样,在示例中可以替换进行替换。
$psprintf()是Vera遗留下来的古董,在Vera菁华被SystemVerilog吸收的过程中也被包含了进来,唯一可惜的是在IEEE1800发布时其并没有成为标准的一部分($sformatf()成为了IEEE1800的一部分),并且在刚开始只用Synopsys的VCS支持$psprintf(),随着现在仿真工具对于各种语言特性的兼容,$psprintf()也被其他的EDA公司的仿真工具所支持。虽然其用法与$sformatf()一样,但是在实际的使用过程中,建议还是使用IEEE1800所支持的函数。也许以后的将来$psprintf()会成为标准的一部分。
本文将以示例展示$sformatf()的用法,$psprintf()的使用格式与$sformatf()一样,在示例中可以替换进行替换。
【格式】
string_var = $sformatf(format_string[,list_of_arguments])【示例】
`timescale 1 ns / 1 ps
module top_tb;
string str;
logic [31:0] data;
initial begin
data = 32'h87654321;
str = $sformatf("The data is %0h!",data);
$display("I'm from display -> %s",str);
end
endmodule 【仿真结果】 示例中,$sformatf函数的返回值是一个字符串“The data is 32'h87654321”,即通过该函数可以将数据转换成字符串的一部分。同时我们也可以看到$sformatf函数本身并不对字符串进行输出,其任务仅仅是实现特定格式的字符串,其返回值就是要实现的特定格式的字符串。其实上例还可以进一步简化为如下的格式,其效果是一样的。
$display("I'm from display -> %s",$sformatf("The data is %0h!",data)); 有些人可能觉得这样使用和直接使用字符串的效果一样,但是在一些特定的场合是需要字符串中可以使用变量,此时就只能借助$sformatf了,如下例: `uvm_info(“DRV”,$sformatf(“I need dat is %0h”,var_t),UVM_LOW)
示例中的var_t为不同值时,$sformatf形成的字符串就会不一样。
【示例】
`timescale 1 ns / 1 ps
module top_tb;
bit [3:0] sig;
initial begin
sig = 4'b0000;
if($test$plusargs("SIG0"))
begin
sig[0] = 1'b1;
$display("SIG0 : %0h",sig[0]);
end
if($test$plusargs("SIG1"))
begin
sig[1] = 1'b1;
$display("SIG1 : %0h",sig[1]);
end
if($test$plusargs("SIG2"))
begin
sig[2] = 1'b1;
$display("SIG2 : %0h",sig[2]);
end
if($test$plusargs("SIG3"))
begin
sig[3] = 1'b1;
$display("SIG3 : %0h",sig[3]);
end
end
endmodule 【仿真结果】 为了实现不同的特定格式的字符串,使用上述方法,代码明显比较冗长,使用$sformatf后,可以有效地简化代码格式,如下例所示:
【示例】
`timescale 1 ns / 1 ps
module top_tb;
bit [3:0] sig;
initial begin
sig = 4'b0000;
foreach(sig[i])
begin
if($test$plusargs($sformatf("SIG%0h",i)))
begin
sig[i] = 1'b1;
$display($sformatf("SIG%0h -> %0h",i,sig[i]));
end
end
end
endmodule 【仿真结果】 当然除了使用$sformatf外还可以使用`define实现上述的示例中的功能,可以参考《Verilog系列:【69】define的扩展用法(一)》和《Verilog系列:【69】define的扩展用法(二)》,此处就不再赘述了。
