【问题标题】:How to define output Reg in Chisel properly如何在 Chisel 中正确定义输出 Reg
【发布时间】:2020-06-15 12:16:21
【问题描述】:

您可能知道 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
}

是否有更“短”的方式来创建输出 reg?
我正在寻找的是在 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】:

    Bundle 中不允许注册以保持其作为接口的纯度。它们比 Verilog 95/2001 端口声明更接近 SystemVerilog 结构。

    对于现有的库,做你想做的最简单的方法是使用RegNext

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

    注意:在 FIRRTL 编译器推断宽度之前,这不会设置 io.dout 的宽度。如果您尝试获取 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)
    

    【讨论】:

    • 我会调整 RegNext 提案以使用支持重置值的 2 参数版本,如原始问题中使用的那样:io.dout := RegNext(io.din + 77.S, 0.S(32.W))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-28
    • 2021-07-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多