Python的进击(下)--python在IC设计里的应用点滴

通过前两篇的了解,一起解决了为什么要用python(Why)以及怎么用python(How)的问题,在这个系列的最后一讲里,一起再来看看在IC设计的征途中里的案例和一些推荐
在这里插入图片描述

案例一:大型文件高速比对

IC设计里边主要处理的对象还是以文本为主,但是在某些特殊的情况下,文本文件非常巨大,譬如上G的文件。这个时候对文件的查验和比较都是比较麻烦的,尤其对于VIMer而言尤其是困难(由于VIM的设定,是需要将文件全部读入到内存里边,大文件的打开和覆写操作都很慢)。

文件体量

笔者有两个比较大的lib文件,
在这里插入图片描述
这两个文件的大小很相近,看文件大小的详情可以有所体会
在这里插入图片描述
但是这里请各位小伙伴注意,同样字符长度的lib描述,很有可能只是内容不同,但是文件大小可能非常相近,设置大小完全一致
在这里插入图片描述
所以,断言这两个lib的内容有多么一致或者不一致从大小上看是比较困难的。如果采用vimdiff或者unix自带的diff工具,速度会使非常非常慢(VIM基本30分钟没有结果~~)

python的高效处理示例

python里边有很强大的数据结构能力,这里使用zip命令可以非常高效的进行文件比对。先说结论,然后慢慢展开
在这里插入图片描述
从以上截图可以看到,使用python进行文件比对,基本在10秒内可以完成两个1.6G文件的比对,其中共找到了19K+的不同行,不同之处可以方便的导出到out.rpt里边。看一下整体行数:
在这里插入图片描述
平均来看,基本是2.2M行/秒的比较速度,可以说是秒比也不为过。

核心命令

这个脚本比较简单,其中的核心命令如下:

zip(open(f1), open(f2))

这条命令蕴含着下面几个加速方法

  • 直接对文件f1/f2进行迭代,并不去对文件对象使用readlines()的操作。python对于文件操作的时候,open()函数打开的对象就会被直接转换成可迭代对象。当然,数据保留的格式是内部数据结构<class '_io.TextIOWrapper'>。并非list或者str,这样可以大大提升处理速度
    在这里插入图片描述
  • zip函数可以对于可迭代对象进行原地打包,并且生成一个新可迭代对象,直接被for...in...调用,效率高出天际。
    在这里插入图片描述

对于可迭代的对象可以直接进行比对,对那些不相等的部分,才进行显式打印,这样的几个操作下来,在大型的文件之间的diff也会变得毫无压力。
案例一小:尽量使用可迭代对象(Iterable)而非直接的显式list/str,可以大幅度的提高运行效率。

案例二:规范的脚本开发思路和策略

在IC设计里边,大部分的工作都是短小的脚本处理,目的就是快速和高效。这种开发思路是有优势的,譬如:数据的快速迭代、抽取、解析、分析以及结果导出。一个合格的IC工程师,可能每天都要面对多个处理和迭代的需求。一周写个三、五个脚本是很稀松平常的。
这样的脚本开发是典型的头疼医头、脚疼医脚的短平快的开发方法。高效,所见即所得是其最大的优势。

常见语言的优缺点

在讨论脚本开发的思路之前,一起看一下常见语言的优缺点:

语言 优点 不足
TCL 数据结构简单,简单易学 通常仅在EDA工具内使用,可处理的类型和场景非常有限,多为文本处理效率较低
shell 基本语法简单,可以和unix命令联动 各种shell语法不统一(bash/tcsh/ksh etc.),native命令比较少,数据信息传递较弱
perl 提供较多的命令,可以和其语言联动,支持复杂的数据结构,模块化设计 语法松散,维护工作量比较大
python 提供较多的命令,可以和其语言联动,支持复杂的数据结构,模块化设计,社区友好,良好的跨平台性, 较易维护,边际成本低 更像一种高级语言,起步需要一定学习坡度,python3有重大变化,从python2转移需要一些工作量,

ICer的脚本开发的几个阶段

