跳转至

输入查询内容

    本页内容

    正则接口与缓存:删除的调试 API 和匹配风险

    已复现的目标库问题

    目标库启用缓存后的 regex/glob 混用问题已复现;默认关闭缓存的对照已验证。

    影响范围

    直接调用 uvm_dump_re_cache 或开启正则缓存的环境需核对;普通缓存关闭的路径按对应用例比较。

    具体差异

    uvm_re_match 从 DPI import 变为 SV 函数并新增可选参数 deglob=0,原两参调用点不受影响。② uvm_dump_re_cache() 删除(2.0 全库 grep 无此符号)。③ 新增 uvm_regex_cache 缓存机制,默认关闭,+define+UVM_ENABLE_RE_MATCH_CACHE 开启(大型层次环境下 resource_db 查找提速;save/restore 场景勿开)。④ C 侧 uvm_hdl_inca.c 删除、新增 uvm_hdl_xcelium.c(Cadence 仿真器文件改名),uvm_dpi.h 汇总 regex/hdl 原型。uvm_hdl_* 后门函数签名两版一致(仅 `uvm_context_prop 宏展开写法变化)。

    组件名检查 visitor 也改用 uvm_is_match,并为自定义约束补 /.../ 定界;UVM_REGEX_NO_DPI 下跳过检查并首用提示 NO_VISIT_CHECK(src/vcs-uvm-1.2/base/uvm_traversal.svh:272src/vcs-uvm-ieee-2020-2.0/base/uvm_traversal.svh:267,274)。该检查的 DPI 前提和告警不能视为零差异。

    修改方案

    删除对 uvm_dump_re_cache() 的调用(若有)。保留缓存默认关闭:目标缓存只以表达式字符串为键,未区分 deglob(src/vcs-uvm-ieee-2020-2.0/dpi/uvm_regex.svh:46,59)。utility_probe 先用 uvm_re_match("a.*","abc") 再用 uvm_is_match,同样代码在两库默认模式第二次均不匹配,目标开启缓存后错误匹配。混合 regex/glob 的查找结果可能依赖调用顺序,不能将缓存开关作为无条件性能优化(S21)。

    兼容措施与范围:旧缓存调试接口不恢复;保持正则缓存默认关闭,兼容措施不修复 regex/glob 共用缓存键。

    已知限制KI-009

    迁移后验证

    按两种调用顺序测试同一表达式的 regexglob,结果必须与无缓存对照一致;默认保持缓存关闭。

    记录本条结果M10-006 · 状态与证据

    已有实测与复现

    补充查阅

    扫描定位与记录结果

    有扫描规则,覆盖部分可识别写法。脚本检查名称、参数和部分 FLAG 表达式,并对少数直接声明关联使用点;未做完整类型解析或预处理,行为结果仍需验证。

    uv run tools/uvm_migration_scan.py <SoC代码目录> --rules S21,D7
    

    核对命中对象及生效分支后,在条目清单记录修改与验证证据;扫描规则记录用于整理命中位置。

    扫描器下载、输入范围与报告说明

    源码与标准依据

    核查方式:源码与实测核对。实测仅覆盖本条所列场景。

    VCS 内置 UVM-1.2uvm_regex.svh:23–25uvm_re_match/uvm_dump_re_cache/uvm_glob_to_re 三个 DPI import)

    VCS 内置 uvm-ieee-2020-2.0uvm_regex.svh:25–31(新 DPI 组 uvm_re_comp/exec/compexec/free/buffer/deglobbed)、uvm_regex.svh:67uvm_re_match(string,string,bit deglob=0) 改为 SV 函数)、uvm_regex.svh:141uvm_glob_to_re 保留为 SV 函数)

    引用代码(高亮为引用行);上方行号链接可直接定位。

    src/vcs-uvm-1.2/dpi/uvm_regex.svh
    `ifndef UVM_REGEX_NO_DPI
    import "DPI-C" context function int uvm_re_match(string re, string str);
    import "DPI-C" context function void uvm_dump_re_cache();
    import "DPI-C" context function string uvm_glob_to_re(string glob);
    
    `else
    
    // The Verilog only version does not match regular expressions,
    // it only does glob style matching.
    function int uvm_re_match(string re, string str);
      int e, es, s, ss;
      string tmp;
      e  = 0; s  = 0;
      es = 0; ss = 0;
    
      if(re.len() == 0)
        return 0;
    

    完整源码 · SHA256:225a284c395963162aa3ce223786a6343d5c6c7f2e92a57df04f6f666849c5dd

    src/vcs-uvm-ieee-2020-2.0/dpi/uvm_regex.svh
    `ifndef UVM_REGEX_NO_DPI
    import "DPI-C" function string uvm_re_deglobbed(string glob, bit with_brackets);
    import "DPI-C" function string uvm_re_buffer();
    import "DPI-C" function void uvm_re_free(chandle rexp);
    import "DPI-C" function chandle uvm_re_comp(string re, bit deglob);
    import "DPI-C" function int uvm_re_exec(chandle rexp, string str);
    import "DPI-C" function chandle uvm_re_compexec(string re, string str, bit deglob, output int exec_ret);
    import "DPI-C" function bit uvm_re_compexecfree(string re, string str, bit deglob, output int exec_ret);
    
    typedef class uvm_regex_cache;
    
    // The uvm_re_match cache is disabled by default, to avoid 
    // potential issues with save-and-restore causing illegal c-side 
    // dereferencing.  When enabled, uvm_re_match should be significantly 
    // faster.   
    `ifdef UVM_ENABLE_RE_MATCH_CACHE
    function int uvm_re_match(string re, string str, bit deglob = 0);
    

    src/vcs-uvm-ieee-2020-2.0/dpi/uvm_regex.svh
      int retval;
    
      cache = uvm_regex_cache::get_inst();
      cached = cache.get(re);
      if (cached.size()) begin
        // Cache hit, use pre-compiled regex
        retval = uvm_re_exec(cached[0], str);
      end
      else begin
        // Cache miss, compile and cache regex
        chandle rexp;
        rexp = uvm_re_compexec(re, str, deglob, retval);
        if (rexp == null) begin
          uvm_report_error("UVM/DPI/REGEX", uvm_re_buffer());
        end
        else begin
          cache.put(re, rexp);
        end
      end // else: !if(cached.size())
      return retval;
    endfunction : uvm_re_match
    
    `else // !`ifdef UVM_ENABLE_RE_MATCH_CACHE
    
    function int uvm_re_match(string re, string str, bit deglob = 0);
      int retval;
      bit success;
      success = uvm_re_compexecfree(re, str, deglob, retval);
      if (!success) begin
        uvm_report_error("UVM/DPI/REGEX", uvm_re_buffer());
      end
      return retval;
    endfunction : uvm_re_match
    
    `endif // !`ifdef UVM_ENABLE_RE_MATCH_CACHE
    
    
    function string uvm_glob_to_re(string glob);
      return uvm_re_deglobbed(glob, 1);
    endfunction : uvm_glob_to_re
    

    src/vcs-uvm-ieee-2020-2.0/dpi/uvm_regex.svh
      end
    endfunction
    
    function string uvm_glob_to_re(string glob);
      return glob;
    endfunction
    
    `endif
    

    完整源码 · SHA256:cd60f89f2d96f4d849f420dcc86c7df74f73c72b557104231f62a205323d93d5

    src/vcs-uvm-1.2/base/uvm_traversal.svh
        endfunction 
        function new (string name = "");
            super.new(name);
        endfunction 
    
        virtual function void begin_v(); 
            uvm_coreservice_t cs = uvm_coreservice_t::get();
    
            _root =  cs.get_root();
    `ifdef UVM_NO_DPI
            `uvm_info("UVM/COMP/NAMECHECK","This implementation of the component name checks requires DPI to be enabled",UVM_NONE)
    `endif
        endfunction
        virtual function void end_v(); 
    `ifndef UVM_NO_DPI
            uvm_dpi_regfree(visit.compiled_regex);
            visit.compiled_regex=null;  
    `endif
        endfunction
    

    完整源码 · SHA256:d259fdb50a332ec9331dab88a7e7406ed579375ef831fefaf846790fa68ff6c6

    src/vcs-uvm-ieee-2020-2.0/base/uvm_traversal.svh
      // This method should return a regex for what is being considered a valid/good component name.
      // The visitor will check all component names using this regex and report failing names
    
      virtual function string get_name_constraint();
        return "/^[][[:alnum:](){}_:-]([][[:alnum:](){} _:-]*[][[:alnum:](){}_:-])?$/";
      endfunction
    
      virtual function void visit(NODE node);
        // dont check the root component
        if(_root != node) begin
    `ifdef UVM_REGEX_NO_DPI
          static bit warned ;
          if (!warned) begin
            `uvm_warning("NO_VISIT_CHECK","Because UVM_REGEX_NO_DPI is defined, no uvm component name constraints will be checked")
            warned = 1;
          end
    `else
          string regex = get_name_constraint();
             // if we don't have something surrounded by "/" characters, add them
          if ((regex.len() <= 2) || 
              (regex[0] != "/") || 
              (regex[regex.len()-1] != "/"))
             regex = {"/",regex,"/"};
          if ( ! uvm_is_match( regex, node.get_name() ) ) begin
            `uvm_warning("UVM/COMP/NAME",$sformatf("the name \"%s\" of the component \"%s\" violates the uvm component name constraints",node.get_name(),node.get_full_name()))
          end
    

    完整源码 · SHA256:990f299b7ca51567ef13e9ecc17cccc53f366345794c5c258c7bac59736d8a37

    术语解释 · 兼容配置

    返回Component / VCS 集成 · 迁移清单

    版本适用范围