When the vast majority of block-level verification, by the end of normal cases, all of the fifo should be empty. If the fifo is not empty, it is likely there is a potential problem. Therefore, the platform should be before the end of the use case, whether done all at once dut in fifo empty check. However, for verification, the need to dut have got all the fifo is not a simple matter. And the script to achieve this function.
verdi NPI tool provides a set of interfaces, allowing users to get hierarchy design. So that we can pass fifo string matching, extract all the fifo, and generates a function, for platform invoke.
debImport "-elab" "$env(DMPDIR)/simv.daidir/kdb" set tbdir "$env(CURDIR)"
set debug 0
set ::m_fp [ open "$tbdir/test_end_checker.sv" "w" ] set ::log [open "$env(DMPDIR)/checker.log" "w"]
set ::cfg_list {}
set cfgfile [ open "$tbdir/checker.cfg" "r" ] set line 1 while { [gets $cfgfile data] >= 0 } { set data [string trim $data] if {$debug} { puts $log "cfg=$data" } if { [string match {#*} $data ] == 0 } { set fields [split $data ","] if {[llength $fields] == 3} { lappend ::cfg_list $fields } else { error "config syntax error. please use "module, signal, value". line [$line]: $data" } } incr line } close $cfgfile
foreach cfg $::cfg_list { set cfg_mod [lindex $cfg 0] set cfg_sig [lindex $cfg 1] set cfg_val [lindex $cfg 2] if {$debug} { puts $::log "cfg_list: $cfg_mod $cfg_sig $cfg_val" } }
proc trv_mod {hdl debug} { if {$hdl != "" } { set def_name [npi_get_str -property npiDefName -object $hdl] set type [npi_get_str -property npiType -object $hdl] set module_fullname [npi_get_str -property npiFullName -object $hdl] if {$type == "npiModule"} { if {$debug} { puts $::log "full= 大专栏tcl自动生成fifo empty checker$module_fullname def=$def_name type=$type " } foreach cfg $::cfg_list { set cfg_mod [lindex $cfg 0] set cfg_sig [lindex $cfg 1] set cfg_val [lindex $cfg 2] if {[string match $cfg_mod $def_name] == "1"} { if {$debug} { puts $::log "match module $cfg_mod $def_name" } set itr [ npi_iterate -type npiPort -refHandle $hdl ] if { $itr != "" } { set sub_hdl [ npi_scan -iterator $itr] while { $sub_hdl != "" } { set module_port [npi_get_str -property npiName -object $sub_hdl] if {[string match $cfg_sig $module_port] == "1"} { puts $::m_fp "tif($module_fullname.$module_port != $cfg_val)begin" puts $::m_fp "tterr = 1;" puts $::m_fp "tt$error("$module_fullname.$module_port != $cfg_val");" puts $::m_fp "tend" } set sub_hdl [ npi_scan -iterator $itr] } } } } } }
set itr [npi_iterate -type npiInternalScope -refHandle $hdl] if {$itr == "" } { return } set sub_scp [npi_scan -iterator $itr ] while {$sub_scp != "" } { set scp_type [npi_get_str -property npiType -object $sub_scp] if {$scp_type == "npiModule" || $scp_type == "npiGenScope"} { trv_mod $sub_scp $debug } set sub_scp [npi_scan -iterator $itr] } }
puts $::m_fp "t$display("test end checking start...");" set itr [npi_iterate -type npiModule -refHandle "" ] if {$itr != "" } { set top_mod [npi_scan -iterator $itr] while {$top_mod != "" } { trv_mod $top_mod $debug npi_release_handle -object $top_mod set top_mod [npi_scan -iterator $itr ] } } puts $::m_fp "t$display("test end checking end");" close $::m_fp close $::log
exit
The script needs to be generated to call the following command before compiling platform.
1
verdi -batch -play fifo_empty_checker.tcl
The script is by eating vcs generated kdb, of course, you can eat filelist, or fsdb.
Test_end_checker.sv generated by the script format is as follows:
1 2 3 4 5 6
$display("test end checking start..."); if(top_tb.dut.xx.fifo.empty != 1)begin err = 1; $display(top_tb.dut.xx.fifo.empty != 1); end $display("test end checking end");
可以将它封装到一个task中
1 2 3 4 5
function int checker(); int err = 0; `include "test_end_checker.sv" return err; endfunction