雖然dc也有report_area -hier命令來報告各級模塊的面積,本python方案看似有點造輪子,但還是有一定的便利性。一、不受網表類型的限制,綜合網表、DFT網表、APR都可以。二、可以過濾面積小于指定值的小模塊,比如工具自動插入的ICG模塊。三、還可以根據面積占比做排序,方便分析面積的瓶頸。
一、讀入網表
下面先讀入網表,并分模塊識別每個模塊內部的stdcell和子模塊。這部分與《用python實現分模塊按cell類型統計cell個數并降序排列》的方法相同,所以這里直接導入netlistparser.py。
import netlistparser as nlparser import sys vlog_netlist_file = sys.argv[2] modules=nlparser.read_vlog_netlist(vlog_netlist_file)
這樣網表就讀到了內部python字典里,結構如下:
{
"moduleA": {
"module_name": "moduleA",
"insts": {
"u_AND2_01":"AND2X1",
"u_AND2_02": "AND2X1",
"u_OR2_01":"OR2X1",
"u_INV_01":"INVX1"
}
},
"moduleB": {
"module_name": "moduleB",
"insts": {
"u_AND2_01": "AND2X1",
"u_AND2_02": "AND2X1",
"u_OR2_01": "OR2X1",
"u_INV_01": "INVX1"
}
},
}
二、讀入lib庫
stdcell的面積信息存儲在fab提供的lib文件里,所以我們需要從lib里讀到每種cell的面積,方法如下:
# libparser.py
import sys
import re
import json
def read_library(file_name):
cells = {}
lib_lines = open(file_name, 'r').readlines()
cell_start = 0
pin_start = 0
total_lines = len(lib_lines)
print('')
for i in range(total_lines):
line = lib_lines[i]
print('33[1F {}%'.format(round(100 * i / total_lines)))
cell_s_m=re.search(r'cells*((w+))s+{',line)
area_m=re.search(r'sareas+:s+(S+)s*;',line)
pin_s_m = re.search(r'spin((w+))s+{', line)
dir_m = re.search(r'sdirections+:s+(w+)', line)
func_m = re.search(r'sfunctions+:s+"(.*)"', line)
end_m = re.search(r'}', line)
if cell_s_m:
cell_start = 1
cell = {}
cell_name = cell_s_m.group(1)
cell['cell_name'] = cell_name
pins = []
cell['pins'] = pins
cells[cell_name] = cell
if cell_start and area_m:
area = area_m.group(1)
cell['area'] = round(float(area), 4)
if cell_start and pin_s_m:
pin_start = 1
pin = {}
pin_name = pin_s_m.group(1)
pin['pin_name'] = pin_name
if cell_start and dir_m:
pin_dir = dir_m.group(1)
pin['pin_dir'] = pin_dir
if cell_start and func_m:
pin_func = func_m.group(1)
pin['pin_func'] = pin_func
if cell_start and pin_start and end_m:
pin_start = 0
pins.append(pin)
return cells
def get_cell_area(cells, cell_name):
if cell_name in cells:
return cells[cell_name]['area']
else:
return 0
def is_libcell(cells, cell_name):
if cell_name in cells:
return True
else:
return False
def write_lib_info(lib_info, file_name):
f = open(file_name, 'w')
f.write(json.dumps(lib_info, indent=4))
f.close()
其中,read_library()函數實現了用正則讀取lib文件里的cell名字、area、pin、pin方向、function等信息。今天只需要用到cell名字和面積。其它信息是為了后續擴展其它功能做準備。
get_cell_area()提供了讀取指定cell面積的接口。is_libcell()實現了判斷是libcell還是一般的設計上的子模塊。
write_lib_info()可以將lib庫的字典寫到json文件里,方便調試。
接下來,用這個libparser讀入lib庫:
import libparser import sys lib_file = sys.argv[1] lib_info=libparser.read_library(lib_file)
三、面積遞歸統計
我們從top design開始,當遇到stdcell中的cell則累加,當遇到子模塊則遞歸。直到子模塊不再含有其它子模塊(僅由stdcell組成)時,則返回。
area_info = {}
def report_area(modules, lib_info, module_name):
global area_info
area = 0
insts = modules[module_name]['insts']
for inst in insts:
cell_inst = inst
cell_type = insts[inst]
if cell_type in area_info:
area = area + area_info[cell_type]
elif libparser.is_libcell(lib_info, cell_type):
area = area + libparser.get_cell_area(lib_info, cell_type)
else:
#遞歸
report_area(modules,lib_info,cell_type)
area = area + area_info[cell_type]
area_info[module_name]=area
四、打印面積
打印的同時,可以做一些過濾或者排序。
for module in area_info:
if not re.search(r'CLOCK_GATE', module):
print(module, round(area_info[module], 4))
效果如下:

-
python
+關注
關注
57文章
4876瀏覽量
90034 -
網表
+關注
關注
0文章
15瀏覽量
7959
原文標題:用python實現網表分模塊統計面積
文章出處:【微信號:處芯積律,微信公眾號:處芯積律】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
請問python可以替代shell嗎?
如何利用Python判斷統計每個月天數源
使用Python DIY Arduino來顯示PC統計數據
淺析python模塊創建和from及import使用
Python實現OpenCV的安裝與使用
如何實現Python復制文件操作
光譜成像技術在作物面積統計中的應用
用python實現網表分模塊統計面積
評論