![]() |
侠义非凡的脆皮肠 · 香港大学深圳医院孔凤鸣教授课题组2023年博 ...· 1 年前 · |
![]() |
绅士的长颈鹿 · VUE读取svg文件 修改svg图标颜色 ...· 1 年前 · |
![]() |
深情的小摩托 · 实现包含 FROM 或子查询的 ...· 1 年前 · |
![]() |
慈祥的皮带 · python - Pynput ...· 1 年前 · |
英伟达深度学习加速器开源项目nvdla(NVIDIA Deep Learning Accelerator)中用到了一个python脚本epython。源代码地址:
https://github.com/nvdla/hw/blob/master/tools/bin/epython
epython全称embeded python utility,简单地说,就是用来预处理verilog文件中嵌入的python脚本。利用python语法的简洁性,来自动生成一些重复的、有规律的代码。
提出问题
我们在写Verilog代码时,状态机的编码一般是由parameter定义,如下:
如果中间需要插入一个新状态,就可能要修改两部分。一是位宽可能加1,二是新插入的后面所有的状态都需要加1。
二进制、十进制、十六进制,可以利用Vim或Emacs列编辑、数据填充、格式化来重新编码。如果是格雷码或者独热码就会麻烦很多。
那么有没有一种比较简便的方法呢?
epython的一个应用
我们知道epython可以让verilog中嵌入python脚本,那么我们可以写一个脚本来做这个事情。
假设我们有若干个状态,用python的列表来描述就是:
st = ['IDLE', 'START', 'NEW', ‘DO_SOMETHING’, 'DONE']
那么我们是否可以仅跟据这个列表来自动产生localparam的定义呢?我们的目标是下面这个样子:
我的方法步骤如下:
1. 计算列表长度,也就是状态个数stat_num
2. 计算状态编码的位宽,log2(stat_num),再向上取整
3. 把0, ..., stat_num-1进行编码转换,转成二、十、十六进制、gray、onehot等
4. 格式化输出
是不是很简单?
为了verilog中的嵌入python的简洁,我把主要的实现过程放在了python的module里,再import进来。最终手写verilog代码如下:
执行epython后,如下:
格雷码效果如下:
独热码效果如下:
是不是效果还可以?
vloglib.py代码分析
代码如下:
要点:
math是数学库,使用了log2()和ceil()两个函数来计算位宽
string的ljust(len)是指定宽度len,左对齐,不足的用空格填充。len由状态字符串的最大长度决定。
二、十、十六进制可以用sting.format()来格式化,再rjust(len)右对齐,填充‘0’
格雷码调用了一个第三方库bin2gray2bin
独热码采用字符串序列的拼接,来实现左移的效果
源码下载
下载地址:
https://github.com/chenfengrugao/vloglib
或者
git clone https://github.com/chenfengrugao/vloglib.git
欢迎关注ExASIC
分享数字集成电路设计中的经验和方法
分享让工作更轻松
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2023 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号: 粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
扫码关注腾讯云开发者
领取腾讯云代金券