十二 · 2021年10月28日

电路描述里apply的妙用

SpinalHDL和Chisel都是基于scala来实现的,而在SpinalHDL的example里,偶然看到一个apply的有趣用法。

“神奇”的逻辑,"奇葩"的写法

偶然看到一个例子,在SpinalHDL里的example关于UDP设计的代码里看到了这么一段代码:

cafba544ceb1c2bd7082df6844433737.png

初见这段代码,按照我的理解,flushRx所描述的是一段电路,然而我通篇代码看下来active信号的拉高也仅仅在其中的apply函数,而在代码的其他地方,倒是见到了不少flushRx()的调用,等等,调用电路单元flushRx难道是把电路一遍遍复制么,这也有点儿太不靠谱儿了,太奇葩了吧。

矛盾的指向——apply

在上面的那段代码里,active拉高仅出现在apply函数里,而从整体代码的设计意图来看,状态机里调用flushRx的初衷在于拉高active,而apply是scala中经常遇到的函数,那么这里是否采用了scala的语法功能来描述电路呢?

先看一段scala的普通代码:

d85d993b4d773ce3645c0b1b1306fac6.png

执行结果如下:

7380237b54621b2210ae9a7143c51f79.png

这里首先声明了一个trait a 类型变量,并为该变量生命了两个applu方法,随后分别对变量进行调用aa(),aa(3),而从执行结果来看,在声明变量a时,打印了“hello”,而当我们调用aa()时,打印了world函数,而在我们调用aa(3)时,其打印了world 3。而apply的妙用也就在此:

用括号传递给变量(对象)一个或多个参数时,Scala 会把它转换成对 apply 方法的调用。

进一步逻辑解耦合

像本篇开始提到的那个例子,在状态机里调用flushRx(),相当于执行了拉高active操作。这里我们将与接口相关的时序操作均封装在flushRx中并将接口的赋值封装成函数的形式供其他人调用,从而将算法设计与接口时序分离。

这里看一个简单的例子:

case class applyTest() extends Component{
  val a=in Bool()
  val b=in Bool()
  val c=out Bool()
  val cSetCtrl=new Area{
    c.setAsReg() init(False)
    def apply()={
      c.set()
    }
    when(c){
      c.clear()
    }
  }
  when(a||b)(cSetCtrl())
}
object applyTestApp extends App{
  SpinalSystemVerilog(applyTest())
}

代码本身意义不大,这里我们将对接口c的时序操作均放置在cSetCtrl中,并为其定义一个apply方法,在apply方法中将c拉高。而在逻辑处理里,当a或者b有一个为高电平时调用cSetCtrl。其生成的RTL代码如下:

module test (
  input               data1,
  input               data2,
  output              dataOut,
  input               clk,
  input               reset
);
  reg                 outputGen_outF;

  assign dataOut = outputGen_outF;
  always @ (posedge clk or posedge reset) begin
    if (reset) begin
      outputGen_outF <= 1'b0;
    end else begin
      if(outputGen_outF)begin
        outputGen_outF <= 1'b0;
      end
      if((data1 || data2))begin
        outputGen_outF <= 1'b1;
      end
    end
  end


endmodule

也许有小伙伴看到第15行至18行代码或许感觉有些奇怪,这段代码会综合生成一个两输入LUT和一个寄存器锁存输出,相当于一个或门加一个寄存器输出。至于为什么就留给小伙伴们自己去思考了。

END

作者:玉骐
原文链接:https://mp.weixin.qq.com/s/CwFKo8KyxvKqQQ0Xsy9BKA
微信公众号:
 title=

推荐阅读

更多SpinalHDL技术干货请关注Spinal FPGA专栏。
推荐阅读
关注数
1581
内容数
133
用SpinalHDL提升生产力
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息