备份与还原仿真状态
当混仿已经跑了很长时间,却必须中断时(如即将断电),或者当混仿初始化序列很长时,可以将仿真数据备份,下次可从当前状态还原。
只有使用VCS® AMS或FineSim® VCS工具时可以备份和还原仿真状态。
备份和还原状态的基本方法
在UCLI交互模式下,使用save
和restore
指令可以实现上述功能,如:
% simv -ucli
ucli% run 100ns
ucli% save sim_state_100ns
ucli% quit
% simv -ucli
ucli% restore sim_state_100ns
ucli% run
高级用法:运行多次仿真
当仿真的初始化时间很长时,可以在完成初始化的时间节点将仿真状态备份,然后在后续需要运行不同的testbench时,可以先还原至初始化后的状态,然后运行不同的测试用例。假设testbench如下:
module tb;
int tst;
...
case (tst)
1: test1( ); // Run test No 1
2: test2( ); // Run test No 2
3: test3( ); // Run test No 3
4: test4( ); // Run test No 4
5: test5( ); // Run test No 5
default: tst0 ( );
endcase
...
end
补图17
仿真过程中改变模拟配置
基于上一节备份和还原仿真状态中的特性,CustomSim和FineSim工具支持在仿真过程中使用 ace reread
UCLI指令,来修改模拟配置,如仿真精度、温度等。
ace reread指令
语法:
ace reread [-c config_file] [-ad control_file] [-o output_file_name]
Options | Description |
---|---|
-c config_file | 指定新的CustomSim配置文件,或为FineSim指定新增的指令文件 |
-ad control_file | 指定新的混仿控制文件(文件只能修改e2r 和r2e 接口的hiz 属性) |
-o output_file_name | 指定输出文件名字 |
该指令只能用于修改模拟配置,不能用来修改VCS命令或数字网表。而且,该指令不能对模拟网表进行结构化改变,如不能修改例化目标、例化名、管脚名、管脚数量等,只能修改温度、SPICE options、仿真精度、馈电电压电流值等不影响模拟网表结构的参数。
在配置文件中允许的更改
仅限CustomSim工具。
可以更改set_sim_level
,set_tolerance_level
, set_ccap_level
, 和 set_model_level
等精度命令,并使用 reread
指令使之生效。
在SPICE文件中允许的更改
可以更改电容、电阻、温度、SPICE stimuli,添加或删除probes。
不可以修改.tran
的值。
通过反标进行布局后仿真
若在SPICE下例化verilog模块,需要用DSPF 和 SPEF反标模拟模块,用SDF反标verilog模块;
若在verilog下例化SPICE网表,需要用HSPF/HSPEF反标模拟模块,依旧用SDF反标verilog模块。
使用SDF文件
与纯数字设计中的反标一致,使用系统任务$sdf_annotate
指定将要被反标的verilog模块,如
module my_back_annotation();
initial $sdf_annotate("./dut.sdf",top);
endmodule
其中,参数top
代表将被反标的verilog模块名。
混合信号设计中的Meta-Encrypted SPICE网表
VCS AMS和FineSim工具支持加密的SPICE子电路。这些加密的SPICE电路可以被应用于HDL-top、SPICE-top或donut配置中。
但是,加密的SPICE子电路相当于一个黑盒,无法看到内部结构,也不能使用use_verilog
或use_vhdl
映射内部的任何模块。如果加密SPICE子电路在数模边界上,工具会自动插入接口元件。
在数模边界上的SDF反标
数模边界上反标的限制条件:
- 在VCS指令中添加
+msvsdf
选项vcs options -ad +msvsdf …
- 跨越混合信号边界的线网定义的SDF延迟必须是
INTERCONNECT
类型,并且必须从一个模块的输出端口连接到另一个模块的输入端口。 - 如果线网定义了SDF反标延迟,并且该线网跨越了数模边界,则应在数字端使用SDF反标延迟。
- 被标记的线网一定要在Verilog中连接。也就是说,
hi-conn
必须在Verilog中。如果在SPICE中连接,则延迟不会被标记。 - 必须只有一个驱动。不能使用SDF标记双向接口。
- 可以反标多个负载。从驱动到每个负载的延时都可以被标记。
- 如果例化在数字模块中的线网用于连接两个模拟模块(a2a through-net),SDF不反标。此外,模拟信号将相互连接在一起,形成一个SPICE节点。
- 如果例化在模拟模块中的线网用于连接两个数字模块(d2d through-net),SDF不反标
- 不支持VHDL
Testbench复用时实例名冲突
在某些SPICE仿真器(如HSPICE和Eldo)中,模拟子电路的实例名需要以字母“x”开头,而数字端view则不需要“x”,导致同一个模块的实例化,Verilog view和SPICE view的名称不一致:
// 注意下面的 g1,g2,g3 和 xg1,xg2,xg3 的区别
// Verilog dut
module dut (out,clk);
output out;
input clk;
inv1 g1 (net1,clk);
inv2 g2 (net2,net1);
inv3 g3 (out,net2);
endmodule
* SPICE dut
.subckt dut out clk
xg1 net1 clk inv1
xg2 net2 net1 inv2
xg3 out net2 inv3
.ends
在例化时,如果调用时例化名缺少“x”,使用 $hdl_xmr 来访问 top.g1.g2.Y 节点时,工具可能报error。如:
$hdl_xmr("top.g1.g2.Y","xmr",1);
Source signal ‘top.g1.g2.Y’ could not be found in the design.
为此,需要修改例化部分语句为:
$hdl_xmr("top.xg1.xg2.Y","xmr",1);
然而,每次因为冲突都去修改设计显得很麻烦,所以可以使用resolve_x_inst_prefix enable
来自动解决这个问题。
在 vcsAD.init 文件中,添加一句 resolve_x_inst_prefix enable;
,那么后续无论是例化Verilog还是SPICE,都可以使用 $hdl_xmr(“top.g1.g2.Y”,“xmr”,1); 成功访问该模块。
编译后并行仿真
如果在编译后希望并行运行多个仿真,仿真器会将多个仿真结果输出到同一目录下,导致运行失败。为此,我们需要为每个仿真结果指定单独的输出路径,或者提前创建多个目录,将命令文件拷贝到每个目录下,然后分别运行。
使能并行仿真
为使能并行仿真,可以在 vcsAD.init 文件中添加指令:
report_option msv_dir = spice;
report_option
命令可以指导工具产生多个报告目录,防止运行多个仿真时将结果写入到同一文件下。
创建单独的输出文件
使用CustomSim和FineSim工具时,可以在并行仿真前设置不同的配置,如下:
# Start first simulation in background
% ./simv \
+TEST1 \
-ucli \
-do Vcs1.ucli \
-l simv1.log \
-ad_runopt=analogconfig:anlg_run_1.do &
# Start second simulation in foreground
% ./simv \
+TEST2 \
-ucli \
-do Vcs2.ucli \
-l simv2.log \
-ad_runopt=analogconfig:anlg_run_2.do
CustomSim的配置
# anlg_run_1.do for CustomSim
change_choose_arguments -o ./xaRun1/anlg_dir_1 -c xa1.cfg
# anlg_run_2.do for CustomSim
change_choose_arguments -o ./xaRun2/anlg_dir_2 -c xa2.cfg
FineSim的配置
# anlg_run_1.do for FineSim
change_choose_arguments -o ./fsRun1/anlg_dir_1 -afile run1.spi
# anlg_run_2.do for FineSim
change_choose_arguments -o ./fsRun2/anlg_dir_2 -afile run2.spi
从数字域访问、驱动与释放模拟信号
通过XMR访问SPICE节点
XMR:cross module referencing
该方法可将SPICE节点视为一个逻辑值(区别于通过特化的系统函数访问SPICE节点),如下列语句可将SPICE节点的电压值转换为对应的逻辑值,再进行赋值:
assign verilog_wire = top.i1.i2.x1.clk;
也可以赋值给寄存器:
initial begin
verilog_reg = top.i1.i2.x1.strb;
end
反之,也可以把数字逻辑转换为模拟电压值,再传递给SPICE节点:
assign top.i1.i2.x1.rst = rst_reg;
对于总线信号,需要使用大括号“{}”将所有的SPICE总线成员括起来,如:
wire [2:0] verilog_wire;
assign verilog_wire = {top.x1.a_2, top.x1.a_1, top.x1.a_0};
通过hdl_xmr等访问SPICE节点
设计中包含VHDL代码时可以使用。描述略。
举例:
module inv (y, in);
input in;
output y;
voltage_r y, in; // y and in are defined as voltage_r type
...
endmodule
module top();
inv m1(y, in);
initial begin
#50 $hdl_xmr_force ("top.m1.y","0.33","50ns", , , 1);
#10 $hdl_xmr_release ("top.m1.y", 1 );
end
endmodule
通过特化的系统函数访问SPICE节点
该方法可将SPICE节点视为一个实数值(区别于通过XMR访问SPICE节点),不过这些方法不适用于VHDL/Verilog-SPICE and Verilog-AMS-SPICE flows。
-
$snps_force_volt()
此方法可修改SPICE节点上的电压值,即使该节点连接了理想电压源,也能将其覆盖。
语法:$snps_force_volt (SPICE_node_name, verilog_real_value | verilog_real_variable);
举例:$snps_force_volt (top.i1.spcell.n1, 3.3);
-
$snps_inject_current()
此方法可为SPICE节点加入额外电流。
语法:$snps_inject_current (SPICE_node_name, verilog_real_value | verilog_real_variable);
举例:$snps_inject_current (top.i1.spcell.n1, 20.0e-6);
仅支持CustomSim,不支持FineSim
-
$snps_release_volt()
此方法可释放SPICE节点上人为施加的电压,此后电压值完全由SPICE电路决定。
语法:$snps_release_volt (SPICE_node);
举例:$snps_release_volt (top.i1.spcell.n1);
-
$snps_get_volt()
此方法可获取SPICE节点的电压值。
语法:$snps_get_volt (SPICE_node_name);
举例:real_var = $snps_get_volt(top.i1.spcell.n2);
-
$snps_get_port_current()
此方法可获取SPICE子电路端口或原始pin管脚上的电流。
语法:$snps_get_port_current (SPICE_port_name | spice_primitive_pin);
举例:real_var = $snps_get_port_current(top.i1.amp.out);
-
snps_above()
此方法可用来检测SPICE节点电压值是否高于或低于某门限。
语法:snps_above ( expression );
举例:// top.dut.x4.rst电压值高于1.85V的时候 always @ (snps_above($snps_get_volt(top.dut.x4.rst) - 1.85)) begin ... end // test_top.i1.x3.strb电压值低于0.9V的时候 always @ (snps_above(0.9 - $snps_get_volt(test_top.i1.x3.strb))) begin ... end
-
snps_cross()
此方法可用来检测SPICE节点电压值跨越某门限的时刻。
语法:snps_cross ( expression, dir );dir: 为1时代表posedge,为-1时代表negedge,为0时代表双边沿检测
举例:
// top.dut.x4.rst电压值跨越1.85V的正边沿 always @ (snps_cross($snps_get_volt(top.dut.x4.rst) - 1.85)) begin ... end // test_top.i1.x3.strb电压值跨越0.9V的正负边沿 always @ (snps_cross(0.9 - $snps_get_volt(test_top.i1.x3.strb))) begin ... end
通过UCLI访问SPICE节点
语法:force node value time 或 release node
举例:
ucli% run 20ns
ucli% force top.g1.g2.y 1
在数模边界控制仿真点数量
混仿工具会在数模边界上插入接口元件(interface elements,IEs)。
数到模:插入nettype-to-electrical (n2e) 接口元件
模到数:插入electrical-to-nettype (e2n) 接口元件
为了权衡性能和精度,可以使用min_delta
和max_delta
参数来控制仿真事件的数量。
-
模拟端电压值变化很小时,可以设置
min_delta
来过滤这些微小的变化。假设最小的信号变化为10mV,命令:e2n min_delta=10m node=top.n1;
那么,修改前后边界上的仿真点数量变化如下图:
-
模拟端电压值变化很大时,可以设置
max_delta
来观测变化的过程。假设最大的信号变化为20mV,命令:e2n max_delta=20m node=top.n2;
那么,修改前后边界上的仿真点数量变化如下图:
-
数字端逻辑值的变化很多,但反应在模拟端电压值变化很小时,可以设置
min_delta
来过滤这些微小的变化。假设最小的信号变化为10mV,命令:n2e min_delta=10m node=top.n1;
那么,修改前后边界上的仿真点数量变化如下图:
混仿时执行蒙特卡洛分析
蒙特卡洛方法可用来分析随机扰动对电路性能的影响。
连续性蒙特卡洛分析
连续性蒙特卡洛分析需在单台机器上运行。
在.TRAN声明中,添加SWEEP MONTE
关键字,然后照常运行即可。
.TRAN ... SWEEP Monte=val | parameter [firstrun=firstnum]
.TRAN ... SWEEP Monte=list(list_specification)
使用CustomSim时输出文件
在vcsAD.init文件中添加choose xa -o results/xa ...
,并使用vcs ... -o simv -l compile.log
启动仿真后,工具将生成如下文件:
rundir/results/
xa.pvadir/, xa.fsdb.grp, xa.log, xa.mc, xa.mc.csv,
xa.mc_params, xa.meas, xa.valog (XA files)
rundir/results/mc1/
xa.pvadir/, xa.m1.fsdb, xa.m1.meas, xa.ma, xa.valog
(Iteration-specific XA files)
rundir/results/mc2/
xa.pvadir/, xa.m2.fsdb, xa.m2.meas, xa.ma, xa.valog
(Iteration-specific XA files)
…
仿真后,生成的波形文件如下:
rundir/results/
xa.pvadir/, xa.fsdb.grp, xa.log, xa.mc, xa.mc.csv,
xa.mc_params, xa.meas, xa.valog (XA files)
rundir/results/mc1/
xa.pvadir/, vcs.m1.fsdb, xa.m1.fsdb, xa.m1.meas, xa.ma,
xa.valog (Iteration-specific XA files & VCS waveform files)
rundir/results/mc2/
xa.pvadir/, vcs.m2.fsdb, xa.m2.fsdb, xa.m2.meas, xa.ma,
a.valog (Iteration-specific XA files & VCS waveform files)
…
使用FineSim时输出文件
FineSim工具不会创建新的目录,而是会在文件名后添加后缀,即
fs.fsdb -> fs_s1.fsdb, fs_s2.fsdb
在vcsAD.init文件中添加choose finesim -o results/fs ...
,并使用vcs ... -o simv -l compile.log
启动仿真后,工具将生成如下文件:
rundir/results/
fs.pvadir/, fs.ic, fs.im, fs.log, fs.mt0, fs.valog,
fs_s1.fsdb , fs_s2.fsdb,…, fs_sn.fsdb, etc (FineSim files)
仿真后,生成的波形文件如下:
rundir/results/
fs.pvadir/, fs.ic, fs.im, fs.log, fs.mt0, fs.valog,
fs_s1.fsdb , vcs.m1.fsdb, fs_s2.fsdb, vcs.m2.fsdb, …,
fs_sn.fsdb, vcs.mn.fsdb, etc (FS files & VCS waveform files)
限制
- 不支持备份/还原功能
- 不支持
ucli2proc
选项 - FineSim的蒙特卡洛分析不会生成波形组文件( *.grp ).
分布式蒙特卡洛分析
蒙特卡洛分析可在计算机集群上分布执行。
.TRAN声明与连续性蒙特卡洛分析中一致。
为了将仿真分配在不同机器上,必须使用-ad_runopt
选项来分配工作:
simv -ad_runopt=analogconfig:dp:worker#:[dp_cfg_file]:[dp_location]
参数说明
Parameter | Description |
---|---|
dp | Keyword to enable distributed Monte Carlo analysis. |
worker# | Specifies the number of worker CPUs |
dp_cfg_file | Optional user-defined file. If not specified, uses the local host. |
dp_location | Optional, can be NFS or TMP. |
更多细节看官方user guide。
扫描与切换
扫描类型
-
参数扫描
语法:.TRAN tstep tstop [UIC] [SWEEP var type np pstart pstop]
或.TRAN tstep tstop [UIC] [SWEEP var start stop incr]
Argument Description var Can be an independent source, parameter, or temperature. type Can be lin , poi , dec , or oct . np Specifies the number of points for lin or poi or the number of points per decade or octave for dec and oc sweeps, respectively. pstart Specifies the first point of a range of parameter values. pstop Specifies the final point of a range of parameter values. -
数据扫描
可以在.DATA模块中扫描参数。
例如:.TRAN 1ns 100ns sweep DATA=data1 .DATA data1 param1 param2 10 20 30 40 .ENDDATA data1
-
温度扫描
例如:.TEMP 10 20 30 .TRAN 10ns 1us UIC SWEEP TEMP -55 75 10 .TRAN 1ns 100ns sweep DATA=data1 .DATA data1 temp p2 0 20 25 30 125 40 .ENDDATA data1
-
模块切换
.ALTER
声明可以对一个网表用另一组配置重新进行仿真。修改一个参数
.alter rvalue=100
修改库
.alter .del lib 'mymodel.l' TT .lib 'mymodel.l' SS
修改温度和阻值
.alter rval=3k .temp 110
组合扫描
可以将上一节参数组合在一起,同时修改,如:
.temp 0 25 55 $3pts
.tran .1p 2n sweep vset 1.3 1.7 0.1 $5pts
.lib 'cln90g_lk.l' TT
.measure tran vo1 find v(aout) when v(in)=0.5 fall=2
.alter $2pts
.lib 'cln90g_lk.l' FF
.end
分布式扫描和切换
在运行时,添加dp
选项:
simv -ad_runopt=analogconfig:dp:worker#:[dp_cfg_file]:[dp_location]
更多细节看官方user guide。
为接口元件指定参考电压
优先级
指定接口元件电压水平的方式有很多,如果对同一元件定义了多种规范,那将按照以下优先级顺序对待它们:
(1优先级最高,4优先级最低)
- 用户定义的a2d/d2a门限
- ie_reference_voltage节点
- 与接口元件相关联的理想馈电源
- 找不到相关联的节点,使用默认值(3.3V)
当接口元件没有使用a2d
或d2a
命令指定电压或门限时,它们会通过寻找与其相连的晶体管或电阻并自动定位到对应的电压基准,但工具不能保证在所有情况下都能定位到正确的电压基准。
为此,可以使用ie_reference_voltage
命令定义一个参考节点来指导工具去寻找基准。
- 静态电压基准
所有与某节点相关联的接口元件都使用该节点的电压值。ie_reference_voltage node=node_name voltage=value;
- 动态电压基准
如果某节点电压不是定值,那么与它相关联的接口元件的基准电压动态变化。ie_reference_voltage node=node_name ;
- 例1
假如变压器输入电压5V,输出电压1.5V。输出端连接着SPICE电路。那么对于SPICE电路的接口元件来说,它们的参考电压可以定义为:ie_reference_voltage node=A1 voltage=1.5; //static // or ie_reference_voltage node=A1; //dynamic
- 例2
假如例1中SPICE电路的馈电源是另一个接口元件,那么可以定义:ie_reference_voltage node=A1; // 这等效于定义: d2a node=top.i1.abc hiv=100% lov=0% VDD=A1; a2d node=top.i1.def hith=50% loth=50% VDD=A1;
运行期间查看和修改接口元件选项
混仿启动后,如果想要查看或修改接口元件的选项,不用重启仿真,可以使用UCLI的ace
指令来实现。
查看接口元件细节
语法:ucli% ace show_ie [type=IE_type] node=node_name [mode=concise|verbose]
其中,IE_type
选项有d2a、a2d、n2e、e2n、r2e、e2r。
默认使用concise
模式。
- 例1:显示特定节点的接口元件细节
ucli% ace show_ie node=top.dut.cin d2a hiv=3.3v lov=0v node=top.dut.cin
- 例2:使用
verbose
模式显示所有信息ucli% ace show_ie node=top.dut.cin mode=verbose d2a hiv=3.3v lov=0v rf_time=1e-11 rise_time=1e-11 fall_time=1e-11 delay=0 x_state=0 x2v=0 vdd_filter=0 node=top.dut.cin
- 例3:显示所有a2d类型的接口元件
ucli% ace show_ie type=a2d node=* a2d loth=1.65v hith=1.65v node=top.dut.s_3 a2d loth=1.65v hith=1.65v node=top.dut.s_2
运行时修改接口元件选项
语法:ace element_type
例:修改所有d2a元件的属性
ucli% ace d2a hiv=3.7 lov=0.22 rise_time=3e-09 fall_time=4e-09 \
delay=1e-09 node=top.dut.a_3
添加网表指令到控制文件
使用CustomSim或FineSim工具时,可以在vcsAD.init中添加仿真指令。
- 对于FineSim工具,可在
netlist_commands_begin
和netlist_commands_end
中添加一系列运行指令。
下例展示了如何指定温度:spice_top; bus_format [%d]; use_verilog -module addr4; choose finesim top.spi -o results/fsim/fsim; netlist_commands_begin; .temp 45 # 这里指定温度 netlist_commands_end;
- 对于CustomSim工具,可在
customsim_commands_begin
和customsim_commands_end
之间添加一系列运行指令。customsim_commands_begin; set_sim_level 5 customsim_commands_end;