Debugging module internals in Chisel - chisel

I have a complex module written in Chisel. I'm using chiseltest to verify its operation. The test is failing. I want to be able to inspect the module's internal wire values to debug what is going wrong. Since the PeekPokeTester only allows me to inspect the value of the io signals, how can I inspect the internal wires?
Here is an example:
import chisel3._
class MyModule extends Module {
val io = IO(new Bundle {
val a = Input(Bool())
val b = Input(Bool())
val c = Input(Bool())
val d = Output(Bool())
})
val i = Wire(Bool())
i := io.a ^ io.b
io.d := i | io.c
}
import chisel3._
import chisel3.tester._
import org.scalatest.FreeSpec
class MyModuleTest extends FreeSpec with ChiselScalatestTester {
"MyModule should work properly" in {
test(new MyModule) { dut =>
dut.io.a.poke(true.B)
dut.io.b.poke(false.B)
dut.io.c.poke(false.B)
dut.i.expect(true.B) // This line throws a java.util.NoSuchElementException
// : key not found: Bool(Wire in MyModule)
}
}
}
How can I inspect the intermediate value "i"?

There's a few ways to do this.
1 ) Turn on VCD output by adding an annotation to your test, as in
import chiseltest.experimental.TestOptionBuilder._
import treadle._
...
test(new MyModule).withAnnotations(Seq(WriteVcdAnnotation)) { dut =>
The .vcd file will be placed in the relevant test_run_dir/ you can view it with GtkWave or similar
2 ) add printf statements to your module.
3 ) There is a simulation shell in the Treadle Repo that allows you to peek poke and step based on a firrtl file (the firrtl file should be in the same test_run_dir/ directory as above). There is A bit of documentation here
Good luck!

Related

Generating Verilog code after BlackBoxing in Chisel3

I am trying BlackBox feature in Chisel3. Every time I try to generate Verilog code of Chisel I got an error.
I followed the right steps, writing the class, class driver and build.sbt.
I am not sure where the problem is
This is my Chisel Code
import chisel3._
import chisel3.util._
import chisel3.experimental._
class BlackBoxRealAdd extends BlackBox with HasBlackBoxInline {
val io = IO(new Bundle() {
val in1 = Input(UInt(64.W))
val in2 = Input(UInt(64.W))
val out = Output(UInt(64.W))
})
setInline("BlackBoxRealAdd.v",
s"""
|module BlackBoxRealAdd(
| input [15:0] in1,
| input [15:0] in2,
| output [15:0] out
|);
|always #* begin
| out <= (in1) + (in2));
|end
|endmodule
""".stripMargin)
}
object BlackBoxRealAddDriver extends App {
chisel3.Driver.execute(args, () => new BlackBoxRealAdd)
}
scalaVersion := "2.11.12"
resolvers ++= Seq(
Resolver.sonatypeRepo("snapshots"),
Resolver.sonatypeRepo("releases")
)
libraryDependencies += "edu.berkeley.cs" %% "chisel3" % "3.1.+"
I have figured it out. The blackboxed module shouldn't be the top one.

parsing JSON into classes with Option[T] arg types in spark-shell with Scala

I'm having trouble parsing JSON with json4s.jackson in spark-shell. The same thing works fine in sbt repl.
I wonder if there's a workaround for the version of Spark I'm using.
spark-shell v1.6, scala v2.10.5
sbt repl scala v 2.11.8
.
The following example demonstrates the problem.
sbt repl works as expected for all examples.
spark-shell chokes and gives an error for val c. What's weird is that it seems to choke on Option[Int] or Option[Double] but it works fine for Option[A] where A is a class.
.
import org.json4s.JsonDSL._
import org.json4s.jackson.JsonMethods.{render,compact,pretty}
import org.json4s.DefaultFormats
import org.json4s.jackson.JsonMethods._
import org.json4s.{JValue, JObject}
implicit val formats = DefaultFormats
class A(val a: Int, val aa: Int)
class B(val b: Int, val optA: Option[A]=None)
class C(val b: Int, val bb: Option[Int]=None)
val jb_optA_nested: JObject = ("b" -> 5) ~ ("optA" -> ("a" -> 999) ~ ("aa" -> 1000))
val jb_optA_not_nested: JObject = ("b" -> 5) ~ ("a" -> 999) ~ ("aa" -> 1000)
val jb_optA_none: JObject = ("b" -> 5)
val jc: JObject = ("b" -> 5) ~ ("bb" -> 100)
val b_nested = jb_optA_nested.extract[B] // works as expected in both (optA=Some(A(999,1000)))
val b_not_nested = jb_optA_not_nested.extract[B] // works as expected in both (optA=None)
val b_none = jb_optA_none.extract[B] // works as expected in both (optA=None)
val c = jc.extract[C] // error in spark-shell; works fine in sbt repl
The error generated is: org.json4s.package$MappingException: Can't find constructor for C
The only real difference I can find (other than scala versions) is that in spark-shell... it chokes on Option[native types] and seems to work on Option[user-defined classes]. But maybe that's coincidence.
In posts like this... JSON4s can't find constructor w/spark I see comments where people suggest the class structure doesn't match the JSON... but to me, class C and val jc look identical.
Also of note... this error persists when I harden class defs and functions in a .JAR and import defs into spark-shell from the jar instead of defining in the repl. sometimes that's relevant for spark 1.6, but doesn't seem to be here.
Have you tried:
class C(val b: Int, val bb: Option[java.lang.Integer]=None)
I've had issues with the Scala Int before with Json4s - although I can't recall exactly what it was.
Also doing a case class is worthwhile with the Int - any reason you prefer a regular class? I don't see any vars.

