3. 门级仿真库与模型准备
门级仿真的第一步不是写 testbench,而是把“库”和“模型”准备正确。RTL 仿真只依赖 Verilog 行为模型,而门级仿真要同时面对工艺库的时序信息、标准单元的仿真模型、IO 单元和存储器宏模型。任何一处配置错误,都会表现为 X 传播、时序全为 0、SDF 反标失败或仿真速度骤降。本节围绕 Synopsys 工艺库的组织方式、标准单元仿真模型的来源与选择、IO 与存储器模型的配置方法,以及最常见的陷阱展开。
一、Synopsys 工艺库的组成与 db 与仿真模型的关系
在 Synopsys 流程中,工艺库通常以 .db 形式提供给 DC/ICC 等综合与布局布线工具,而仿真需要的是 Verilog 仿真模型和 SDF 时序文件。二者来源相同但用途不同:.db 是二进制时序库,供综合工具计算路径延迟;仿真模型是标准单元的 Verilog 行为描述,供 VCS 等仿真器实例化并计算延迟。典型目录结构如下:
lib/
sc9mc_logic_tt_1v0_25c.db # 综合用时序库
sc9mc_logic_tt_1v0_25c.lib # 可读文本库
sc9mc_logic_tt_1v0_25c.sldb # 符号库
verilog/
sc9mc_logic.v # 标准单元仿真模型
sc9mc_io.v # IO 单元仿真模型
sc9mc_memory.v # 存储器仿真模型
sdf/
sc9mc_logic_tt_1v0_25c.sdf # 时序反标文件
关键点在于:仿真模型必须与综合所用库的工艺角一致。若综合用 tt(typical)库,仿真却加载 ss(slow)模型,则时序分析结果与综合预期不符。常见做法是在 VCS 编译时通过 -y 指定库目录,并用 +libext+.v 让仿真器自动查找模块:
vcs -full64 -sverilog \
-y $LIB_DIR/verilog \
+libext+.v \
+define+TSMC_CM_NO_WARNING \
-top tb_top \
-l compile.log
这里 -y 告诉 VCS 在指定目录中按模块名查找文件,+libext+.v 限定扩展名。若库文件命名与模块名不一致,或目录层级不对,VCS 会报 “module not found”,此时应检查文件内 module 名是否与文件名匹配。
二、标准单元仿真模型的来源与选择
标准单元仿真模型通常由 foundry 提供,常见形式有三种:行为级模型、带时序的 Verilog 模型、以及用于 SDF 反标的 specify 块模型。行为级模型只描述逻辑功能,延迟为 0,适合功能验证;带 specify 块的模型才支持 SDF 反标,用于时序验证。选择时需确认模型是否包含 specify 和 endspecify,以及是否支持 $sdf_annotate。
一个典型的带时序标准单元模型片段如下:
module NAND2X1 (A, B, Y);
input A, B;
output Y;
nand (Y, A, B);
specify
(A => Y) = (0.12, 0.10);
(B => Y) = (0.13, 0.11);
endspecify
endmodule
其中 (0.12, 0.10) 表示上升延迟 0.12ns、下降延迟 0.10ns。若模型中没有 specify 块,SDF 反标会报 “no specify block” 警告,时序信息无法生效。另一个陷阱是模型中的 timescale 与 testbench 不一致,导致延迟被放大或缩小 1000 倍。建议在 testbench 顶部统一声明 `timescale 1ns/1ps,并确认库模型使用相同或兼容的时间单位。
三、IO 与存储器模型的配置
IO 单元模型比标准单元复杂,通常包含电源、地、上拉/下拉、施密特触发等行为。配置时需注意:IO 模型的端口顺序必须与网表中实例化一致,否则会出现电源短路或 X 传播。存储器模型则通常以 behavioral 或 functional 形式提供,部分 foundry 会提供带时序检查的 memory_model。配置存储器时,要确认地址位宽、数据位宽、深度与网表一致,并检查是否需要在仿真时加载初始化文件:
initial begin
$readmemh("mem_init.hex", u_mem.mem_array);
end
若存储器模型内部已包含初始化逻辑,重复加载会导致冲突。此外,存储器模型往往有 setup/hold 检查,若 testbench 在时钟沿附近改变地址,会报 timing violation。此时应检查激励是否满足存储器数据手册的时序要求,而不是简单屏蔽检查。
四、常见陷阱与排查路径
门级仿真库配置的陷阱集中在四类:库版本不匹配、SDF 反标失败、模型缺失 specify 块、以及 timescale 不一致。下图给出从编译到反标的排查路径,帮助快速定位问题。
实际项目中,建议在编译脚本中固定库路径和工艺角,并在仿真日志中搜索 “Warning” 和 “Error” 关键字。若 SDF 反标成功,日志会显示 “SDF annotation completed”;若失败,会提示具体模块和原因。对于 IO 和存储器模型,优先使用 foundry 提供的版本,不要自行修改模型内部逻辑,否则可能掩盖真实时序问题。
- 库文件目录是否包含
verilog/子目录,且文件名与模块名一致? - VCS 编译是否使用
-y和+libext+.v? - 标准单元模型是否包含
specify块? - testbench 与库模型的
timescale是否一致? - SDF 文件路径和工艺角是否与仿真库匹配?
- IO 模型端口顺序是否与网表实例化一致?
- 存储器模型是否需要
$readmemh初始化,是否与内部初始化冲突?
完成库与模型准备后,下一步才是编写门级 testbench 和运行仿真。库配置的正确性直接决定后续时序分析的可靠性,因此建议在项目初期就建立固定的库目录结构和编译脚本,避免每次仿真都重新排查环境问题。