Mrchacha Mrchacha - 20 days ago 5
Scala Question

Use generic type to turn off logic in datapath (Chisel)

I'm working on a Z-Scale RISCV-processor where I've implemented new functionality and logic into the datapath. I'm wondering if there exist an easy way to "power off" certain parts of the code without using a bunch of if-loops? I would like to make it easy to switch between the regular implementation of the Z-scale processor and the one with extended implementation.

The new logic I've implemented does not replace the main components of the datapath, but rather extends the functionality.

Answer

This question really strikes at the heart of what makes Chisel powerful. As a DSL embedded in Scala, you have access to the full power of an object-oriented and functional programming language.

While I'm not sure of exactly what you're doing, this seems like a good place to use inheritance. You could make a new Module class that extends the datapath Module and adds the additional functionality.

A toy example:

import Chisel._

class ParentIO extends Bundle {
  val foo = UInt(width = 32).asInput
  val bar = UInt(width = 32).asOutput
}

class Parent extends Module {
  // Note the use of lazy val
  // Due to Scala initialization order (http://docs.scala-lang.org/tutorials/FAQ/initialization-order.html)
  //   this cannot be a val
  // Due to quirks of Chisel, this cannot be a def
  lazy val io = new ParentIO
  io.bar := io.foo
}

class ChildIO extends ParentIO {
  val isOdd = Bool().asOutput
}

class Child extends Parent {
  override lazy val io = new ChildIO
  io.isOdd := io.foo(0)
}

// Note use of call-by-name for passing gen
// Chisel Modules must be constructed within the Module(...) function
class Top(gen: => Parent) extends Module {
  val dut = Module(gen)
  val io = dut.io.cloneType
  io <> dut.io
}

Thus, Module Top is now parameterized by the type of Module it instantiates, Parent or Child. You can thus only conditionally instantiate Parent or Child rather than all of the logic that differentiates them. If in your use case you want the Child to be overriding certain functionality of the parent, due to Chisel's last connection semantics, any connections in the Child will overrule connections in the Parent.