如何在Chisel中正确定义输出Reg?

问题描述 投票:0回答:1

你可能知道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
    }
}
hdl chisel register-transfer-level
1个回答
4
投票

在Chisel中不允许使用寄存器 Bundle 以保持它们作为接口的纯粹性。它们更接近SystemVerilog结构,而不是Verilog 952001端口声明。

在现有的库中, 最简单的方法是使用 RegNext:

io.dout := RegNext(io.din + 77.S, 0.S(32.W))

注意:这将不会设定 io.dout 直到FIRRTL编译器推断出宽度。这有时会造成问题,如果你想得到的是 io.dout 的东西。

忽略标准库,你也可以通过定义你自己的实用程序,用两种可能的方式之一来创建注册连接,从而更加手动地完成这个任务。

  1. 创建一个函数来做 "注册 "连接。
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)
  1. 创建一个隐式类来添加一个方法到: 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)
© www.soinside.com 2019 - 2024. All rights reserved.