tcl自动生成fifo empty checker

在绝大多数block级验证时,正常用例结束后,所有的fifo都应该是空的。如果fifo不空,很有可能存在潜在问题。所以,平台应该在用例结束之前,做一次所有dut中fifo是否为空的检查。但是,对于验证来说,需要把dut中所有的fifo都拿到,并不是一件简单的事情。而,该脚本就实现了这个功能。

verdi工具提供了一套NPI接口,可以让用户得到设计的hierarchy。这样我们就能通过fifo字符串匹配,提取出所有的fifo,并生成一个function,供平台调用。

脚本fifo_empty_checker.tcl如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
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

该脚本需要在平台编译之前调用如下命令产生。

1
verdi -batch -play fifo_empty_checker.tcl

该脚本是通过吃vcs产生的kdb,当然也可以吃filelist,或者fsdb。

该脚本生成test_end_checker.sv格式如下:

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

在平台结束之前,就可以调用该function来检查fifo是否都空了。

再增加一个配置文件checker.cfg。第一列是module名称,第二列是信号,第三列是要检查的值。

1
*fifo*,o_empty,1

提示:如果使用filelist的方式加载,若design有error,有可能取到的hierarchy不全,需要增加环境变量setenv NPI_IGNORE_ERROR_VIEW 1。当然,更好的方式是通过打开kdb的方式加载。

扩展:verdi其实提供了apps来实现类似功能。

verdi –> tools –> VC Apps Toolbox –> Design Expioration

里面有比如 Get Module Hierarchy,Get Module IO, Find Instance with Module Def Name等app。

这个apps都可以使用GUI的方式,也可以使用batch的方式。例如:

1
$VERDI_HOME/share/VIA/Apps/DesignComprehension/FindInstDefWild/findInstDefWild_batch.pl -f flist -top top_tb -pattern "*fifo*" -outlog fifo.log

参考资料:

verdi/doc/NPI_tutorial.pdf

verdi/doc/VC_APPS_NPI.pdf

原文地址:https://www.cnblogs.com/lijianming180/p/12432969.html