摘要:
在日常搭建验证平台的过程中会经常使用到字符串,本文主要记录一下两种字符串格式化函数 $sformatf() 和 $sformat()的区别和用法。
$sformatf() 和 $sformat() 都是字符串格式化函数,用于将字符串按照特定的格式进行整理,其原型如下:
$sformatf(format,args);
按照format的格式将args填进去,将格式化后的字符串作为该函数返回值
$sformat(str,format,args);
按照format的格式将args填进去,将格式化后的字符串存储在第一个参数str中
在格式化字符串时,可以使用不同的格式控制符,如 %d、%b、%o、%h 等,用于以十进制、二进制、八进制、十六进制等不同进制格式输出数据。
举例:
string string0;
string string1;
$sformat(string0, “string0_inst==%0d” , 100); //返回值存放在string0
$display(“%0s”, string0); //string0_inst==100
string1=$sformatf(“string1_inst==%0d” , 200); //整体直接作为返回值赋给string1
$display(“%0s”, string1); //string1_inst==200
Note:从上面例子可以看出,$sformatf() 和 $sformat() 不是负责打印的。只是按照 " "中的格式,将变量的值填进去。
在UVM验证平台中,使用到的uvm_info 宏的打印方式如下:
`uvm_info(“my_driver”,"data is drived ! ",UVM_LOW)
其中第二个参数是我们需要打印的信息,但是当我们需要打印变量值时就需要使用到 $sformatf() 或 $sformat()
`uvm_info(“my_driver”,$sformatf(“the drive data is %0x”, drv_data),UVM_LOW)
当drv_data取不同值时,就会输出不同的打印信息,从而将每次通过driver驱动的数据打印出来。
妙用1:
`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
在仿真阶段,可以通过在命令行传入SIG0,SIG1…等值,完成对sig[i]的赋值并打印出来,用少量代码便可以实现该功能。
妙用2:
软硬件之间通信,通过如下方式可以将软件写的值从顶层force进去,而不用逐一force
virtual task axi_com(ref svt_axi_transaction xact);
if(xact.xact_type == svt_axi_transaction::WRITE) begin
case(xact.addr):
addr_A: begin
`uvm_info("axi_com",$sformatf("force spi[%0d] to 1",xact.data[0],UVM_LOW)
uvm_hdl_force($sformatf("test_top.dut.spi[%0d]",xact,data[0]),1'b1);
end
endcase
end
endtask:axi_com