下午微信群里有个小伙伴问了这么一道题:
将一个为UInt(128 bits)的Stream接口连接到一个UInt(32 bits)的StreamFiFo上,在SpinalHDL里有没有什么好的方式实现。
熟悉数字逻辑电路的小伙伴想必都不陌生,其本质上是一个接口位宽转换,在实现时无非用位宽转换FIFO或者自己在入口做一个简单的位宽转换,进来一拍有效数据分成4拍放入FIFO里~
若自己的工作里遇到这个需求,熟悉Verilog的小伙伴们是否已经迫不及待的开始动手写了呢~
三行代码实现一个功能
这个需求在SpinalHDL里只需要三行代码(接口的声明不算~):

仿真波形:

这里的实现调用了两个库函数:StreamWidthAdapter,queue。而你的接口列表写完了否?
StreamWidthAdapter
StreamWidthAdapter,顾名思义,其用途是进行Stream接口的位宽转换。看下其源代码:


其输入参数列表为:
input:输入Stream接口
output:输出Stream接口
endianness:选择转换方式为大尾端还是小尾端(LITTLE,BIG)
padding:当输入输出端口位宽不是整数倍时进行数据填充(默认为false,但如果位宽不能整除则要设置为true)。
其内部设计实现思路并不难,位宽匹配时输入输出直接相连,不匹配时则通过增加一个counter来实现接口时序调整和数据填充。
除此之外,StreamWidthAdapter还提供了一个make方法:

可以看出,其内部封装了对StreamWidthAdapter的实现并返回一个Stream接口,通过这个函数,我们上面的代码甚至可以简化为一行:

queue
SpinalHDL在Stream里提供了一个queue方法:

注释很明晰:将Stream接口连接到FIFO上,并返回FIFO的POP端口。
小结
SpinalHDL本质上和我们写Verilog并无差别,只不过借助于Scala语言及将常见基础组件封装起来便于快捷的调用。当然我们在使用的同时还是要去仔细分析下其源代码,理解设计的本质。
原作者:玉骐
|