前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用python实现分模块按cell类型统计cell个数并降序排列

用python实现分模块按cell类型统计cell个数并降序排列

作者头像
ExASIC
发布2022-12-06 16:38:58
6990
发布2022-12-06 16:38:58
举报
文章被收录于专栏:ExASICExASIC

有同学想看看综合网表里某模块里and、or、inv等cell的个数,谁最多谁最少。虽然用dc的各种命令组合也可以实现,但今天我们用python来实现。

因为verilog网表非常有规律,很容易用正则来匹配,所以用python来做统计正合适。之前写过一篇文章:《用Python提取Verilog网表层次和实例化关系》,这篇文章已经实现了网表parser,基于这个脚本做统计就非常简单了。

网表parser

用三条正则'module\s+(\w+)','\s*(\w+)\s+(\w+)\s*\(','endmodule'来解析和拆分module、识别模块名、读取cell的类型和例化名。

代码语言:javascript
复制
# netlistparser.py
import sys
import json
import re


def read_vlog_netlist(vlog_file):
    """
    get insts by module
    """
    
    vlog_lines = open(vlog_file, 'r').readlines()    

    module_start = 0
    modules = {}
    for line in vlog_lines:
        module_start_m = re.search('module\s+(\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            
            
        elif module_end_m:
            module_start = 0

        elif module_start and inst_m:
            module_name = inst_m.group(1)
            inst_name = inst_m.group(2)
            insts[inst_name] = module_name

    return modules

if __name__ == '__main__':
    modules = read_vlog_netlist(sys.argv[1])
    print(json.dumps(modules, indent=4))

解析完成后,我们把数据放到dict里,方便存储成json,和进一步处理。格式如下:

代码语言:javascript
复制
{
"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"        
    }
},
}

统计cell类型和个数

从网表parser的数据dict里分模块取出module,遍历insts,在字典cell_count用cell类型做key存放cell的计数。

代码语言:javascript
复制
# cellinfo.py
import sys
import netlistparser as nlparser
import re
import json

def count_cells(modules):
    cells_info = []
    
    module_names = modules.keys()
    for module_name in module_names:
        cell_count = {}
        insts = modules[module_name]['insts']
        for inst in insts:
            cell_inst = inst
            cell_type = insts[inst]
            if cell_type in cell_count:
                cell_count[cell_type] = cell_count[cell_type] + 1
            else:
                cell_count[cell_type] = 1
        # sort by cell_type
        cell_count2 = dict_sort_by_val(cell_count)
        
        cells_info_module = {module_name : cell_count2}
        cells_info.append(cells_info_module)
        
    return cells_info

其中用了一个函数,按字典的value排序:dict_sort_by_val(),如下,先把dict转成list,用sorted对list排序,排序后再转为dict。

代码语言:javascript
复制
def dict_sort_by_val(d):
    keys = d.keys()
    values = d.values()
    l = [(key, val) for key, val in zip(keys, values)]
    l2 = sorted(l, key=lambda x:x[1], reverse=True)
    d2 = {}
    for k,v in l2:
        d2[k] = v
        
    return d2

写顶层调用:

代码语言:javascript
复制
if __name__ == '__main__':
    vlog_netlist_file = sys.argv[1]

    print('Read {} ...'.format(vlog_netlist_file))
    modules = nlparser.read_vlog_netlist(vlog_netlist_file)
    
    cells_info = count_cells(modules)
    print(json.dumps(cells_info, indent=4))

最终效果如下:

代码语言:javascript
复制
[
    {
        "cv32e40p_clock_gate": {
            "CKLNQD12BWP": 1
        }
    },
    {
        "cv32e40p_sleep_unit_PULP_CLUSTER0": {
            "DFCNQD1BWP": 2,
            "OR2D1BWP": 1,
            "OR4D1BWP": 1,
            "OA21D1BWP": 1,
            "cv32e40p_clock_gate": 1,
            "INR3D0BWP": 1
        }
    },
    {
        "cv32e40p_prefetch_controller_PULP_OBI0_PULP_XPULP0_DEPTH2_DW01_add_1": {
            "CKND2D1BWP": 23,
            "NR2XD0BWP": 18,
            "INVD1BWP": 17,
            "XOR2D1BWP": 15,
            "XNR2D1BWP": 9,
            "HA1D0BWP": 4,
            "HICIND1BWP": 1
        }
    },
    {
        "cv32e40p_prefetch_controller_PULP_OBI0_PULP_XPULP0_DEPTH2": {
            "INVD1BWP": 38,
            "DEL100D1BWP": 24,
            "AO32D0BWP": 13,
            "AOI32D0BWP": 10,
            "CKND2BWP": 9,
            "ND3D3BWP": 9,
            "OAI221D1BWP": 8,
            "ND2D1BWP": 8,
            ...
    },
    ...
]
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-06-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ExASIC 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档