语言各有优缺点,唯场景以定之。基于笔者的工作经验来看,脚本的开发有以下几个阶段

  • 阶段一:TCL统管一切
    最开始工作的时候,主要的工作场景都是在EDA工具里边。TCL确实好用,和工具的嵌套比较紧密,甚至可以调用shell或者perl脚本,基本可以在工具里边完成大部分事情。一些短平快的脚本基本都用TCL开发。但是随着脚本越来越多,那些随意化的脚本非常的散乱,格式也不统一,由于是EDA based的,很多命令只能在特定的EDA工具里边运行,交互起来缺乏便利性。
    结局:由于以上原因,很多用意类似脚本被反复书写,效率低下,继承性低。

    扫描二维码关注公众号,回复: 14955446 查看本文章
  • 阶段二:shell的支持
    shell是直接运行在unix下的语言,可以很好的对unix环境进行调剂和管控,简单编程就可以生成比较好用的胶水工具箱,譬如:R2G流程的联动(SYN->APR->extraction -> PV -> STA etc.),传递参数运行多个并行的后台流程(R2G_run1, R2G_run2 etc.)。但是由于shell语法比较简单的原因,对于结果的解析通常只能使用awk、sed等unix native命令,需要学习独立的语法和用法,这些损耗有时候已经超出shell脚本本身。
    结局:shell脚本很多,但是好用的还是比较少,数据抽取操作弱,对于纠错和容错处理相对困难

  • 阶段三:perl的介入
    这个时候,perl的介入就是毋庸置疑了。很多公司的大型仿真、验证环境都是使用perl语言搭建的。数据结构复杂,文本操作方式多,效率也不差。可以完美取代shell成为更为流程可控、输出标准的胶水工具。后端也很喜欢用perl,譬如对timing report进行summary和格式化打印,可以方便的对于每一版本的数据进行归一化比对;再譬如,对于某一个block的R2G运行环境进行迁移的时候,可以使用异常灵活的perl -pie 命令行方式,对所有的脚本文件中特定字串进行高速替换,效率极高。总之,perl对实际常见文本的处理非常高效和方便
    结局:perl文本处理异常强大和高效,但是强大的代价是松散的上下文决定式(context)的语法体系,这个对于后期维护带来了一定的障碍。复杂数据结构的表达较晦涩(reference/dereference),不易操作

  • 阶段四:python的出现
    上述三个阶段的文本处理、胶水工具、格式化输出等等复杂的问题。在高级语言python看起来,都不是问题。python和perl都是用C语言编写的初版(perl6以后有使用java编写的可能;python前期的Cpython(使用C编译),后期的Jpython(Java 编译,用于JVM环境)都是一些拓展的话题)。python文本处理没有perl直接,也不支持命令行快速操作模式,但是

    • 规范的语法规则以及PEP8的加持
    • 良好的阅读性和可维护性
    • 复杂数据结构的支持
    • 更类似于高级语言的编程方法和思路

    以上种种,都不失为一个系统化、增量化、可视化、易继承、易维护的一个语言选择。

系统化的解决问题的痛点

通常的工作,都是点滴任务的直接需求,用户可以把这些简单脚本视为一个一个的点脚本。为了日后的可扩展、可维护以及可套叠的长远目标。需要相对统一的开发方式进行各个点脚本的开发,包括但不限于下列的限制和规范:

  • 统一的命名方式:蛇形命名法(snake_case):使用下滑线连接单词进行变量命名:cell_order_reversed
  • PEP8 句法 规则:这里并非真正的语法要求,而是python推荐的代码书写风格(coding style),譬如:逗号(‘,’)前边没有空格,后面需要接一个空格等等。具体细节,可以点击查看 PEP8的规范文档。 (Pycharm里边默认就使能了PEP8的代码书写风格检查
  • 局部的、专一的功能尽量使用函数(def)或者类(class)进行描述,减少冗长的代码,并且提高代码维护性的效率。
  • 使用main函数进行主程序的执行
  • 点脚本的链式集合:过往的点脚本,使用模块的导入(import)的方式进行尽可能的重用和构建
  • 脚本的格式化和规范化输出
  • 构建具有趋势性的JSON 作为API接口,以供日后使用

ICer的python脚本模板分享

python的理念相当现进,和专家相比,笔者也是初来乍到,结合上述表述,构建了一个简单的python 脚本模板,这里分享出来以飨读者,也欢迎各位ICer使用和讨论:

#!/usr/bin/python3.6 -u
# use -u to support tee meaage in unix

# support Chinese encoding
# -*- coding: utf-8 -*-

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# import part
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
import argparse
import utils_local as ut

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Scripts version info
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ver = 'V0.1'
ver_date = 'September 13, 2021'
ver_des = 'initial version.'

ut.ver = ver
ut.ver_date = ver_date
ut.ver_des = ver_des


# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# CLASS part
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class TextParse
    def __init__(self, file):
        self.file = file
        ......
    def get_text_header(self):
        ......
        return XXX


# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# FUNCTION part
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def parse_argu():
    ......
    return argus

def func_1():
    ......
    return func_1_value
    
def func_2():
    ......
    return func_2_value

def main_run(......):
    ......
    func_1()
    func_2()
    ......
    return main_run_status


# ------------------------------------------------------------
# MAIN part
# ------------------------------------------------------------
if __name__ == '__main__':
    # global variable for main run
    cell_name = "abc"
    setup_margin = 0.3

    # welcome message include scripts version message from local utils
    ut.welcome()

    # args parse
    args = parse_argu()
    
    # Call main run
    main_run(*args)

    # bye message from local utils
    ut.bye()

上述示例可以简单的提供一个python的开发模板,按照这种格式化的模板,利用本地工具模块(utils_local.py)可以方便的进行格式化(welcome 、bye message)的输出打印。就算后期需要调整打印格式(尽量避免),也可以通过只改动这个模块文件进行同意刷新(new-face)。
python是强大的高级语言,使用python可以设立更大的目标,如果未来想实现更为复杂、结构化的脚本环境,建议读者们可以从现在就向python靠拢。设想在不远的未来,可以将一个个简单的点脚本串接在一起呈现出系统化、结构化的工具箱式的工具包,提供给各位ICer使用。

本章词汇

词汇 解释
蛇形命名法(snake_case) 使用下划线进行单词连接方式的命名法

【敲黑板划重点】

在这里插入图片描述
python的潜力大、可维护性好,是构建大型ICer工作环境和复杂脚本的优选语言之一

参考资料

艾思 自研python脚本big_file_diff.py:大型文件对比
www.python.org

猜你喜欢

转载自blog.csdn.net/i_chip_backend/article/details/120631223
今日推荐