如何理解凿子语言中的节拍?

How to understand the beat in chisel language?

正在研究riscv-Boom的设计。它是用 chisel 设计的。我在看它的源码的时候,总是想不明白这些电路中的信号是什么时候获取到的。正常程序一个一个执行。但是像 chisel 这样的硬件语言不是。

https://github.com/riscv-boom/riscv-boom/blob/master/src/main/scala/exu/issue-units/issue-slot.scala 比如上面的link就是Boom中Issue-slot的源码

 103:  val next_uop = Mux(io.in_uop.valid, io.in_uop.bits, slot_uop)
 113:  state := io.in_uop.bits.iw_state
 126:  next_state := state
 127:  next_uopc := slot_uop.uopc
 128:  next_lrs1_rtype := slot_uop.lrs1_rtype
 129:  next_lrs2_rtype := slot_uop.lrs2_rtype
 155   slot_uop := io.in_uop.bits
 208:  for loop

这是上面 link 中 IssueSlot class 中的一些代码。对于chisel硬件语言来说,这些:=应该是指它们是通过电线连接在一起的。那么这些信号是同时变化的吗?比如当io.in_uop.valid为真时,上面的代码是否同时赋值?

  1. 比如当前uop为fmul,in_uop=为fadd。当io.in_uop.valid时,上面的代码会同时执行。但是有个问题。
origin 
     uop = fmux
when io.in_uop.valid
     103:  val next_uop = io.in_uop.bits       (fadd uop)
     113:  state := io.in_uop.bits.iw_state    (fadd state)
     126:  next_state := state                  (fmux state)
     127:  next_uopc := slot_uop.uopc             (fmux uopc)
     128:  next_lrs1_rtype := slot_uop.lrs1_rtype (fmux lrs1_rtype )
     129:  next_lrs2_rtype := slot_uop.lrs2_rtype (fmux lrs2_rtype )
     155   slot_uop := io.in_uop.bits              (faddlrs2_rtype )
     208:  for loop

当io.in_uop.valid为真时,此时的发送槽会输入fadd信息。同时,原来的fmul信息仍然会输出到next相关信号。这应该是不合理的。问题出在哪里?

  1. 对于第207行的for循环,我还是觉得很难理解。 for循环会不会一拍执行完?比如我用for循环遍历队列,for循环什么时候结束?

如果有人愿意回答我,我将不胜感激!

  1. 首先

a := b 表达式表示 b 连接到 a 是。 b 是源,a 是汇。 如果在代码中完成与 a 的新连接,它将被替换。

在下面的代码中,a 连接到 c

a := b
a := c

这种写法可能比较奇怪,但在条件分支中设置默认值很有用。

例如:

a := b
when(z === true.B){
    a := c
}

默认情况下,a 将连接到 b,除非 z 为真。

不要忘记 Chisel 是一个 HDL 生成器。它生成硬件代码,一些关键字是纯 Scala,如 iffor、...和其他是硬件凿子关键字,如 whenMux、...

然后在代码生成阶段执行第208行的for循环。并且它会生成一些硬件凿子 when mux 代码。

我强烈建议您花一些时间在 Chisel Bootcamp 上。真的可以帮助你掌握凿子的生成器方面。