How can I infer widths from a flattened Bundle? - chisel

I am trying to wire a BlackBox to an arbitrary Bundle, but width inference does not seem to work with the fromBits function. The following compiles fine:
class testBundle extends Bundle {
val io1 = Bool(INPUT)
val io2 = UInt(INPUT,10)
}
class testBox extends BlackBox {
val io = new Bundle {
val in = Bits(INPUT) # Width inference works fine here
val out = Bits(OUTPUT,(new testBundle).getWidth) # But it doesn't work here!
}
}
class test extends Module {
val io = new Bundle {
val in = new testBundle
val out = (new testBundle).flip()
}
val testbox = Module(new testBox)
testbox.io.in := io.in.toBits
io.out := io.out.fromBits(testbox.io.out)
}
But if I remove the (new testBundle).getWidth argument, Chisel cannot infer the width of the output port and errors out. How can I get testBox to connect to arbitrary bundles?

For now I am solving this by passing in the bundle as an argument to the BlackBox:
class testBox(b:Bundle) extends BlackBox {
val w = b.getWidth
val io = new Bundle {
val in = Bits(INPUT,w)
val out = Bits(OUTPUT,w)
}
}
class test extends Module {
val io = new Bundle {
val in = new testBundle
val out = (new testBundle).flip()
}
val testbox = Module(new testBox(io.in))
testbox.io.in := io.in.toBits
io.out := io.out.fromBits(testbox.io.out)
}
I'd welcome a cleaner solution, though.

Related

Dependency injection in scala using guice

I have the following class
class MigrateJob #Inject()(
val resultsMetadataRepo: ResultsMetadataRepo,
val resultsMetadataDao: ResultsMetadataDao,
val tenantProvisioningDao: TenantProvisioningDao,
val migrationOffsetDao: MigrationOffsetDao) extends Job {
def startULFMigrationJob(tenantId: String): Unit = {}
}
To test this MigrateJob class i have this in the test. Whats the syntax for boot strap initialization i am not able to follow and did not find working samples either.
#Test def launchWorkflow(): Unit = {
var guiceBundle =
GuiceBundle.newBuilder[SchedulerApiConfiguration].
addModule(new SchedulerModule)
.enableAutoConfig(getClass.getPackage.getName)
.setConfigClass(classOf[SchedulerApiConfiguration]).build
guiceBundle.initialize(new Bootstrap[SchedulerApiConfiguration](new SchedulerApiConfiguration()))
val injector = guiceBundle.getInjector
val migrateToULFJob = new MigrateToULFJob(
injector.getInstance(classOf[ResultsMetadataRepo]),
injector.getInstance(classOf[ResultsMetadataDao]),
injector.getInstance(classOf[TenantProvisioningDao]),
injector.getInstance(classOf[MigrationOffsetDao]))
migrateToULFJob.startULFMigrationJob(tenantId)

Bundle using Mux

