在芯片验证中,会遇到在验证一个不大的模块但是和其他模块交互较多时候,如果从零构造单独验证环境,那么牵涉到较多全局配置,而场景难覆盖到。如果放在SOC层级验证的话,模块又太小不能成为独立domain。本文提供一种热插拔的并行验证方式。
可以实现首要不干扰主业务,其次无需繁琐的新配置。仅仅从激励侧动态改动,从而是被测试模块能够在合适的时候响应测试。
在开始之前,首先介绍一个verilog的语言使用细节。
一、drive strength
在verilog中驱动net的强度 涉及到2个方面 power/capability 来影响net的值。
在一个net声明时有2中强度可以指定。
1.Chare Strength.
2.Drive Strength.
这里用到的是第二个特性,驱动强度。其涉及到针对一个net值的改变能力。它表示信号在门或网络的输出端上被驱动的强度。
当多个驱动试图控制一个net时,驱动力对于解决冲突至关重要。net采用最强驱动程序的值,如果相同强度的驱动程序存在冲突的值,结果将是未知的(x)。在平时仿真时候相信大家经常遇到 ,即报错“There are multiple drivers…” ,然后对应信号在verdi上显示为X态。
格式:
assign (strength1, strength0) net = expression;
- strength1: The strength when the net is driven to logic 1.
- strength0: The strength when the net is driven to logic 0.
如果没有指定强度,默认的驱动强度通常是强的,这意味着如果存在多个驱动因素,网络将采用强驱动因素的值。
如果多个不同强度的驱动程序试图驱动一个网络,net将承担最强驱动程序的value。如果两个或多个驱动器具有相同的强度但值不同,则结果将未知(x)。
2. 实现介绍
这里为了简化说明,使用简单的几个文件解释用法。这以一个fir滤波器为例来解释说明,这个模块很符合使用bind验证。
因为模块比较小 ,牵涉算法比对,然后如果单独配置又需要外围很多模块配合。
目录结构如下:
msr_fir_hpf |--golden_file | |-- PA.sv | |-- fir.sv | |-- fir_drv.sv | `-- fir_if.sv |--- msr_fir_hpf.c |---tb_stim.v `--- test.cfg
首先整体的最顶层的tb_top.v里面要引入PA.sv
`include "./golden_file/PA.sv" //module内不可以 因为他展开和module同级别 module tb_xxx_mcu; ur_chip_top u_xxxk_mcu( .P0_0 (P0_0), ........ ); `include "tb_stim.v" endmodule
tb_stim.v里面:
import PA_LIB::*; bind fir_filter:u_fir_filter fir_if fif(.*); //模块例化 FirDrv fdrv; FirModel fm; initial begin fdrv=new(u_xxx_mcu.u_project_digital_top.x_soc.x_apb.u_measure_top.u_fir_filter.fif); //该文件在大的tb下面 路径为相对当前路径 fdrv.fir_set(); fm=new(u_xxx_mcu.u_project_digital_top.x_soc.x_apb.u_measure_top.u_fir_filter.fif); fm.addr=29; fm.myshow(); end
interface fir_if( input wire clk, input wire reset_n, input wire data_in_en, input reg data_out_valid, inout wire signed [24:0] data_in_l, //这个信号在driver中被驱动 input reg signed [24:0] data_out_l, ...... ); parameter WIDTH=25; //被驱动的信号一定按照下面方式 logic [24:0] din_drv; //中间信号转化一下 initial {din_drv}<='z;//一开始必须赋值z态 即没有驱动 assign (supply1,supply0) data_in_l=din_drv; endinterface
PA.sv Package文件里面:
`include "./golden_file/fir_if.sv"; package PA_LIB; `include "./golden_file/fir.sv"; `include "./golden_file/fir_drv.sv"; endpackage:PA_LIB
fir_drv 驱动文件写法:
// ./golden_file/fir_drv.sv class FirDrv; virtual fir_if dif; function new(virtual fir_if yif); dif=yif; endfunction task fir_set; $display("I'm a driver"); #1000; dif.din_drv=1259; //注意这里不是驱动data_in_l ,否则出现x态; #1000; dif.din_drv=-2359; endtask endclass
最后的fir model 文件
//./golden_file/fir_sv class FirModel; virtual fir_if vif; bit [31:0] addr,firout,data[8]; function new(virtual fir_if myfif); vif=myfif; addr=3; firout=9; foreach(data[i]) data[i]=12; endfunction task myshow; $display("show fir model out:%d",data_in_l); repeat(30)begin @(posedge vif.data_out_valid); $display("datal:%d",vif.data_out_l); end endtask endclass
这样的话,我们在正常验证soc业务同时,可以适时的触发Fir滤波器的验证,而由于我们的单独fir驱动能力弱于soc的。所以我们不会干扰主业务。做好与其他业务的配合,就可以很方便的bind很多类似小的验证组件。