• 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

  • 相关阅读:
    暑假学习
    暑假学习
    暑假学习
    暑假学习
    暑假学习
    经验教训+总结
    NT 时刻
    联赛模拟测试 17
    联赛模拟测试 16
    联赛模拟测试 15
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12432969.html
Copyright © 2020-2023  润新知