你可能知道Verilog中的 "输出reg",非常有用的功能。但是在Chisel中我找不到如何做类似的事情。当我需要寄存器输出时,我应该这样做。
package filter
import chisel3._
class TestReg extends Module {
val io = IO( new Bundle {
val din = Input(SInt(32.W))
val ena = Input(Bool())
val dout = Output(SInt())
})
val dout = RegInit(0.S(32.W))
when (io.ena) {
dout := io.din + 77.S
}
io.dout <> dout
}
有没有一种更 "简捷 "的方法来创建输出寄存器? 我想找的是在IO捆绑中定义Reg,然后把它写成寄存器,就像这样。
class TestReg extends Module {
val io = IO( new Bundle {
val din = Input(SInt(32.W))
val ena = Input(Bool())
val dout = Output(RegInit(0.S(32.W)))
})
when (io.ena) {
io.dout := io.din + 77.S
}
}
在Chisel中不允许使用寄存器 Bundle
以保持它们作为接口的纯粹性。它们更接近SystemVerilog结构,而不是Verilog 952001端口声明。
在现有的库中, 最简单的方法是使用 RegNext
:
io.dout := RegNext(io.din + 77.S, 0.S(32.W))
注意:这将不会设定 io.dout
直到FIRRTL编译器推断出宽度。这有时会造成问题,如果你想得到的是 io.dout
的东西。
忽略标准库,你也可以通过定义你自己的实用程序,用两种可能的方式之一来创建注册连接,从而更加手动地完成这个任务。
object ConnectionUtilities {
def regConnect(lhs: Data, rhs: Data): Unit = {
val rhsReg = Reg(chiselTypeOf(rhs))
rhsReg := rhs
lhs := rhsReg
}
}
有了这个,你就可以用这个方法来做连接,并生成必要的寄存器。
import ConnectionUtilities.regConnect
regConnect(io.out, io.in + 77.S)
Data
. 这是更高级的,有可能让阅读你代码的人感到困惑。然而,它可以让你用自己的领域特定语言扩展Chisel领域特定语言。object ConnectUtilities2 {
implicit class DataWithRegConnect(lhs: Data) {
def `:=r` (rhs: Data): Unit = {
val rhsReg = Reg(chiselTypeOf(rhs))
rhsReg := rhs
lhs := rhsReg
}
}
}
然后,你可以使用这个新方法(注意,这需要回标,因为 :=r
本身就不是一个法律名称)。)
import ConnectUtilities2.DataWithRegConnect
io.dout `:=r` (io.din + 77.S)