Saturday, May 6, 2017

Use of HellaQueue in Chisel, secondary constructor

This post is an expanded update to an entry in my personal "NOTES" file.  At first glance, I found the following code perplxing, therefore I decided to break it down.

class HellaQueue[T <: Data](val entries: Int)(data: => T) extends Module {
  val io = new QueueIO(data, entries)

  val fq = Module(new HellaFlowQueue(entries)(data)) <> io.enq
  io.deq <> Queue(, 1, pipe = true)

object HellaQueue {
  def apply[T <: Data](enq: DecoupledIO[T], entries: Int) = {
    val q = Module((new HellaQueue(entries)) { enq.bits }) := enq.valid // not using <> so that override is allowed := enq.bits
    enq.ready :=

What does the :< operator do in [T <: Data>]?

It is obvious (to me at least) that this is for type parameterization.  The <: operator indicates that the type supplied to the class instance must have chisel3.core.Data as an ancestor.

Why does (data: => T) do?

No suprise that (val entries: Int) is the primary constructor.  The fat arrow (=>) implies a function.  The first argument to the constructor lets you specific the number of entries.  The second argument data helps to parameterize the class.

// example usage
val xy: Data
val hq1 = (new HellaQueue(entries = 90)){xy}
// equivalent to above, without (data: => T) in the class constructor
val hq2 = (new HellaQueue[SInt](entries = 90))

Why is a class definion and a object definition of the same name?

The object is known as a companion class, consult for more info

What does the apply function do in the object?

The apply function acts as an auxillary constructor.  Allows alternative syntax for creating HellaQueue.

No comments:

Post a Comment