4. Verilog网表读入与层次化设计展开
任务说明
本案例使用 OpenROAD 的 Tcl 接口读入一个 Verilog 网表,执行层次展开(flatten),并统计展开前后的实例(instance)、线网(net)和端口(port)数量。核心命令为 read_verilog、link_design、flatten,统计通过 get_cells、get_nets、get_ports 完成。
环境与依赖
- OpenROAD 已编译并可在 PATH 中调用(
openroad命令可用)。 - 一个含层次结构的 Verilog 网表文件,本案例提供最小可复现示例。
示例网表
保存为 top.v。顶层 top 例化两个 sub,sub 内部再例化一个 leaf,形成三层层次。
module leaf (input a, input b, output y);
assign y = a & b;
endmodule
module sub (input a, input b, output y);
leaf u_leaf (.a(a), .b(b), .y(y));
endmodule
module top (input clk, input a, input b, output y0, output y1);
sub u_sub0 (.a(a), .b(b), .y(y0));
sub u_sub1 (.a(a), .b(b), .y(y1));
endmodule
OpenROAD 脚本
保存为 run.tcl。脚本读入网表、链接设计、统计层次展开前的数量,执行 flatten 后再统计一次。
read_verilog top.v
link_design top
proc report_counts {tag} {
set cells [llength [get_cells *]]
set nets [llength [get_nets *]]
set ports [llength [get_ports *]]
puts "\[$tag\] cells=$cells nets=$nets ports=$ports"
}
report_counts "before_flatten"
flatten
report_counts "after_flatten"
运行方式
openroad -no_init -exit run.tcl
验证方法与通过条件
- 脚本正常退出,无 Tcl 报错。
- 输出两行统计:
before_flatten与after_flatten。 - 展开前
cells应包含层次实例(u_sub0、u_sub1、u_leaf等),展开后层次被消除,cells数量按叶子单元展开后重新计算。 - 端口数量在展开前后保持一致(顶层端口不变),可作为一致性检查。
层次展开流程
常见问题
link_design报找不到模块:确认read_verilog已成功读入且顶层模块名与link_design参数一致。flatten后get_cells数量变化不明显:检查网表是否确实存在多级例化;单层网表展开前后数量可能相同。- 端口数量异常:确认顶层模块端口声明完整,未被优化掉。