雖然dc也有report_area -hier命令來報告各級模塊的面積,本python方案看似有點造輪子,但還是有一定的便利性。一、不受網(wǎng)表類型的限制,綜合網(wǎng)表、DFT網(wǎng)表、APR都可以。二、可以過濾面積小于指定值的小模塊,比如工具自動插入的ICG模塊。三、還可以根據(jù)面積占比做排序,方便分析面積的瓶頸。
一、讀入網(wǎng)表
下面先讀入網(wǎng)表,并分模塊識別每個模塊內(nèi)部的stdcell和子模塊。這部分與《用python實現(xiàn)分模塊按cell類型統(tǒng)計cell個數(shù)并降序排列》的方法相同,所以這里直接導(dǎo)入netlistparser.py。
import netlistparser as nlparser import sys vlog_netlist_file = sys.argv[2] modules=nlparser.read_vlog_netlist(vlog_netlist_file)
這樣網(wǎng)表就讀到了內(nèi)部python字典里,結(jié)構(gòu)如下:
{ "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()函數(shù)實現(xiàn)了用正則讀取lib文件里的cell名字、area、pin、pin方向、function等信息。今天只需要用到cell名字和面積。其它信息是為了后續(xù)擴展其它功能做準(zhǔn)備。
get_cell_area()提供了讀取指定cell面積的接口。is_libcell()實現(xiàn)了判斷是libcell還是一般的設(shè)計上的子模塊。
write_lib_info()可以將lib庫的字典寫到j(luò)son文件里,方便調(diào)試。
接下來,用這個libparser讀入lib庫:
import libparser import sys lib_file = sys.argv[1] lib_info=libparser.read_library(lib_file)
三、面積遞歸統(tǒng)計
我們從top design開始,當(dāng)遇到stdcell中的cell則累加,當(dāng)遇到子模塊則遞歸。直到子模塊不再含有其它子模塊(僅由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
+關(guān)注
關(guān)注
56文章
4782瀏覽量
84460 -
網(wǎng)表
+關(guān)注
關(guān)注
0文章
14瀏覽量
7631
原文標(biāo)題:用python實現(xiàn)網(wǎng)表分模塊統(tǒng)計面積
文章出處:【微信號:處芯積律,微信公眾號:處芯積律】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論