ucb-bar / chisel2-deprecated

chisel.eecs.berkeley.edu
387 stars 90 forks source link

Difficulties creating a literal from a generated type #571

Open da-steve101 opened 8 years ago

da-steve101 commented 8 years ago

I am trying to create a literal from a generated type. Here is what I have so far:

import Chisel._

class GenTypeIssue [T <: Bits with Num[T]]( val genType : T ) extends Module {
  val io = new Bundle {
    val in = genType.cloneType.asInput
    val out = genType.cloneType.asOutput
  }

  val ZERO = genType.cloneType
  // ZERO.setWidth(genType.getWidth)
  val tmpZero = ZERO.toUInt()
  tmpZero := UInt(0, width = genType.getWidth)
  // Can't really do
  // val ZERO = Lit("b00", width=genType.getWidth) { ?? }
  // maybe genType.getConstructor
  /*
  for ( i <- 1 until genType.getWidth ) {
    ZERO.bitSet(UInt(i), Bool(false))
  }
   */
  // val tmp = Reg(init = ZERO) // compile error: inferred type arguments [Object] do not conform to method apply's type parameter bounds [T <: Chisel.Data]
  val tmp = RegInit[T](ZERO) // Node.getWidth() for node /*? in < (class L2Norm.Math.GenTypeIssue)>*/ Chisel.Flo(OUTPUT, width=None, connect to 0 inputs: ()) returns unknown width in class L2Norm.Math.GenTypeIssue
  tmp := io.in
  io.out := tmp
}

class GenTypeExSuite extends TestSuite {

  @Test def genTypeTest() {
    class UserMod extends Module {
      val io = new Bundle {
        val in = Flo(INPUT)
        val out = Flo(OUTPUT)
      }
      val tmp = Flo(0)
      val gti = Module(new GenTypeIssue[Flo]( tmp) )
      gti.io.in := io.in
      io.out := gti.io.out
    }

    class UserTest(c : UserMod) extends Tester(c) {
      poke(c.io.in, (0.5).toFloat)
      step(1)
      expect(c.io.out, (0.5).toFloat)
    }
    launchCppTester( (c : UserMod) => new UserTest(c) )
  }
}

First option of constructing a literal directly is using Lit() object. This requires knowing the companion object which getting dynamically is apparently not advisable. One way around this would to have each type have a reference to the companion object such as

class UInt {
...
def getCompanion = { UInt() } // return reference to object
...
}
// pass to Lit like so
val ZERO = Lit("b00", genType.getWidth) { genType.getCompanion }

After this gave me issues I tried cloning and setting the value to 0. This gave me compile errors which I am still trying to figure out (see comment next to reg declaration for error). Width issue for cloning a Flo is puzzling. Thoughts?

da-steve101 commented 8 years ago

Just realized i was passing in tmp = Flo(0) rather than tmp = Flo() as generating type, still convenient to have getLit however