十二 · 2023年12月19日

数据中心逻辑搬砖要会的——几个好用的Python库

✎ 编 者 按

作为一个在数据中心搬砖的逻辑开发,日常不是仅仅简单的写写RTL就可以完事儿的。在数据中心,你可能连板卡都看不到,日常常打交道的,也就是PCIe。作为逻辑版本的生产者,出现问题往往需要自己有详细的定位手段和方式(没有谁比设计者更清楚逻辑的功能。专门的软件人员来做当然没问题,但增加沟通成本),那么一套自己常用的软件工具还是非常有必要的。对于这种工具型工具,C就显得太笨重了,而Python才是首选。

推荐几个不错的Python库

ctypes

作为常与PCIe打交道的人来说,99%的定位方式都是通过寄存器来进行定位信息。在python中自然也可以通过mmap来实现PCIe Bar空间的映射,但有一个问题就是Python下的mmap一次读或者写有时往往会产生两次TLP读写。这么高深的问题自然逻辑开发人员是解不了的。那这时候最好的方式就是通过ctypes来实现与C的打通,mmap与寄存器读写功能API交给C代码来做,生成.so后Python通过ctypes来实现调用即可,方便简洁。

rich

在linux环境里,基本上就是一个命令行窗口,那么基本上就是各种打印了。有些时候想基于Python的print自己实现各种功能还是太略显麻烦了。那么rich库是一个很好的选择。

image.png

Rich 是一个 Python 库,可以为您在终端中提供富文本和精美格式。

Rich 的 API 让在终端输出颜色和样式变得很简单。此外,Rich 还可以绘制漂亮的表格、进度条、markdown、语法高亮的源代码以及栈回溯信息(tracebacks)等——开箱即用。

网上关于rich库的介绍挺多的,这里就不拾人牙慧了。借助rich的丰富功能,可以基于少量的代码来实现相对比较丰富的功能。

举个例子,对于设计而言,维护寄存器/文档的一致性除非代码用脚本生成的那么其他情况下往往项目做到最后越来越文不对题。在逻辑开发中,我会基于SpinalHDL中的regif来在代码中进行定义寄存器实现,在其上面基础上重定义了它文档生成的代码,用来能够生成整个系统的寄存器文档。日常会输出一份html寄存器文档以及一份Json格式寄存器文档。随后在做集成工具时会通过命令行参数直接将json文件直接传给命令行工具,解析后借助rich的table直接能够一键dump所有的寄存器,并精确给到每个寄存器每个比特的注释说明,这比读一个寄存器,再去对照寄存器文档去看什么意思简直不要方便太多!

当然,借助chatgpt来实现基于rich定义各种显示功能这种体力劳动更能节省思考和动手能力。

Fire

既然定位是工具类型的,那么我们最终需要的肯定是一个命令行工具CLIs。这里推荐使用Fire这个库。不为别的,它最简单,简单到令人发指!

import fire

def add(x, y):
  return x + y

def multiply(x, y):
  return x * y

if __name__ == '__main__':
  fire.Fire({
      'add': add,
      'multiply': multiply,
  })

在上面这段代码里,我们定义的功能函数仅需把函数注册到Fire里就能自动生成命令行工具:

$ python example.py add 10 20
30
$ python example.py multiply 10 20
200

基本零成本实现一个CLI工具,简直太香了。

在VSCode中配合autoDocstring - Python Docstring Generator这个插件可以方便的为函数增加注释,从而在上面生成的命令行中很方便的生成帮助信息

import fire
def add(x:int, y:int) -> int:
    """add operation

    Args:
        x (int): data
        y (int): data

    Returns:
        int: sum
    """
    return x + y

def multiply(x:int, y:int) -> int:
    """multiply operation

    Args:
        x (int): data
        y (int): data

    Returns:
        int: multiply
    """
    return x*y

def version()-> str:
    """get version info

    Returns:
        str: version number
    """
    return "1.2.3"

if __name__ == '__main__':
  fire.Fire()

运行时:


python3 test.py --help
NAME
    test.py

SYNOPSIS
    test.py GROUP | COMMAND

GROUPS
    GROUP is one of the following:

     fire
       The Python Fire module.

COMMANDS
    COMMAND is one of the following:

     add
       add operation

     multiply
       multiply operation

     version
       get version info
python3 test.py add --help

NAME
    test.py add - add operation

SYNOPSIS
    test.py add X Y

DESCRIPTION
    add operation

POSITIONAL ARGUMENTS
    X
        Type: int
        data
    Y
        Type: int
        data

NOTES
    You can also use flags syntax for POSITIONAL ARGUMENTS

白嫖的即视感!

pyinstaller

这种脚本在不同的机器上运行,自然是不希望直接将代码复制到机器上的,毕竟还要安装各种依赖包,有时候这些机器往往是不联网的。那么最简单的方式就是通过pyinstaller打包成一个可执行文件了。pyinstaller网上资料也比较多,也可以记住chatgpt来获取如何打包的方式。

比如针对上面的需要带.so的打包,我们仅需针对python main文件执行一条指令即可:

pyinstaller --onefile --add-binary='./clib/a.so:.' Test.py

☆ END ☆

作者:玉骐
原文链接:Spinal FPGA
微信公众号:
 title=

推荐阅读

更多SpinalHDL技术干货请关注[Spinal FPGA]欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。
推荐阅读
关注数
1581
内容数
133
用SpinalHDL提升生产力
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息