如何将算法翻译成Verilog代码?

如何将算法翻译成Verilog?

巧了,我是一名数字前端IP设计工程师,方向为通信芯片IP设计,我的主要工作就是“翻译”算法代码。

经典的ASIC开发流程主要有:

  • 以算法设计为主导
  • 算法C代码手工转换为RTL
  • RTL与算法C代码生成的测试向量对比进行验证
  • 依赖FPGA做大量实时、现场测试
  • 适合通信信号处理,音视频处理或图像处理等产品

我的工作主要就是将算法C代码手工转换为RTL,尤其是通信芯片的设计,算法主要是将浮点运算近似成定点运算,定点的精度决定了系统的性能,所以一种开发模式就是,用C平台生成的case数据和RTL仿真的数据进行对比,保证定点化后的仿真性能。

所以对于单个计算模块的开发来说,可以说就是体力活了,算法的计算过程已经摆在那里,单就是纯翻译。

然而再复杂的算法,在设计工程师的眼里,也就是一堆数学公式,算法设计者也应该尽量做简单的算法实现,比如除法,求幂次方、开平方等复杂运算到了设计工程师这里都已经转化成了简单的乘法和加法运算。更复杂的就是累加、累乘(我所能接触到的)。

做芯片第一应该关注的是芯片的PPA(Performance, Power, Area),如何设计的出更高性能的电路,占用更少的资源/面积,更低的功耗。这才是我们的专业知识。

通过学习算法代码和文档以及协议,了解算法的计算意图。然后进行数据通路的分析,整体的数据流走向。哪些需要计算的数据可以用寄存器存储,哪些数据需要用RAM存储。模块的划分可拆解,哪些计算单元是功能类似的,可以做成一个小IP,乘法器同时使用的最大数量,是否能在整个大模块中分时复用。

算法的设计中没有时序的概念,也没有计算时间的长短。需要设计工程师去整理整个模块的计算流水,流水线排的时间长,需要的计算逻辑就越少,反之,面积越大。面积与速度互换思想,贯穿始终。现成乘法器的数量有限,是否能加上几个乘法器而获得模块整体运算速度提高30%的收益,都需要去折中(Trade off)考虑。

排好计算流水,控制通路,一般都使用状态机去做,当然,状态机怎么设计算法可不会教你。整个模块与更高层模块的交互,接口控制时序需要讨论确定。数据通路可能还需要用到RAM/Regfile去缓存中间数据的结果,RAM/Regfile的读写地址控制也是常见设计。数据通路的运算,是主要消耗资源的部分,所以一个好的详细设计方案非常重要,同样的设计,别人可以用比你小30%的面积和少30%的时间来实现。这可能就是设计工程师真正的价值体现之处。

对于通信算法中,矩阵运算也是比较常见的,复杂矩阵的运算是最耗费资源的,矩阵运算的拆解也需要很多技巧,比如矩阵的乘法是A的第一行乘以B的第一列,累加得到第一个元素,这部分的运算电路可以复用流水起来做。一个矩阵需要拆解合并成数个小矩阵,想要保持并行,用寄存器存储,就会消耗的资源多。存在RAM中就是串行流水做会消耗的时间长,所以这都需要在模块架构设计阶段去计算处理时间和评估消耗资源、折中是否采取(Trade off)。

这种大型矩阵运算动辄几百上千bit的寄存器输出,连线选择运算,可能会造成后端congestion问题,所以方案设计的重要性又体现出来了。组合逻辑的运算,如果路径过长,时序会出现问题,插寄存器的位置也非常重要,消耗的寄存器的数量也是不同的,甚至可以通过手动retimming,找个寄存器把打拍的位置换一下,消耗的资源还是相同的。

对于芯片的功耗前端能做的就是,去加一些时钟门控,模块不用时候可以关掉,组合逻辑计算单元不用的时候避免翻转,乘法器的使能信号的控制,避免无效翻转,数据通路寄存器带着使能打拍,工具也会自动插时钟门控,这些就和算法没关系了。

至于算法,当然不同领域的相关知识不同,虽然设计方法是完全类似的,但是在一个领域深扎,成为这个领域的专业的人,可以更好的理解算法到硬件的实现。

IP设计工程师经常调侃自己是算法“翻译官”,其实也没什么问题,但是自嘲归自嘲,如果感兴趣的话,还是应该去想着如何更好的做好自己的设计,做好芯片。即使是“翻译官”也是一个十分有价值的“翻译官”。。

实现详细设计方案设计好后,具体的代码实现的技巧看这个。

NingHeChuan wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!