Wednesday, October 4, 2017

To link Chisel annotations and circuit info

Here's another snippet of Chisel code.  It was well worth the (ashamed to admit) 4+ hrs to write.  Admittedly, I am still getting a hand of functional programming.  I am particularly proud of the recursive function call to populate an immutable val.  The function's use case is to return Chisel circuit level information from an Annotation object.  It is necessary because Annotation does not contain (do best of my knowledge) a reference to a Data object.


  private def getDirection(circuit: Circuit, a: Annotation): ActualDirection = {
    // get net info from annotation object
    val thisModName = a.target.asInstanceOf[ComponentName].module.name
    val thisPortName = a.target.name.replace("io.", "") // FIXME: this is a HACK ..

    // find matching module in Chisel circuit
    val module = circuit.components.flatMap {
      case m: DefModule => Some(m)
      case b: DefBlackBox => None
    }.find {
      _.name == thisModName
    }.head

    // recursively return Element objects
    def elemsFromData(d: Data): Seq[Element] = d match {
      case e: Element => Seq(e)
      case r: Record =>
        r.elements.flatMap((e: (String, Data)) => {
          elemsFromData(e._2)
        }).toSeq
    }

    // all elements for all module port
    val elems: Seq[Element] = module.ports.flatMap((p: Port) => {
      elemsFromData(p.id)
    })

    // use DataMirror to find direction, have yet to test whether fully accurate
    // FIXME: obviously not optimal, should filter above
    val dir = DataMirror.directionOf(elems.find(_.name == thisPortName).head)
    dir
  }