2. Jasper环境搭建

Jasper 是业界常用的形式验证工具,主要用于安全属性验证(Security Property Verification)与逻辑等价验证(LEC)。在开始写属性、跑证明之前,第一步是把工具环境、目录结构和基本命令跑通。本节以一个可复现的最小工程为主线,把“装好—建好—跑通—看懂结果”四件事串起来,让读者能独立完成第一个验证任务。

一、安装与授权配置

Jasper 通常以安装包形式分发,安装过程本身不复杂,真正容易卡住的是授权(License)配置。安装完成后,工具目录下会有 bin/、lib/、include/ 等子目录,其中 bin/jaspergold(或 jg)是主入口。授权一般通过环境变量指定:

export JASPER_HOME=/tools/cadence/jasper/2023.09
export PATH=$JASPER_HOME/bin:$PATH
export LM_LICENSE_FILE=27020@license-server
# 或使用 CDS_LIC_FILE
export CDS_LIC_FILE=27020@license-server

配置完成后,用 jaspergold -version 验证工具能否启动,用 jaspergold -help 查看可用选项。如果启动时报 “Cannot connect to license server”,优先检查网络连通性、端口号和 license 文件中的 feature 名称,而不是反复重装工具。建议把上述变量写入 ~/.bashrc 或项目专用的 env.sh,避免每次手动设置。

授权服务器地址、端口和 feature 名称由 IT 或 CAD 团队提供,不要自行猜测。若使用浮动授权,注意同时占用 license 的并发用户数。

二、项目目录结构

Jasper 工程没有强制目录规范,但一个清晰的结构能显著降低后续维护成本。推荐按“设计、属性、脚本、结果”四类划分:

my_jasper_proj/
├── rtl/            # 待验证的 RTL 设计文件
│   └── counter.v
├── sva/            # SystemVerilog 断言/属性文件
│   └── counter_sva.sv
├── scripts/        # 运行脚本(.tcl)
│   └── run_counter.tcl
├── results/        # 输出结果、日志、报告
└── env.sh          # 环境变量

其中 rtl/ 放设计源码,sva/ 放属性,scripts/ 放 Tcl 脚本,results/ 用于存放工具生成的日志和证明结果。这种划分让“设计”与“验证意图”分离,便于复用和版本管理。

三、基本命令与 Tcl 脚本

Jasper 支持交互式命令行和 Tcl 脚本两种方式。交互式适合调试,脚本适合回归。核心命令包括:

  • analyze:分析并读入 RTL 或属性文件;
  • elaborate:精化设计,构建内部模型;
  • clock / reset:定义时钟和复位;
  • assert / assume / cover:加载属性、约束和覆盖点;
  • prove:启动证明;
  • report:查看结果。

下面是一个最小 Tcl 脚本示例,用于验证一个 4 位计数器:

# run_counter.tcl
analyze -sv rtl/counter.v
analyze -sv sva/counter_sva.sv
elaborate -top counter

clock clk
reset -expression {!rst_n}

prove -all
report -summary

运行方式为 jaspergold -tcl scripts/run_counter.tcl。脚本中 analyze 负责读入文件,elaborate 指定顶层模块,clock 和 reset 定义时序基准,prove -all 对所有已加载属性发起证明,report -summary 输出汇总结果。

四、第一个验证任务:计数器属性验证

假设设计是一个带同步复位的 4 位递增计数器,RTL 如下:

module counter (
  input  logic clk,
  input  logic rst_n,
  output logic [3:0] cnt
);
  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) cnt <= 4'b0;
    else        cnt <= cnt + 1'b1;
  end
endmodule

我们想验证两条属性:复位后计数为 0;正常工作时每个时钟周期加 1。对应的 SVA 可以写成:

module counter_sva (
  input logic clk,
  input logic rst_n,
  input logic [3:0] cnt
);
  // 复位后下一拍计数为 0
  property p_reset;
    @(posedge clk) !rst_n |=> cnt == 4'b0;
  endproperty
  a_reset: assert property (p_reset);

  // 非复位时每拍加 1
  property p_inc;
    @(posedge clk) rst_n |=> cnt == $past(cnt) + 1'b1;
  endproperty
  a_inc: assert property (p_inc);
endmodule

运行脚本后,Jasper 会输出每条属性的证明状态。常见状态有:proven(已证明)、cex(发现反例)、unknown(未收敛)、unreachable(不可达)。如果 a_inc 返回 cex,说明设计或属性存在问题,需要查看反例波形定位原因。

Jasper 第一个验证任务:数据流与结果判读 RTL 设计 counter.v 属性文件 counter_sva.sv Tcl 脚本 run_counter.tcl Jasper 引擎 analyze / elaborate clock / reset assert / assume prove -all 证明结果 proven(已证明) cex(反例) unknown(未收敛) unreachable(不可达) 结果判读要点: • proven:属性在所有可达状态下成立,验证通过。 • cex:存在反例路径,需查看波形定位设计或属性问题。 • unknown:证明未收敛,可尝试增加约束、调整时钟或使用更强引擎。

五、常见问题与排查

第一个验证任务跑通后,通常会遇到几类问题。第一类是 elaborate 报错,常见原因是顶层模块名写错或 RTL 中有语法错误,此时应先用 analyze 单独检查每个文件。第二类是属性返回 unknown,往往是因为时钟或复位定义不完整,或者属性本身过于复杂导致证明不收敛,可以尝试简化属性或增加 assume 约束。第三类是 cex,需要打开反例波形,逐拍检查信号变化,判断是设计缺陷还是属性写错。

不要忽略 unknown 状态。它既不代表通过,也不代表失败,而是“未得出结论”。在回归中应把 unknown 视为需要处理的问题,而不是默认通过。