I want to use Mux to choose bundle
enter code here
class ComIO extends Bunlde {
val in = Input(UInt(32.W)
val in = Input(UInt(32.W)
}
class EntIO extends Bundle {
val com = new ComIO
}
class Ent extends Module {
val io = IO(new EntIO)
...
}
class DemoIO extends Bundle {
val com1 = new ComIO
val com2 = new ComIO
val en = Input(Bool())
}
class Demo extends Module {
val io = IO(new DemoIO)
val ent = Module(new Ent)
ent.io <> Mux(io.en,io.com1,io.com2)
}
enter code here
The Error is flowing
enter image description here
Muxes are unidirectional, you can't use them for bidirectional things. Try using a when:
class Demo extends Module {
val io = IO(new DemoIO)
val ent = Module(new Ent)
when (io.en) {
ent.io <> io.com1
} .otherwise {
ent.io <> io.com2
}
}

how to pack zeros in to bundles in chisel

I have a question on pack zeros into bundles. For example consider the next code:
class CmplxNum(val bitwidth: Int) extends Bundle {
val real = SInt(INPUT,bitwidth.W)
val imag = SInt(INPUT,bitwidth.W)
}
class MyClass extends Module {
val io = IO(new Bundle {
val in = new CmplxNum(16)
val load = Bool(INPUT)
val clr = Bool(INPUT)
...
})
...
val sample = RegEnable(io.in,0.S,io.load) // <-- how do i set the reset value
When(io.clr) {
sample <> sample.fromBits(0.S) // <-- I tried this it compiles, but dont know if it is correct
}
}
How do I pack zeros into this Bundle in the RegEnable & clr cases ?
For RegEnable I've got elaboration error of type miss-match which make sense
Here is one way. It relies on the relatively new BundleLiterals (new CmplxNum(16)).Lit(_.real -> 0.S, _.imag -> 0.S). I have also refactored your code a little bit to use the current chisel3 idioms. Without a specific need I would not recommend placing your Input/Output in Bundle. Also the more modern way is to wrap the IO fields in Input() or Output()
import chisel3._
import chisel3.util.RegEnable
import chisel3.experimental.BundleLiterals._
class CmplxNum(val bitwidth: Int) extends Bundle {
val real = SInt(bitwidth.W)
val imag = SInt(bitwidth.W)
}
class MyClass extends Module {
val io = IO(new Bundle {
val in = Input(new CmplxNum(16))
val load = Input(Bool())
val clr = Input(Bool())
...
})
...
val sample = RegEnable(
io.in,
init = (new CmplxNum(16)).Lit(_.real -> 0.S, _.imag -> 0.S),
enable = io.load
)
when(io.clr) {
sample <> sample.fromBits(0.S) // <-- I tried this it compiles, but dont know if it is correct
}
}

Spray json trait formatter with nested subclasses

My use-case is the following:
import spray.json._
import DefaultJsonProtocol._
sealed trait TestT
case class A(a: String) extends TestT
case class B(b: String) extends TestT
case class C(c: TestT) extends TestT
case class Parent(list: Seq[TestT])
implicit val aFormat = jsonFormat1(A)
implicit val bFormat = jsonFormat1(B)
implicit lazy val cFormat = lazyFormat(jsonFormat1(C))
implicit object TestTJsonFormat extends RootJsonFormat[TestT] {
override def read(json: JsValue) = {
if(json.asJsObject.fields.get("a").isDefined) {
json.convertTo[A]
} else if(json.asJsObject.fields.get("b").isDefined) {
json.convertTo[B]
} else if(json.asJsObject.fields.get("c").isDefined) {
json.convertTo[C]
} else {
???
}
}
override def write(obj: TestT) = {
obj match {
case a:A => a.toJson
case b:B => b.toJson
case c:C => c.toJson
case _ => ???
}
}
}
implicit val pFormat = jsonFormat1(Parent)
val json = Parent(Seq(A("test"), B("test2"), A("test3"))).toJson
println(json)
val p = json.convertTo[Parent]
println(p)
The main problem is that I can't make a formatter for C if I don't have a formatter for TestT. But I can't make a formatter for TestT because I don't have a json.convertTo for C yet...
Any idea how can I resolve this form of dependency?
https://github.com/milessabin/spray-json-shapeless
Serialize whole classtrees.
object MyFormats extends DefaultJsonProtocol with FamilyFormats {
// gives a slight performance boost, but isn't necessary
implicit val MyAdtFormats = shapeless.cachedImplicit[JsonFormat[TestT]]
}
import MyFormats._

Chisel3: Bitwise negation operator

There appears to be either a bug with or undocumented changes to the bitwise negation operator between chisel2 and chisel3.
Chisel3 code not working
import chisel3._
class bitwise_neg extends Module {
val io = new Bundle {
val in = Input(UInt(4.W))
val out = Output(UInt(4.W))
}
io.out := ~io.in
}
Error message generated for line containing "~":
type mismatch; found : ()chisel3.core.Bits required: chisel3.core.Data
Chisel2 working code
import Chisel._
class bitwise_neg extends Module {
val io = new Bundle {
val in = UInt(INPUT, 4)
val out = UInt(OUTPUT, 4)
}
io.out := ~io.in
}
Any ideas on the new Chisel3 syntax or if this is a bug?
The problem is not related to the ~, you will get the same error even if you remove the ~. Just as jkoenig said, chisel3 requires that you wrap the io bundle in an IO() like this:
class bitwise_neg extends Module {
val io = IO(new Bundle {
val in = Input(UInt(4.W))
val out = Output(UInt(4.W))
})
io.out := ~io.in
}
If you want (but I wouldn't recommend it) you can use chisel2 notation using the compatibility layer in chisel3 with capital chisel import import Chisel._
import Chisel._
class bitwise_neg extends Module {
val io = new Bundle {
val in = UInt(INPUT, 4.W)
val out = UInt(OUTPUT, 4.W)
}
io.out := io.in
}