翻译自《vcs user guide》有能力的还是建议看英文原版。。。。
1.SDF 反标 (SDF Annotation)
开放 Verilog 国际标准延迟文件 (OVI SDF) 规范提供了一种用于表示和应用延迟信息的标准 ASCII 文件格式。VCS支持此规范的OVI 1.0、1.1、2.0、2.1和3.0版本。
在SDF格式中,工具可以指定固有延迟(intrinsic delays)、互连延迟 (interconnect delays)、端口延迟 (port delays)、时序检查 (timing checks)、时序约束 (timing constraints) 和脉冲控制 (PATHPULSE)。
当 VCS 读取 SDF 文件时,它会将延迟值“反标 (back-annotates)”到设计中,即它会添加延迟值或更改源文件中指定的延迟值。
1.1使用统一SDF功能(Using the Unified SDF Feature)
统一SDF功能允许使用以下编译/细化 (elaboration) 选项进行延迟反标:
-sdf min|typ|max:instance_name:file.sdf
两步流程 (For two-step flow):
编译 (Compilation):
vcs -sdf min|typ|max:instance_name:file.sdf [compile_options]
仿真(Simulation):
simv [run_options]
三步流程 (For three-step flow):
分析(Analysis):
vlogan [vlogan_options] file2.v file3.v
vhdlan [vhdlan_options] file4.vhd file5.vhd
注意:VHDL 需要首先分析最底层的实体 (bottommost entity),然后按顺序向上分析。
细化 (Elaboration)
vcs -sdf min|typ|max:instance_name:file.sdf [elab_options] top_cfg/entity/module
仿真 (Simulation)
simv [run_options]
1.2使用 $sdf_annotate 系统任务 (Using the $sdf_annotate System Task)
可以使用 $sdf_annotate 系统任务将 SDF 文件中的延迟值反标到您的 Verilog 设计中。
$sdf_annotate 系统任务的语法如下:
$sdf_annotate ("sdf_file"[, module_instance][, "sdf_configfile"][,"sdf_logfile"][, "mtm_spec"][, "scale_factors"][, "scale_type"]);
其中:
"sdf_file":指定SDF文件的路径。
module_instance:指定反标开始的层次范围 (scope)。默认是调用 $sdf_annotate 的模块实例的层次范围。
"sdf_configfile"
指定 SDF 配置文件。有关 SDF 配置文件的更多信息,请参阅 SDF Configuration File 部分。
"sdf_logfile"
指定一个 SDF 日志文件,VCS 会将错误消息和警告发送到该文件。默认情况下,VCS 在控制台显示不超过十条关于反标的警告和错误消息,并且在您使用 -l 选项指定的日志文件中写入的消息数量也不超过此限制。但是,如果您使用此参数指定 SDF 日志文件,该 SDF 日志文件将接收所有关于反标的消息。您还可以使用 +sdfverbose 运行时选项来启用显示所有反标消息。
"mtm_spec"
指定 VCS 反标的最小:典型:最大值 (min:typ:max) 三元组中的哪些延迟值。其可能值为 "MINIMUM"、"TYPICAL"、"MAXIMUM" 或 "TOOL_CONTROL"(默认)。
"scale_factors"
指定延迟三元组的最小、典型和最大分量的乘数。它是一个由三个正实数组成的冒号分隔的字符串,默认为 "1.0:1.0:1.0"。
"scale_type"
指定在缩放之前使用来自 SDF 文件中每个三元组的哪个延迟值。其可能值为 "FROM_TYPICAL"、"FROM_MINIMUM"、"FROM_MAXIMUM" 和 "FROM_MTM"(默认)。
使用 $sdf_annotate 仿真设计的用法模型与基本用法模型相同,如下所示:
两步流程 (For two-step flow):
编译 (Compilation)
vcs [elab_options] top_cfg/entity/module
仿真 (Simulation)
simv [run_options]
三步流程 (For three-step flow):
分析 (Analysis)
vlogan [vlogan_options] file2.v file3.v
vhdlan [vhdlan_options] file4.vhd file5.vhd
注意:VHDL 需要首先分析最底层的实体 (bottommost entity),然后按顺序向上分析。
细化 (Elaboration)
vcs [elab_options] top_cfg/entity/module
仿真 (Simulation)
simv [run_options]
1.3使用 -xlrm 选项处理 SDF 保留、门级脉冲传播和门级脉冲检测警告 (Using the -xlrm Option for SDF Retain, Gate Pulse Propagation, and Gate Pulse Detection Warning)
以下部分解释了在 -xlrm 选项下添加的新功能的使用方法:
在 SDF 中使用乐观模式 (Using the Optimistic Mode in SDF)
使用门级脉冲传播 (Using Gate Pulse Propagation)
在门级脉冲期间生成警告 (Generating Warnings During Gate Pulses)
1.4在SDF中使用乐观模式 (Using the Optimistic Mode in SDF)
当前,当使用-sdfretain选项时,SDF保留值会在相关输入发生变化时显现。
当指定-xlrm alt_retain选项时(即 vcs -xlrm alt_retain ...),SDF保留值仅在输出发生变化时才显现。这种新行为称为乐观模式。
例如,考虑以下 Verilog 代码:
and u(qout,d1,d2);
specify
(d1 => qout) = (10); //RETAIN (6)
(d2 => qout) = (10);
endspecify
对应的 SDF 条目是:
(IOPATH d1 qout (RETAIN (6))(10) )
(IOPATH d2 qout (10) )
上述示例的默认输出(非乐观模式)为:
time= 10 , d1=0,d2=0, qout=0
time= 100 , d1=1,d2=0, qout=0
time= 106 , d1=1,d2=0, qout=x // 由于输入 d1 在 100 时刻改变,VCS 将 'x' 传播到 qout
time= 110 , d1=1,d2=0, qout=0
time= 200 , d1=0,d2=0, qout=0
time= 206 , d1=0,d2=0, qout=x // 由于输入 d1 在 200 时刻改变,VCS 将 'x' 传播到 qout
time= 210 , d1=0,d2=0, qout=0
time= 300 , d1=0,d2=1, qout=0
time= 400 , d1=1,d2=1, qout=0
time= 406 , d1=1,d2=1, qout=x
time= 410 , d1=1,d2=1, qout=1
使用 -xlrm alt_retain 选项的输出(乐观模式)如下:
time= 10 , d1=0,d2=0, qout=0
time= 100 , d1=1,d2=0, qout=0 // 由于 "qout" 的逻辑值没有变化,未看到保留引起的 'x'
time= 200 , d1=0,d2=0, qout=0
time= 300 , d1=0,d2=1, qout=0
time= 400 , d1=1,d2=1, qout=0
time= 406 , d1=1,d2=1, qout=x // 由于 "qout" 的逻辑值发生变化,保留引起的 'x' 被传播
time= 410 , d1=1,d2=1, qout=1
使用门级脉冲传播 (Using Gate Pulse Propagation)
使用 -xlrm gd_pulseprop 选项时,VCS 始终会传播门级脉冲,即使脉冲宽度等于门延迟(Gate Delay)也会传播。例如,考虑以下Verilog代码:
module dut(qout, dinA, dinB);
output qout;
input dinA;
input dinB;
xor #10 inst(qout, dinA, dinB); // 门延迟为 10 个单位
endmodule
在启用 -xlrm gd_pulseprop 后,若门级脉冲宽度等于门延迟(10),VCS 会严格按照时序传播脉冲值,仿真结果如下:
0: qout=x, dinA=1, dinB=1
10: qout=0, dinA=0, dinB=1 // 输入变化
20: qout=1, dinA=0, dinB=0 // 脉冲被传播
30: qout=0, dinA=0, dinB=1
40: qout=1, dinA=0, dinB=0
50: qout=0, dinA=0, dinB=0
关键点:
默认行为会过滤宽度等于门延迟的脉冲(视为毛刺),而 gd_pulseprop 确保所有脉冲均被传播。
在门级脉冲期间生成警告(Generating Warnings During Gate Pulses)
使用 -xlrm gd_pulsewarn 选项时,VCS 会检测脉冲宽度等于门延迟的情况并生成警告。以上述相同 Verilog 代码为例:
module dut(qout, dinA, dinB);
output qout;
input dinA;
input dinB;
xor #10 inst(qout, dinA, dinB); // 门延迟为 10
endmodule
启用 -xlrm gd_pulsewarn 后,当脉冲宽度等于门延迟时,VCS 输出如下警告:
0: qout=x, dinA=1, dinB=1
Warning-[PWIWGD] Pulse Width Identical With Gate Delay
verilogfile.v, line 42 // 代码位置
top.mid_inst.dut_inst // 模块层级
At time 10, pulse width identical with gate delay "10" is detected // 检测到脉冲宽度=延迟
10: qout=0, dinA=0, dinB=1 // 后续仿真继续
20: qout=1, dinA=0, dinB=0
关键点:
该警告帮助设计者定位潜在时序风险(如竞争条件),但不影响仿真行为。
通过 SPICE 增强 SDF 反标以支持网络 (Enhancing SDF Annotation to Support Nets Through SPICE)
在混合信号验证(MSV)中,VCS 支持对数字-模拟接口的反标:
覆盖场景:
数字端口↔模拟端口间的互连延迟(INTERCONNECT delay)
SPICE 模块为父级的配置(如 V-S-V 环形拓扑)
启用选项:
编译时添加 +msvsdfext,使 SDF 反标支持穿过 SPICE 模块的数字网络
反标对象:
输入端口(input)、输出端口(output)、双向端口(inout)
典型用例:
d2d互连(在 V-S-V 环形配置中)
图中 td0 为互连延迟,SDF 将在输入/输出端口正确反标延迟值。
2.预编译SDF文件
在编译设计时,如果设计需要反标SDF数据,VCS会解析ASCII文本格式的SDF文件或其预编译版本。即使SDF文件未更改且已在前次编译中生成二进制版本,VCS仍会重新解析。此外,即使使用增量编译且SDF文件反标的设计部分未作修改,VCS仍会执行解析。
VCS解析预编译SDF文件的速度远快于解析ASCII文本格式的SDF文件。因此,对于大型SDF文件,建议让VCS生成其预编译版本。
2.1创建SDF文件的预编译版本
在vcs命令行中添加+csdf+precompile选项即可生成预编译版本。
默认情况下,+csdf+precompile选项会在ASCII文本SDF文件所在目录下生成预编译版本,并在扩展名后追加_c以示区分。例如,若/u/design/sdf目录下存在design1.sdf文件,预编译后的文件将被命名为design1.sdf_c,并存储在同一目录下。
生成预编译版本后,除非SDF文件发生更改,否则无需在后续编译中再次添加+csdf+precompile选项。但若将其保留在编译脚本中,VCS会在检测到ASCII文本SDF文件更新时自动重新生成预编译版本,因此该选项适合长期嵌入编译脚本。
重新编译设计时,VCS会自动在$sdf_annotate系统任务指定的SDF文件所在目录查找预编译版本。用户也可直接在$sdf_annotate中指定预编译SDF文件。该选项同样支持压缩格式的SDF文件(zipped SDFs)。
2.2单独预编译SDF文件(不编译设计文件)
若仅需预编译SDF文件而不编译设计文件,可使用以下命令:
vcs +csdf+precomp+file+<SDF文件>
示例:
vcs +csdf+precomp+file+test1.sdf
2.3将预编译SDF文件输出至指定目录
如需将预编译SDF文件写入不同目录,可使用以下选项:
+csdf+precomp+dir+<目录路径>
示例:
mkdir PRE_COMP_SDF
vcs +csdf+precomp+file+./test.sdf +csdf+precomp+dir+PRE_COMP_SDF/
注意:预编译后的SDF文件将生成在指定的PRE_COMP_SDF目录中。
3.SDF配置文件
SDF配置文件可用于在模块类型或全局范围内控制以下内容:
•最小(min)、典型(typ)或最大(max)延迟值选择
• 缩放比例(Scaling)
• 模块输入端口延迟(MIPD)的近似策略(适用于同一输入端口存在“重叠”标注的情况)
此外,还可使用映射命令将IOPATH和TIMINGCHECK语句的目标从INSTANCE范围重定向到其子层次结构中的特定IOPATH或TIMINGCHECK(适用于指定模块类型的所有实例)。
3.1延迟对象与结构
VCS中SDF语句到仿真对象的映射关系是固定的,如下表所示:
3.2 SDF配置文件命令
本节介绍SDF配置文件中使用的命令及其语法和示例:
1)INTERCONNECT_MIPD 命令
该命令选择SDF文件中映射到VCS模块输入端口延迟(MIPD)的 INTERCONNECT延迟。默认情况下,互联延迟建模为MIPD(即使目标有多个源,仅选择一个端口延迟)。
可选策略:
• MINIMUM:选择所有INTERCONNECT延迟值中的最短延迟作为MIPD。
• MAXIMUM(默认):选择最长延迟。
• AVERAGE:选择平均延迟。
• LAST:选择最后一个INTERCONNECT延迟值。
语法:
INTERCONNECT_MIPD = MINIMUM | MAXIMUM | AVERAGE | LAST;
示例:
INTERCONNECT_MIPD=LAST;
2)MTM 命令
该命令标注最小(min)、典型(typ)或最大(max)延迟值。
可选策略:
• MINIMUM:标注最小延迟值。
• TYPICAL:标注典型延迟值。
• MAXIMUM:标注最大延迟值。
• TOOL_CONTROL(默认):延迟值由Verilog工具命令行选项(+mindelays/+typdelays/+maxdelays)决定。
语法:
MTM = MINIMUM | TYPICAL | MAXIMUM | TOOL_CONTROL;
示例:
MTM=MAXIMUM;
3)SCALE 命令
分为两类:
• SCALE_FACTORS:三个实数乘数,用于缩放SDF文件中的时序信息到反标的最小/典型/最大时序。例如 1.6:1.4:1.2。
• SCALE_TYPE:选择缩放基准:
• FROM_MINIMUM:基于SDF中的最小时序缩放。
• FROM_TYPICAL:基于典型时序缩放。
• FROM_MAXIMUM:基于最大时序缩放。
• FROM_MTM(默认):直接基于SDF中的min/typ/max时序缩放。
语法:
SCALE_FACTORS = number : number : number;
SCALE_TYPE = FROM_MINIMUM | FROM_TYPICAL | FROM_MAXIMUM | FROM_MTM;
示例:
SCALE_FACTORS=1.1:2.1:3.1;
SCALE_TYPE=FROM_MINIMUM;
4.延迟与时序控制
4.1传输延迟与惯性延迟
• 传输延迟(Transport Delays)
• 允许所有窄于延迟的脉冲传播(即使脉冲宽度小于路径延迟)。
• 启用方式:
+transport_path_delays # 模块路径延迟
+transport_int_delays # SDF反标的INTERCONNECT延迟
• 需配合脉冲控制选项(如+pulse_e/80 +pulse_r/50)使用。
• 惯性延迟(Inertial Delays)
• 默认行为:过滤所有窄于延迟的脉冲(仅传播宽脉冲)。
• 适用于门级原语(如逻辑门、开关)、MIPD和连续赋值语句。
波形对比:
• 传输延迟:窄脉冲(如3时间单位)在延迟后出现在输出端(延迟=7时间单位)
• 惯性延迟:窄脉冲被完全过滤,仅宽脉冲(≥延迟)传播。
4.2脉冲控制
通过阈值控制脉冲传播行为:
• 模块路径延迟控制:
+pulse_e/80 # 宽度<80%延迟的脉冲输出X并警告
+pulse_r/50 # 宽度<50%延迟的脉冲被过滤(无警告)
• INTERCONNECT延迟控制:
+pulse_int_e/80
+pulse_int_r/50
行为模式:
• +pulse_on_event(默认):X脉冲在延迟结束后出现。
• +pulse_on_detect:X脉冲在检测到窄脉冲时立即出现。
示例场景:
• 延迟=10时间单位,输入脉冲宽度=7时间单位(+pulse_e/80):
• 输出端替换为X脉冲(因7 < 80%×10)。
4.3延迟模式选择
通过编译选项指定延迟计算方式:
选项行为
+delay_mode_path 仅使用模块路径延迟(忽略原语和连续赋值的分布式延迟)
+delay_mode_distributed 仅使用分布式延迟(忽略模块路径延迟)
+delay_mode_unit 所有延迟替换为timescale的最小精度(如1ns)
+delay_mode_zero 所有延迟设为0
默认 取模块路径延迟和分布式延迟中的较大值
示例:
specify (in => out) = 7; // 模块路径延迟
assign #4 out = int2; // 连续赋值延迟
buf #3 buf1(int1, in); // 原语延迟
• +delay_mode_path → 总延迟=7时间单位。
• +delay_mode_distributed → 总延迟=4+3+3=10时间单位。
4.4无匹配条件时的延迟标注
• +ignorempcond运行时选项:
当输入变化无匹配条件时,忽略条件检查并应用最小延迟。
• 扩展选项:
+ignorempcond=match_min # 应用所有适用延迟中的最小值
+ignorempcond=match_max # 应用最大值
5.使用配置文件禁用时序控制
可以通过VCS配置文件在指定模块实例或所有模块定义实例中禁用以下时序相关功能:
1. 模块路径延迟(Module Path Delays)
2. specify块
3. 时序检查(Timing Checks)
配置时需使用instance、module和tree语句(与Radiant Technology配置方式相同),并通过以下属性关键字控制:
noIopath
禁用指定模块实例中的模块路径延迟
Iopath
启用指定模块实例中的模块路径延迟
noSpecify
禁用指定模块实例中的specify块
Specify
启用指定模块实例中的specify块
noTiming
禁用指定模块实例中的时序检查
Timing
启用指定模块实例中的时序检查
6.使用 timopt 时序优化器
功能概述
timopt 时序优化器可为全时序门级设计提供显著的仿真加速效果。该工具通过分析设计中的时钟信号和推断出的时序器件(如触发器)进行优化,特别适用于使用SDF文件的反标场景(与 Radiant 技术不兼容)
可以通过以下编译选项启用timopt时序优化器:
+timopt
+timopt[timopt]
+timopt+clock_period
其中clock_period参数需设置为设计中时钟信号的最短周期。例如:
+timopt+100ns表示最短时钟周期为100ns。
timopt首先会显示设计中发现的时序单元总数及可优化时序单元数量,例如:
随后显示实际可优化的时序单元比例及优化过程信息:
下一步是通过仿真验证timopt的优化效果。若效果不理想,可采取以下步骤获取更多优化:
当timopt能完全确认所有时钟信号和时序单元时,会直接应用优化。若存在不确定性,可通过以下流程最大化优化效果:
1)timopt会在当前目录生成timopt.cfg配置文件,列出存疑的信号和时序单元
2)检查并编辑该文件,确认其中信号是否为时钟信号、模块定义是否为时序单元,无需修改则跳转至步骤5,有修改则继续步骤3
3)使用+timopt+clock_period选项重新编译设计
timopt将对首次编译时因不确定而未优化的部分进行补充优化
4)再次检查timopt.cfg文件:
若无新增条目,跳转至步骤5
有新增条目但未修改,跳转至步骤5
修改了新增条目,则返回步骤3
5)此时timopt无需再查找时钟信号,可认为timopt.cfg已正确指定时钟信号和时序单元
仅需应用最新优化,使用不带clock_period参数的+timopt选项重新编译
6)使用timopt优化进行设计仿真
若发现假设错误(如时钟周期错误或存在异步控制端口),timopt会显示类似警告:
Timopt Warning: for clock testbench.clockgen..clk:
TimePeriod 50ns Expected 100ns
编辑timopt.cfg文件时,先处理时序单元条目,确认无需修改后再处理时钟信号条目。
时序单元条目编辑示例:
// POTENTIAL SEQUENTIAL CELLS
// flop {jknpn} {,};
// flop {jknpc} {,};
// flop {tfnpc} {,};
修改后示例:
flop { jknpn } { CP, true};
flop { jknpc } { CP, true, CLN};
flop { tfnpc } { CP, true, CLN};
其中CP表示时钟端口,true表示时序单元在时钟上升沿触发,CLN为异步端口。
时钟信号条目编辑示例:
clock {
// test.badClock , // 1
test.goodClock // 2000
} {100ns};
该例中test.badClock因仅连接1个时序单元被注释,test.goodClock连接2000个时序单元保留。要启用被注释的时钟信号,只需移除其层次名前注释符号。