SV及UVM中force和deposit的用法及区别

文摘   2024-05-30 23:02   上海  

在gate level simulation 中,$deposit(a,1)表示给一个net a 赋一个初值1,而 force a = 1  也表示给a 强迫一个初值 1,那么二者有什么区别?什么时候使用deposit,什么时候使用force?

deposit -- 使用代码或者脚本驱动后可以由dut内部信号再次改写
deposit: it will put a value to a signal, but it will hold until it is overwritten.

for example if I 'deposite' a Q of a flip flop to a '0', it will remain a '0', untill the simulation updates it to a new value. It is like giving a initial value to a signal.

force -- 使用代码或者脚本驱动后无法通过dut内部信号改写
force: it will put a value to a signal, and this value will remain as such throughout the simulaiton. It cannot be overwritten by simulation.

通过上面的解释相信大家对于SystemVerilog里的force和release,以及assign和deassign已经比较熟悉了。force和release配合使用,可以用来强制赋值,优先级高于assign和deassign,这两者都属于连续赋值语句。但是force的值会一直保持,而deposit只是set值,值可以被接下来的操作覆盖。另外,

force :不能将某个信号force成某个变量值;

$deposit (variable, value) ; deposit 则可以实现上述功能。与其相对的是,UVM提供了类似的以下接口:
//与SV中force语句相对应import "DPI-C" context function int uvm_hdl_force(    string path,    uvm_hdl_data_t value)
//与SV中release语句相对应 import "DPI-C" context function int uvm_hdl_release( string path)
//与SV中assign语句相对应 import "DPI-C" context function int uvm_hdl_deposit( string path, uvm_hdl_data_t value)
//用于检查HDL path是否存在import "DPI-C" context function int uvm_hdl_check_path( string path)
//用于读取HDL path变量的值import "DPI-C" context function int uvm_hdl_read( string path, output uvm_hdl_data_t value)
//用于release然后读取HDL path变量的值 import "DPI-C" context function int uvm_hdl_release_and_read( string path, inout uvm_hdl_data_t value)
直接使用上述UVM提供的函数与直接用SV中force, release 有什么区别?从上面这些UVM接口函数的输入端口类型为字符串就可以看出,这些函数的输入是字符串而不是HDL的层次结构(hierarchy path)。除此之外,使用uvm_hdl相关后门函数可以在package里访问RTL的信号,而SV的force语法则不行,常规的force必须要在package之外,即$unit空间。也就是说,如果在package里,下面第一行不可行,但是第二行可行,但这有个条件,需要添加VCS的编译选项-debug_access+f[用于将值写入(存入)寄存器和变量,以及将值强制写入寄存器、变量和网络]来支持该功能。
force top.DUT.A = 0; //不可行uvm_hdl_force("top.DUT.A",0); //可行

下面是一个例子:

module rtla();wire [7:0] sig_a;endmodule
module tb_top();rtla dut();endmodule
module test();import uvm_pkg::*;`include "uvm_macros.svh" int read_value;initial beginforce tb_top.dut.sig_a = 8'h5a;`uvm_info("TEST",$sformatf("after normal force sig_a value is %b",tb_top.dut.sig_a),UVM_NONE)release tb_top.dut.sig_a; if(uvm_hdl_check_path("tb_top.dut.sig_a"))begin `uvm_info("TEST",$sformatf("uvm_hdl_check_path success, mean HDL path %s exists!","tb_top.dut.sig_a"),UVM_NONE) end if(uvm_hdl_deposit("tb_top.dut.sig_a",8'ha3))begin `uvm_info("TEST",$sformatf("after uvm deposit, sig_a value is %h",tb_top.dut.sig_a),UVM_NONE) end if(uvm_hdl_force("tb_top.dut.sig_a",8'h5c))begin `uvm_info("TEST",$sformatf("after uvm force, sig_a value is %h",tb_top.dut.sig_a),UVM_NONE) end if(uvm_hdl_read("tb_top.dut.sig_a",read_value))begin `uvm_info("TEST",$sformatf("after uvm force, read_value is %h",read_value),UVM_NONE) end //if(uvm_hdl_release("tb_top.dut.sig_a",read_value))begin //wrong code if(uvm_hdl_release("tb_top.dut.sig_a"))begin `uvm_info("TEST",$sformatf("uvm release success"),UVM_NONE) end if(uvm_hdl_read("tb_top.dut.sig_a",read_value))begin `uvm_info("TEST",$sformatf("after uvm release, read_value is %h",read_value),UVM_NONE) end if(uvm_hdl_force("tb_top.dut.sig_a",8'haa))begin `uvm_info("TEST",$sformatf("after uvm force, sig_a value is %h",tb_top.dut.sig_a),UVM_NONE) end if(uvm_hdl_release_and_read("tb_top.dut.sig_a",read_value))begin `uvm_info("TEST",$sformatf("after uvm release, read_value is %h",read_value),UVM_NONE) end endendmodule

使用Xcelium仿真的结果如下图所示:

需要注意的是,release之后,根据release的对象类型的不同,结果也会不同,具体如下:

1、对于wire来说,release之后值将会立刻被改变为当前其他连线的驱动值。
2、其他类型则是release之后将会保持之前force的值直到下一次被assign新的值。

参考文章
https://www.cnblogs.com/Alfred-HOO/articles/17455694.html

一切改变源于看见;
看,是一种本能;
看见,是一种学问。
欢迎加入知识星球。星球内每周都有高质量内容更新!每天都会解答大家提出的技术问题。欢迎加入知识星球,助您快速成长。

最后,由于TX修改规则,为了不错过后续内容,欢迎加入QQ群,

另外,由于微信群已经超过200人,添加小编的微信,拉你进入WX学习群。

感谢关注微信公众号《芯片验证日记》,
一起好好学习,天天向上!

芯片验证日记
分享芯片验证相关的知识。
 最新文章