Verilog是由一个个module组成的,下面是其中一个module在网表中的样子,我只需要提取module名字、实例化关系。
module rst_filter (
...);
端口声明...
wire定义...
FUBS7T rst_n_ext_sync1_reg (.D(rst_n_ext),
.Q(rst_n_ext_sync1),
.T(clk));
FUBS7T rst_n_ext_sync2_reg (.D(rst_n_ext_sync1),
.Q(rst_n_ext_sync2),
.T(clk));
FUDS7T low_filter_cnt_reg_0_ (.D(n39),
.Q(low_filter_cnt[0]),
.R(por),
.T(clk));
V01S7T U3 (.A(low_filter_cnt[6]),
.Y(n9));
V01S7T U4 (.A(low_filter_cnt[4]),
.Y(n15));
AN3S7T U5 (.A(low_filter_cnt[0]),
.B(low_filter_cnt[1]),
.C(low_filter_cnt[2]),
.Y(n41));
N02S7T U6 (.A(n41),
.B(low_filter_cnt[3]),
.Y(n17));
R02S7T U7 (.A(n15),
.B(n17),
.Y(n13));
//...
endmodule
来观察规律:
所以写正则还是比较简单的。
def read_vlog.NETlist(vlog_file):
vlog_lines = open(vlog_file, 'r').readlines()
#get inst tree
module_start = 0
modules = {}
for line in vlog_lines:
module_start_m = re.search('modules+(w+)', line)
inst_m = re.search('s+(w+)s+(w+)s*(', line)
module_end_m = re.search('endmodule', line)
if module_start_m:
module_start = 1
module = {}
module_name = module_start_m.group(1)
module['module_name'] = module_name
insts = {}
module['insts'] = insts
modules[module_name] = module
if module_end_m:
module_start = 0
if inst_m:
module_name = inst_m.group(1)
inst_name = inst_m.group(2)
insts[inst_name] = module_name
return modules
数据存储结构:
modules = {
"module1": {
"module_name": module1,
"module_inst": {
"inst1": "stdcell1",
"inst2": "stdcell2",
...
}
}
"module2": {
...
}
"module3": {
...
}
}
测试一下:
import netlistparser as nl
modules = nl.read_vlog_netlist("digital_pr.v")
print(json.dumps(modules, indent=4))
结果输出如下。是不是效果还不错!
{
"spr_1": {
"module_name": "spr_1",
"insts": {
"spr_gate806": "V01S7T",
"spr_gate805": "V01S7T",
"spr_gate804": "V01S7T",
"spr_gate803": "V01S7T",
"spr_gate802": "V01S7T",
...
}
},
"gclk_3": {
"module_name": "gclk_3",
"insts": {
"icg": "TLATNTSCAL7T"
}
},
"rst_filter": {
"module_name": "rst_filter",
"insts": {
"rst_n_ext_sync1_reg": "FUBS7T",
"rst_n_ext_sync2_reg": "FUBS7T",
"low_filter_cnt_reg_0_": "FUDS7T",
"low_filter_cnt_reg_9_": "FUDS7T",
...
}
},
...
}
总结:
正则不难,难的是善于总结和灵活应用。定义合理的数据存储结构也是非常重要的,后续操作会简便很多。