Encoding/Decode shapeless records with circe

Upgrading circe from 0.4.1 to 0.7.0 broke the following code:
import shapeless._
import syntax.singleton._
import io.circe.generic.auto._
.run[Record.`'transaction_id -> Int`.T](transport)
def run[A](transport: Json => Future[Json])(implicit decoder: Decoder[A], exec: ExecutionContext): Future[A]
With the following error:
could not find implicit value for parameter decoder: io.circe.Decoder[shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("transaction_id")],Int],shapeless.HNil]]
[error] .run[Record.`'transaction_id -> Int`.T](transport)
[error] ^
Am I missing some import here or are these encoders/decoders not available in circe anymore?
Instances for Shapeless's hlists, records, etc. were moved to a separate circe-shapes module in the circe 0.6.0 release. If you add this module to your build, the following should just work:
import io.circe.jawn.decode, io.circe.shapes._
import shapeless._, record.Record, syntax.singleton._
val doc = """{ "transaction_id": 1 }"""
val res = decode[Record.`'transaction_id -> Int`.T](doc)
The motivation for moving these instances was that the improved generic derivation introduced in 0.6 meant that they were no longer necessary, and keeping them out of implicit scope when they're not needed is both cleaner and potentially supports faster compile times. The new circe-shapes module also includes features that were not available in circe-generic, such as instances for coproducts.

How can I generate FIRRTL from chisel code?

How can I generate FIRRTL file from chisel code? I have installed sbt, firrtl and verilator according to the github wiki. And created a chisel code for simple adder. I want to generate the FIRRTL and covert it to Verilog? My problem is how to get the firrtl file from the chisel code.
Thanks.
Source file : MyQueueTest/src/main/scala/example/MyQueueDriver.scala
package example
import chisel3._
import chisel3.util._
class MyQueue extends Module {
val io = IO(new Bundle {
val a = Flipped(Decoupled(UInt(32.W)))
val b = Flipped(Decoupled(UInt(32.W)))
val z = Decoupled(UInt(32.W))
})
val qa = Queue(io.a)
val qb = Queue(io.b)
qa.nodeq()
qb.nodeq()
when (qa.valid && qb.valid && io.z.ready) {
io.z.enq(qa.deq() + qb.deq())
}
}
object MyQueueDriver extends App {
chisel3.Driver.execute(args, () => new MyQueue)
}
I asked a similar question here.
The solution could be to use full template provided here, or you can simply do that:
Add these lines at the end of your scala sources :
object YourModuleDriver extends App {
chisel3.Driver.execute(args, () => new YourModule)
}
Replacing "YourModule" by the name of your module.
And add a build.sbt file in the same directory of your sources with these lines :
scalaVersion := "2.11.8"
resolvers ++= Seq(
Resolver.sonatypeRepo("snapshots"),
Resolver.sonatypeRepo("releases")
)
libraryDependencies += "edu.berkeley.cs" %% "chisel3" % "3.0-SNAPSHOT"
To generate FIRRTL and Verilog you will just have to do :
$ sbt "run-main YourModuleDriver"
And the FIRRTL (yourmodule.fir) /Verilog (yourmodule.v) sources will be in generated directory.

Why does this getOrElse statement return type ANY?

