nvdla epython用于自动生成状态机编码的实例
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了nvdla epython用于自动生成状态机编码的实例,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4588字,纯文字阅读大概需要7分钟。
内容图文
英伟达深度学习加速器开源项目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定义,如下:
?localparam?IDLE? =?3'd0;
localparam?START?=?3'd1;
...
localparam?START?=?3'd7;
如果中间需要插入一个新状态,就可能要修改两部分。一是位宽可能加1,二是新插入的后面所有的状态都需要加1。
二进制、十进制、十六进制,可以利用Vim或Emacs列编辑、数据填充、格式化来重新编码。如果是格雷码或者独热码就会麻烦很多。
那么有没有一种比较简便的方法呢?
epython的一个应用
我们知道epython可以让verilog中嵌入python脚本,那么我们可以写一个脚本来做这个事情。
假设我们有若干个状态,用python的列表来描述就是:
st = ['IDLE', 'START', 'NEW', ‘DO_SOMETHING’, 'DONE']
那么我们是否可以仅跟据这个列表来自动产生localparam的定义呢?我们的目标是下面这个样子:
st?=?['IDLE',?'START',?'NEW',?'DO_SOMETHING',?'DONE']
stat_gen()?
我的方法步骤如下:
1. 计算列表长度,也就是状态个数stat_num
2. 计算状态编码的位宽,log2(stat_num),再向上取整
3. 把0, ..., stat_num-1进行编码转换,转成二、十、十六进制、gray、onehot等
4. 格式化输出
是不是很简单?
为了verilog中的嵌入python的简洁,我把主要的实现过程放在了python的module里,再import进来。最终手写verilog代码如下:
?//:|?import?vloglib
//:|??
//:|?st?=?['IDLE',?'FULL',?'WIN',?'PROT',?'WR_FULL',?'WR_WIN']
//:|?vloglib.stat_gen(st,?'bin')
//:|?
//:)?epython:?generated_beg
//:)?epython:?generated_end
?
执行epython后,如下:
?//:|?import?vloglib
//:|??
//:|?st?=?['IDLE',?'START',?'NEW',?'DO_SOMETHING',?'DONE']
//:|?vloglib.stat_gen(st,?'bin')
//:|?
//:)?epython:?generated_beg?(DO?NOT?EDIT?BELOW)
??localparam?IDLE?????????=?3'b000;
??localparam?START????????=?3'b001;
??localparam?NEW??????????=?3'b010;
??localparam?DO_SOMETHING?=?3'b011;
??localparam?DONE?????????=?3'b100;
//:)?epython:?generated_end?(DO?NOT?EDIT?ABOVE)
格雷码效果如下:
//:|?import?vloglib
//:|??
//:|?st?=?['IDLE',?'START',?'NEW',?'DO_SOMETHING',?'DONE']
//:|?vloglib.stat_gen(st,?'gray')
//:|?
//:)?epython:?generated_beg?(DO?NOT?EDIT?BELOW)
??localparam?IDLE?????????=?3'b000;
??localparam?START????????=?3'b001;
??localparam?NEW??????????=?3'b011;
??localparam?DO_SOMETHING?=?3'b010;
??localparam?DONE?????????=?3'b110;
//:)?epython:?generated_end?(DO?NOT?EDIT?ABOVE)
独热码效果如下:
//:|?import?vloglib
//:|??
//:|?st?=?['IDLE',?'START',?'NEW',?'DO_SOMETHING',?'DONE']
//:|?vloglib.stat_gen(st,?'onehot')
//:|?
//:)?epython:?generated_beg?(DO?NOT?EDIT?BELOW)
??localparam?IDLE?????????=?5'b00001;
??localparam?START????????=?5'b00010;
??localparam?NEW??????????=?5'b00100;
??localparam?DO_SOMETHING?=?5'b01000;
??localparam?DONE?????????=?5'b10000;
//:)?epython:?generated_end?(DO?NOT?EDIT?ABOVE)
是不是效果还可以?
vloglib.py代码分析
代码如下:
import?os
import?sys
import?re
import?math
import?bin2gray2bin
def?stat_gen(l_stat,?code='dec'):
????#calc?bit?width
????stat_num?=?len(l_stat)
????bit_width?=?math.ceil(math.log2(stat_num))
????#get?the?max?lenght?of?strings?in?list
????l?=?[len(i)?for?i?in?l_stat]
????maxlenth?=?max(l)
????#print?verilog?code
????for?i?in?range(len(l_stat)):
????????n?=?'??localparam?{}'.format(l_stat[i]).ljust(13?+?maxlenth)
????????c?=?''
????????if?code?==?'bin':
????????????t?=?'{:b}'.format(i)
????????????t?=?t.rjust(bit_width,?'0')
????????????c?=?'?=?{}\'b{};'.format(bit_width,?t)
????????elif?code?==?'dec':
????????????c?=?'?=?{}\'d{};'.format(bit_width,?i)
????????elif?code?==?'hex':
????????????t?=?'{:x}'.format(i)
????????????t?=?t.rjust(math.ceil(bit_width/4),?'0')
????????????c?=?'?=?{}\'h{};'.format(bit_width,?t)
????????elif?code?==?'gray':
????????????t?=?'{:b}'.format(i)
????????????t?=?t.rjust(bit_width,?'0')
????????????t?=?bin2gray2bin.bin2gray(t,?bit_width)
????????????c?=?'?=?{}\'b{};'.format(bit_width,?t)
????????elif?code?==?'onehot':
????????????if?i?==?0:
????????????????t?=?'0'?*?(stat_num?-?1)?+?'1'
????????????else:
????????????????t?=?t[1:]?+?'0'
????????????c?=?'?=?{}\'b{};'.format(stat_num,?t)
????????print(n?+?c)
要点:
-
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
内容总结
以上是互联网集市为您收集整理的nvdla epython用于自动生成状态机编码的实例全部内容,希望文章能够帮你解决nvdla epython用于自动生成状态机编码的实例所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。