下午微信群里有个小伙伴问了这么一道题: 
将一个为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语言及将常见基础组件封装起来便于快捷的调用。当然我们在使用的同时还是要去仔细分析下其源代码,理解设计的本质。 
原作者:玉骐 
 
 |