I am trying to follow the tutorial https://www.jamesward.com/2012/02/21/play-framework-2-with-scala-anorm-json-coffeescript-jquery-heroku but of course play-scala has changed since the tutorial (as seems to be the case with every tutorial I find). I am using 2.4.3 This requires I actually learn how things work, not necessarily a bad thing.
One thing that is giving me trouble is the getOrElse method.
Here is my Bar.scala model
package models
import play.api.db._
import play.api.Play.current
import anorm._
import anorm.SqlParser._
case class Bar(id: Option[Long], name: String)
object Bar {
val simple = {
get[Option[Long]]("id") ~
get[String]("name") map {
case id~name => Bar(id, name)
}
}
def findAll(): Seq[Bar] = {
DB.withConnection { implicit connection =>
SQL("select * from bar").as(Bar.simple *)
}
}
def create(bar: Bar): Unit = {
DB.withConnection { implicit connection =>
SQL("insert into bar(name) values ({name})").on(
'name -> bar.name
).executeUpdate()
}
}
}
and my BarFormat.scala Json formatter
package models
import play.api.libs.json._
import anorm._
package object Implicits {
implicit object BarFormat extends Format[Bar] {
def reads(json: JsValue):JsResult[Bar] = JsSuccess(Bar(
Option((json \ "id").as[Long]),
(json \ "name").as[String]
))
def writes(bar: Bar) = JsObject(Seq(
"id" -> JsNumber(bar.id.getOrElse(0L)),
"name" -> JsString(bar.name)
))
}
}
and for completeness my Application.scala controller:
package controllers
import play.api.mvc._
import play.api.data._
import play.api.data.Forms._
import javax.inject.Inject
import javax.inject._
import play.api.i18n.{ I18nSupport, MessagesApi, Messages, Lang }
import play.api.libs.json._
import views._
import models.Bar
import models.Implicits._
class Application #Inject()(val messagesApi: MessagesApi) extends Controller with I18nSupport {
val barForm = Form(
single("name" -> nonEmptyText)
)
def index = Action {
Ok(views.html.index(barForm))
}
def addBar() = Action { implicit request =>
barForm.bindFromRequest.fold(
errors => BadRequest,
{
case (name) =>
Bar.create(Bar(None, name))
Redirect(routes.Application.index())
}
)
}
def listBars() = Action { implicit request =>
val bars = Bar.findAll()
val json = Json.toJson(bars)
Ok(json).as("application/json")
}
and routes
# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~
# Home page
POST /addBar controllers.Application.addBar
GET / controllers.Application.index
GET /listBars controllers.Application.listBars
# Map static resources from the /public folder to the /assets URL path
GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset)
When I try to run my project I get the following error:
now bar.id is defined as an Option[Long] so bar.id.getOrElse(0L) should return a Long as far as I can tell, but it is clearly returning an Any. Can anyone help me understand why?
Thank You!
That's the way type inference works in Scala...
First of all there is an implicit conversion from Int to BigDecimal:
scala> (1 : Int) : BigDecimal
res0: BigDecimal = 1
That conversion allows for Int to be converted before the option is constructed:
scala> Some(1) : Option[BigDecimal]
res1: Option[BigDecimal] = Some(1)
If we try getOrElse on its own where the type can get fixed we get expected type Int:
scala> Some(1).getOrElse(2)
res2: Int = 1
However, this does not work (the problem you have):
scala> Some(1).getOrElse(2) : BigDecimal
<console>:11: error: type mismatch;
found : Any
required: BigDecimal
Some(1).getOrElse(2) : BigDecimal
^
Scala's implicit conversions kick in last, after type inference is performed. That makes sense, because if you don't know the type how would you know what conversions need to be applied. Scala can see that BigDecimal is expected, but it has an Int result based on the type of the Option it has. So it tries to widen the type, can't find anything that matches BigDecimal in Int's type hierarchy and fails with the error.
This works, however because the type is fixed in the variable declaration:
scala> val v = Some(1).getOrElse(2)
v: Int = 1
scala> v: BigDecimal
res4: BigDecimal = 1
So we need to help the compiler somehow - any type annotation or explicit conversion would work. Pick any one you like:
scala> (Some(1).getOrElse(2) : Int) : BigDecimal
res5: BigDecimal = 1
scala> Some(1).getOrElse[Int](2) : BigDecimal
res6: BigDecimal = 1
scala> BigDecimal(Some(1).getOrElse(2))
res7: scala.math.BigDecimal = 1
Here is the signature for Option.getOrElse method:
getOrElse[B >: A](default: ⇒ B): B
The term B >: A expresses that the type parameter B or the abstract type B refer to a supertype of type A, in this case, Any being the supertype of Long:
val l: Long = 10
val a: Any = l
So, we can do something very similar here with getOrElse:
val some: Option[Long] = Some(1)
val value: Any = option.getOrElse("potatos")
val none: Option[Long] = None
val elseValue: Any = none.getOrElse("potatos")
Which brings us to your scenario: the returned type from getOrElse will be a Any and not a BigDecimal, so you will need another way to handle this situation, like using fold, per instance:
def writes(bar: Bar) = {
val defaultValue = BigDecimal(0)
JsObject(Seq(
"id" -> JsNumber(bar.id.fold(defaultValue)(BigDecimal(_))),
"name" -> JsString(bar.name)
))
}
Some other discussions that can help you:
Why is Some(1).getOrElse(Some(1)) not of type Option[Int]?
Option getOrElse type mismatch error