Search code examples
scalachisel

How to init a register with a parametrized value


I'm trying to deploy RegInit in a module with parametrized data types. Normally, for a simple port in Chisel I'd do the following:

val myReg = RegInit (0.U(32.W))

In my code, I have the following:

import dsptools._
import dsptools.numbers._

class Acc[A <: Data:Ring, B <: Data:Ring] (inType:A, outType:B, 

mulPipeLen:Int = 1, addPipeLen:Int = 1) extends Module {
...
  def zero = dsptools.numbers.Ring[B].zero

  val mres  = Reg(outType.cloneType) // this works, no initialization
  val ares  = RegInit(zero(outType.cloneType.getWidth.W)) // this fails trying to zero init in the parametrized Ring
...

}

which return a compile error:

[error] Acc.scala:43:27: B does not take parameters
[error]   val mres  = RegInit(zero(outType.cloneType.cloneType.getWidth.W)) 

How do I fix this? Thank you!


Solution

  • When I tried the above, I got 3 errors:

    [error] /Users/jack/work/chisel3-raw/src/main/scala/RegInit.scala:10:13: inferred type arguments [Object] do not conform to method apply's type parameter bounds [T <: chisel3.core.Data]
    [error]   val reg = RegInit(0.U, (32.W))
    [error]             ^
    [error] /Users/jack/work/chisel3-raw/src/main/scala/RegInit.scala:10:23: type mismatch;
    [error]  found   : chisel3.core.UInt
    [error]  required: T
    [error]   val reg = RegInit(0.U, (32.W))
    [error]                       ^
    [error] /Users/jack/work/chisel3-raw/src/main/scala/RegInit.scala:10:30: type mismatch;
    [error]  found   : chisel3.internal.firrtl.Width
    [error]  required: T
    [error]   val reg = RegInit(0.U, (32.W))
    [error]                              ^
    

    RegInit has two flavors, documented here: https://chisel.eecs.berkeley.edu/api/latest/chisel3/core/RegInit$.html

    In short, if just 1 argument, it is the initialization value. If the initialization value has a defined width (0.U(32.W) vs. 0.U) then it will adopt the width (and type) of the initializing value.

    val reg = RegInit(0.U(32.W))
    

    Otherwise, you can give 2 arguments, the first defining the type, the second defining the initialization value

    val reg2 = RegInit(UInt(32.W), 0.U)
    

    Response to Edited post

    I don't know much about the dsptools, but I don't think Ring has much to do with the concept of zero. You can set the type of ares to be the same as outType and then try casting 0 to the same type as the init value, eg.

    val ares = RegInit(outType.cloneType, 0.U.asTypeOf(outType.cloneType))
    

    Or perhaps you can cast 0 and also set the width:

    val ares = RegInit(0.U(outType.getWidth.W).asTypeOf(outType.cloneType))
    

    I'm not sure if these will work, but they might