Tuesday, May 2, 2017

One simple command and voila ...


I have been trying to get IntelliJ IDEA's debugger working with Scala (support via plugin) for the better part of this past week.  Each time the debugger was launched, I hit an issue that presented itself as a runtime exception: ClassNotFoundException for: org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.

My initial guess was "JAR Hell".  The best trick I found for debugging library dependency issues is using sbt-depdency-graph plugin to visualize the dependency tree using sbt.  To make use of the plugin you you need to add the following line to your plugins.sbt file.  Use command sbt dependencyTree to view the output (library dependency tree) of the plugin.

addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.8.2")

Turns it that it wasn't a library dependency issue.  This is the hint that finally unblocked me:

Connected to the target VM, address: '127.0.0.1:36512', transport: 'socket'

Luckily enough, I knew that something was up with my firewall as my Jenkins instance was no longer accepting connections.  I had yet to debug this.  On further inspection, I found my workstation's firewall rules had been completely wiped.  The effect was no local TCP connections werepossible.  The simple solution was to re-add the loopback network interface (lo) to firewalld and apply the trusted firewall zone to it.  The not-so-simple solution, aka. the one that I first tried, was to identify the ports that IDEA's Scala plugin uses for local remote debugging.  It turns out the port choice is random, thus the simple solution.

% firewall-cmd --zone=trusted --add-interface=lo --permanent

The debugger works fine now.

Tuesday, April 18, 2017

PeekPokeTester and LazyModule

In Chisel, it appears that PeekPokeTester doesn't play well with LazyModule.  If ChiselTop is a LazyModule (not Module), the following will not work.

  class ChiselTopTester(c: ChiselTop) extends PeekPokeTester(c) { }

Adding a wrapper class around the LazyModule instance solves the problem.

class ChiselTopTest extends ChiselFlatSpec {

  class ChiselTopTester(c: ChiselTopWrapper) extends PeekPokeTester(c) {
    println("Hello World!")
  }

  // hint from: https://github.com/ucb-bar/rocket-chip/issues/359
  class ChiselTopWrapper(p: Parameters) extends Module {
    val top = Module(LazyModule(new ChiselTop()(p)).module)
    val io = top.io.cloneType
    io <> top.io
  }

  implicit val p: Parameters = new BlankConfig
  chisel3.iotesters.Driver(() => new ChiselTopWrapper(p)) { c => new ChiselTopTester(c) }
}

In other news, my Scala skills are improving...

Friday, April 14, 2017

Parameters and lazy modules

I haven't looked at rocket chip in ~2 years or so.  Wow, did it grow in complexity.  One area where I am lacking familiarily (and where documentation is notably absent) is in the use of TileLink2.  For the purpose of learning and exploration, I'll take it one step at a time and try to connect a single AHB master to an AHB slave using TileLink.

One stumbling block was the use of parameters and lazy modules.  Rocket uses the content dependent environment package for configuring its components.  The project template repo offers some explanation on the use of the cake pattern (design pattern) for allowing configuration to complete before hardware elaboration begins (paraphrasing, here).  Here is another thread that discusses the strategy.

On to some code (module elaboration only) ...

// Define your very own configuration object ...

case object BlankField extends Field[Boolean]

class BlankConfig extends Config((site, here, up) => {
  case BlankField => false
})

// Pay close attention to use of LazyModule and LazyModuleImp ...

object ChiselTopDriver extends App {
  implicit val p: Parameters = new BlankConfig
  chisel3.Driver.execute(args, () => LazyModule(new ChiselTop).module)
}

class ChiselTop()(implicit p: Parameters) extends LazyModule {
  val master = LazyModule(new AHBMaster)
  val slave = LazyModule(new AHBSlave)

  slave.node := master.node // does not work.. yet..

   lazy val module = new LazyModuleImp(this) {
    val io = new Bundle {
      val ddrClock = Input(Clock())
      val ddrReset = Input(UInt(1.W))
    }
  }
}

class AHBMaster()(implicit p: Parameters) extends LazyModule
{
  val node = AHBOutputNode() // does not work.. yet..

  lazy val module = new LazyModuleImp(this) {
    val io = new Bundle {
      val out = node.bundleOut
    }
  }
}

class AHBSlave()(implicit p: Parameters) extends LazyModule
{
  val node = AHBInputNode() // does not work.. yet..

  lazy val module = new LazyModuleImp(this) {
    val io = new Bundle {
      val in = node.bundleIn
    }
  }
}

Friday, March 24, 2017

Register a bundle in Chisel

I have been playing with more with Chisel lately.  An area I find lacking in the documentation is how to register a bundle (i.e. struct).  Most examples I have seen use simple registers with type UInt.

It took some trial and error, but here is an example that elaborates and synthesizes properly.

class DDR3Command extends Bundle {
  val casN = UInt(1.W)
  val rasN = UInt(1.W)
  val ba = UInt(3.W)

  // user function to specify defaults (sync reset)
  def defaults() = {
    casN := 1.U
    rasN := 1.U
    ba := 0.U
  }
}

class MemoryController extends Module {
  val io = IO(new Bundle {
    val ddr3 = Output(new DDR3Command())
  })

  // create a wire of the bundle and set it's default values (sync reset)
  val resetDDR3Cmd = Wire(new DDR3Command())
  resetDDR3Cmd.defaults()

  val nextDDR3Cmd = Reg(new DDR3Command(), init=resetDDR3Cmd)

  // for example purposes, only update select fields
  when (true.B) {
    nextDDR3Cmd.ba := 3.U
    nextDDR3Cmd.casN := 0.U
    //nextDDR3Cmd.rasN := 1.U
  }

  io.ddr3 := nextDDR3Cmd
}

Friday, March 10, 2017

REX to Intel and proud of the team


I left REX Computing about 1 year ago for reasons I choose not to disclose publically.  What I will say is that I am proud of the team to have brought the design through final tapeout, board development and now bring up.  I'm looking forward to the final power & performance numbers and, hopefully, an announcement about the software stack.  Here's Thomas (smart guy, 2013 Thiel fellow) presenting the hardware at Standford.  It's not the best quality and they were hit by Murphy's Law during the demo.  I'll switch up the video when a better presentation becomes available.



I am at Intel now (have been for 1 year).  The team develops verification testbench collateral to support the functional verification of their Xeon-line of server CPUs (Xeon, Xeon PHI, Xeon-D, etc.).  In a nutshell, my role is to manage a portion of a distributed "software" team (and virtual team) within a large organization that works on scrum-like sprints.  I am being challenged in different ways than previous - thus I am growing and grateful.

No official comment yet on the previous post.