From e1e7c7ea3359df1351ba979287b62458e411e846 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Mon, 8 Aug 2016 16:54:05 -0700 Subject: Provide public SignalID trait to be used to conjure up a signal identifier. --- .../src/main/scala/chisel3/core/Module.scala | 3 +++ .../src/main/scala/chisel3/internal/Builder.scala | 21 ++++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Module.scala b/chiselFrontend/src/main/scala/chisel3/core/Module.scala index 5af744c4..4f25515b 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Module.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Module.scala @@ -63,6 +63,9 @@ extends HasId { /** Legalized name of this module. */ final val name = Builder.globalNamespace.name(desiredName) + /** Signal name (for simulation). */ + override def signalName(component: Component) = name + /** IO for this Module. At the Scala level (pre-FIRRTL transformations), * connections in and out of a Module may only go through `io` elements. */ diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index cecbd91e..dd4b3264 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -55,11 +55,30 @@ private[chisel3] class IdGen { } } -private[chisel3] trait HasId { +/** Public API to Nodes. + * currently, the node's name, the full path name, and a reference to its parent. + */ +trait SignalID { + def signalName(component: Component): String + def signalPathName(component: Component, separator: String = "_"): String + def signalParent: Module +} + +private[chisel3] trait HasId extends SignalID { private[chisel3] def _onModuleClose {} // scalastyle:ignore method.name private[chisel3] val _parent = Builder.dynamicContext.currentModule _parent.foreach(_.addId(this)) + // Implementation of public methods. + override def signalParent = _parent.get + override def signalName(component: Component) = _ref.get.fullName(component) + override def signalPathName(component: Component, separator: String = "_"): String = { + _parent match { + case Some(p) => p.signalPathName(component, separator) + separator + signalName(component) + case None => signalName(component) + } + } + private[chisel3] val _id = Builder.idGen.next override def hashCode: Int = _id.toInt override def equals(that: Any): Boolean = that match { -- cgit v1.2.3 From 0744b3e5f9c0648878b97d3375cd7d88e2d0ee08 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Wed, 10 Aug 2016 17:07:31 -0700 Subject: Add component to signature. --- chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala | 3 +-- chiselFrontend/src/main/scala/chisel3/internal/Builder.scala | 9 ++++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 15643ac8..de64cb3d 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -374,5 +374,4 @@ class Bundle extends Aggregate(NO_DIR) { private[core] object Bundle { val keywords = List("flip", "asInput", "asOutput", "cloneType", "toBits", - "widthOption") -} + "widthOption", "signalName", "signalPathName", "signalParent", "signalComponent") diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index dd4b3264..21f32483 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -55,13 +55,15 @@ private[chisel3] class IdGen { } } -/** Public API to Nodes. - * currently, the node's name, the full path name, and a reference to its parent. +/** Public API to access Node/Signal names. + * currently, the node's name, the full path name, and references to its parent Module and component. + * These are only valid once the design has been elaborated, and should not be used during its construction. */ trait SignalID { def signalName(component: Component): String - def signalPathName(component: Component, separator: String = "_"): String + def signalPathName(component: Component, separator: String = "."): String def signalParent: Module + def signalComponent: Option[Component] } private[chisel3] trait HasId extends SignalID { @@ -78,6 +80,7 @@ private[chisel3] trait HasId extends SignalID { case None => signalName(component) } } + override def signalComponent: Option[Component] = None private[chisel3] val _id = Builder.idGen.next override def hashCode: Int = _id.toInt -- cgit v1.2.3 From 2d01fdf6f26f480cb7ed19c1365f181ea717ddc2 Mon Sep 17 00:00:00 2001 From: Donggyu Kim Date: Mon, 15 Aug 2016 18:03:12 -0700 Subject: provides signal name methods for firrtl annotation and chisel testers * signalName: returns the chirrtl name of the signal * pathName: returns the full path name of the signal from the top module * parentPathName: returns the full path of the signal's parent module instance from the top module * parentModName: returns the signal's parent **module(not instance)** name. --- .../src/main/scala/chisel3/core/Aggregate.scala | 3 +- .../src/main/scala/chisel3/core/Module.scala | 22 ++++++++++- .../src/main/scala/chisel3/internal/Builder.scala | 44 +++++++++++++--------- src/main/scala/chisel3/Driver.scala | 2 + .../scala/chisel3/internal/firrtl/Emitter.scala | 16 ++------ 5 files changed, 54 insertions(+), 33 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index de64cb3d..82c6097f 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -374,4 +374,5 @@ class Bundle extends Aggregate(NO_DIR) { private[core] object Bundle { val keywords = List("flip", "asInput", "asOutput", "cloneType", "toBits", - "widthOption", "signalName", "signalPathName", "signalParent", "signalComponent") + "widthOption", "signalName", "signalPathName", "signalParent", "signalComponent") +} diff --git a/chiselFrontend/src/main/scala/chisel3/core/Module.scala b/chiselFrontend/src/main/scala/chisel3/core/Module.scala index 4f25515b..eb48a14d 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Module.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Module.scala @@ -31,7 +31,9 @@ object Module { m._commands.prepend(DefInvalid(childSourceInfo, m.io.ref)) // init module outputs dynamicContext.currentModule = parent val ports = m.computePorts - Builder.components += Component(m, m.name, ports, m._commands) + val component = Component(m, m.name, ports, m._commands) + m._component = Some(component) + Builder.components += component pushCommand(DefInstance(sourceInfo, m, ports)) m.setupInParent(childSourceInfo) } @@ -63,8 +65,24 @@ extends HasId { /** Legalized name of this module. */ final val name = Builder.globalNamespace.name(desiredName) + /** FIRRTL Module name */ + private var _modName: Option[String] = None + private[chisel3] def setModName(name: String) = _modName = Some(name) + def modName = _modName match { + case Some(name) => name + case None => throwException("modName should be called after circuit elaboration") + } + + /** Keep component for signal names */ + private[chisel3] var _component: Option[Component] = None + + /** Signal name (for simulation). */ - override def signalName(component: Component) = name + override def signalName = + if (_parent == None) name else _component match { + case None => getRef.name + case Some(c) => getRef fullName c + } /** IO for this Module. At the Scala level (pre-FIRRTL transformations), * connections in and out of a Module may only go through `io` elements. diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index 21f32483..bf78c410 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -59,29 +59,18 @@ private[chisel3] class IdGen { * currently, the node's name, the full path name, and references to its parent Module and component. * These are only valid once the design has been elaborated, and should not be used during its construction. */ -trait SignalID { - def signalName(component: Component): String - def signalPathName(component: Component, separator: String = "."): String - def signalParent: Module - def signalComponent: Option[Component] +trait SignalId { + def signalName: String + def pathName: String + def parentPathName: String + def parentModName: String } -private[chisel3] trait HasId extends SignalID { +private[chisel3] trait HasId extends SignalId { private[chisel3] def _onModuleClose {} // scalastyle:ignore method.name private[chisel3] val _parent = Builder.dynamicContext.currentModule _parent.foreach(_.addId(this)) - // Implementation of public methods. - override def signalParent = _parent.get - override def signalName(component: Component) = _ref.get.fullName(component) - override def signalPathName(component: Component, separator: String = "_"): String = { - _parent match { - case Some(p) => p.signalPathName(component, separator) + separator + signalName(component) - case None => signalName(component) - } - } - override def signalComponent: Option[Component] = None - private[chisel3] val _id = Builder.idGen.next override def hashCode: Int = _id.toInt override def equals(that: Any): Boolean = that match { @@ -117,6 +106,27 @@ private[chisel3] trait HasId extends SignalID { private[chisel3] def setRef(parent: HasId, index: Int): Unit = setRef(Index(Node(parent), ILit(index))) private[chisel3] def setRef(parent: HasId, index: UInt): Unit = setRef(Index(Node(parent), index.ref)) private[chisel3] def getRef: Arg = _ref.get + + // Implementation of public methods. + def signalName = _parent match { + case Some(p) => p._component match { + case Some(c) => getRef fullName c + case None => throwException("signalName/pathName should be called after circuit elaboration") + } + case None => throwException("this cannot happen") + } + def pathName = _parent match { + case None => signalName + case Some(p) => s"${p.pathName}.$signalName" + } + def parentPathName = _parent match { + case Some(p) => p.pathName + case None => throwException(s"$signalName doesn't have a parent") + } + def parentModName = _parent match { + case Some(p) => p.modName + case None => throwException(s"$signalName doesn't have a parent") + } } private[chisel3] class DynamicContext { diff --git a/src/main/scala/chisel3/Driver.scala b/src/main/scala/chisel3/Driver.scala index 0979314f..5aeeef99 100644 --- a/src/main/scala/chisel3/Driver.scala +++ b/src/main/scala/chisel3/Driver.scala @@ -112,6 +112,8 @@ object Driver extends BackendCompilationUtilities { def emit[T <: Module](gen: () => T): String = Emitter.emit(elaborate(gen)) + def emit[T <: Module](ir: Circuit): String = Emitter.emit(ir) + def dumpFirrtl(ir: Circuit, optName: Option[File]): File = { val f = optName.getOrElse(new File(ir.name + ".fir")) val w = new FileWriter(f) diff --git a/src/main/scala/chisel3/internal/firrtl/Emitter.scala b/src/main/scala/chisel3/internal/firrtl/Emitter.scala index 31856541..79f86ae9 100644 --- a/src/main/scala/chisel3/internal/firrtl/Emitter.scala +++ b/src/main/scala/chisel3/internal/firrtl/Emitter.scala @@ -27,11 +27,7 @@ private class Emitter(circuit: Circuit) { case e: Stop => s"stop(${e.clk.fullName(ctx)}, UInt<1>(1), ${e.ret})" case e: Printf => s"""printf(${e.clk.fullName(ctx)}, UInt<1>(1), "${e.format}"${e.ids.map(_.fullName(ctx)).fold(""){_ + ", " + _}})""" case e: DefInvalid => s"${e.arg.fullName(ctx)} is invalid" - case e: DefInstance => { - val modName = moduleMap.get(e.id.name).get - s"inst ${e.name} of $modName" - } - + case e: DefInstance => s"inst ${e.name} of ${e.id.modName}" case w: WhenBegin => indent() s"when ${w.pred.fullName(ctx)} :" @@ -47,8 +43,6 @@ private class Emitter(circuit: Circuit) { // Map of Module FIRRTL definition to FIRRTL name, if it has been emitted already. private val defnMap = collection.mutable.HashMap[(String, String), Component]() - // Map of Component name to FIRRTL id. - private val moduleMap = collection.mutable.HashMap[String, String]() /** Generates the FIRRTL module declaration. */ @@ -89,15 +83,11 @@ private class Emitter(circuit: Circuit) { defnMap get (m.id.desiredName, defn) match { case Some(duplicate) => - moduleMap(m.name) = duplicate.name + m.id setModName duplicate.name "" case None => - require(!(moduleMap contains m.name), - "emitting module with same name but different contents") - - moduleMap(m.name) = m.name defnMap((m.id.desiredName, defn)) = m - + m.id setModName m.id.name moduleDecl(m) + defn } } -- cgit v1.2.3 From bc4f64020b8115d04af00e92bf9a7c68d9b35443 Mon Sep 17 00:00:00 2001 From: chick Date: Wed, 17 Aug 2016 16:12:33 -0700 Subject: Add annotating example to test new signal name api --- src/test/scala/chiselTests/AnnotatingExample.scala | 115 +++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 src/test/scala/chiselTests/AnnotatingExample.scala diff --git a/src/test/scala/chiselTests/AnnotatingExample.scala b/src/test/scala/chiselTests/AnnotatingExample.scala new file mode 100644 index 00000000..dc0d0421 --- /dev/null +++ b/src/test/scala/chiselTests/AnnotatingExample.scala @@ -0,0 +1,115 @@ +// See LICENSE for license details. + +package chiselTests + +import chisel3._ +import chisel3.core.Module +import chisel3.internal.Builder +import chisel3.internal.firrtl.{Emitter, Circuit} +import chisel3.testers.BasicTester +import org.scalatest._ +import org.scalatest.prop._ + +import scala.util.DynamicVariable + +class SomeSubMod extends Module { + val io = new Bundle { + val in = UInt(INPUT, 16) + val out = SInt(OUTPUT, 32) + } + MyBuilder.myDynamicContext.annotationMap(AnnotationKey(io.in, AllRefs)) = "sub mod io.in" + MyBuilder.myDynamicContext.annotationMap(AnnotationKey(io.out, JustThisRef)) = "sub mod io.out" +} + +class AnnotatingExample extends Module { + val io = new Bundle { + val a = UInt(INPUT, 32) + val b = UInt(INPUT, 32) + val e = Bool(INPUT) + val z = UInt(OUTPUT, 32) + val v = Bool(OUTPUT) + val bun = new Bundle { + val nested_1 = UInt(INPUT, 12) + val nested_2 = Bool(OUTPUT) + } + } + val x = Reg(UInt(width = 32)) + val y = Reg(UInt(width = 32)) + + val subModule1 = Module(new SomeSubMod) + val subModule2 = Module(new SomeSubMod) + + + val annotate = MyBuilder.myDynamicContext.annotationMap + + annotate(AnnotationKey(x, JustThisRef)) = "I am register X" + annotate(AnnotationKey(io.a, JustThisRef)) = "I am io.a" + annotate(AnnotationKey(io.bun.nested_1, JustThisRef)) = "I am io.bun.nested_1" + annotate(AnnotationKey(io.bun.nested_2, JustThisRef)) = "I am io.bun.nested_2" + + when (x > y) { x := x -% y } + .otherwise { y := y -% x } + when (io.e) { x := io.a; y := io.b } + io.z := x + io.v := y === UInt(0) +} + +class AnnotatingExampleTester(a: Int, b: Int, z: Int) extends BasicTester { + val dut = Module(new AnnotatingExample) + val first = Reg(init=Bool(true)) + dut.io.a := UInt(a) + dut.io.b := UInt(b) + dut.io.e := first + when(first) { first := Bool(false) } + when(!first && dut.io.v) { + assert(dut.io.z === UInt(z)) + stop() + } +} + +class AnnotatingExampleSpec extends ChiselPropSpec { + + property("show node info") { + MyDriver.doStuff { () => new AnnotatingExampleTester(1, 2, 3) } + } + +} + +trait AnnotationScope +case object Default extends AnnotationScope +case object AllRefs extends AnnotationScope +case object JustThisRef extends AnnotationScope + +case class AnnotationKey(val component: Data, scope: AnnotationScope) + +class MyDynamicContext { + val annotationMap = new scala.collection.mutable.HashMap[AnnotationKey, String] +} + +object MyBuilder { + private val myDynamicContextVar = new DynamicVariable[Option[MyDynamicContext]](None) + + def myDynamicContext: MyDynamicContext = + myDynamicContextVar.value getOrElse (new MyDynamicContext) + + def build[T <: Module](f: => T): Unit = { + myDynamicContextVar.withValue(Some(new MyDynamicContext)) { + Driver.emit(() => f) + val list = myDynamicContextVar.value.get.annotationMap.map { case (k,v) => + k match { + case (AnnotationKey(signal, JustThisRef)) => + f"Just this ref ${signal.pathName + signal.signalName}%60s -> $v%30s component $signal" + case (AnnotationKey(signal, AllRefs)) => + f"All refs ${signal.signalName}%60s -> $v%30s component $signal" + case _ => + s"Unknown annotation key $k" + } + }.toList.sorted + println(list.mkString("\n")) + } + } +} + +object MyDriver extends BackendCompilationUtilities { + def doStuff[T <: Module](gen: () => T): Unit = MyBuilder.build(Module(gen())) +} \ No newline at end of file -- cgit v1.2.3 From 3f771ee67b9f8fa0d92ce00af1ea062c5a2605b2 Mon Sep 17 00:00:00 2001 From: chick Date: Thu, 18 Aug 2016 13:03:16 -0700 Subject: Add AnnotationSpec file which provides an example of a way to implement generation of annotations in a chisel circuit that could be used by custom firrtl passes This spec also shows and tests in a limited way the new API of .signalName, .pathName, parentModName which allows access to the various path information of a chisel component (something that subclasses SignalId, most prominently SubClasses of Data and Module --- src/test/scala/chiselTests/AnnotatingExample.scala | 102 +++++++++++++++------ 1 file changed, 72 insertions(+), 30 deletions(-) diff --git a/src/test/scala/chiselTests/AnnotatingExample.scala b/src/test/scala/chiselTests/AnnotatingExample.scala index dc0d0421..073355fc 100644 --- a/src/test/scala/chiselTests/AnnotatingExample.scala +++ b/src/test/scala/chiselTests/AnnotatingExample.scala @@ -4,20 +4,31 @@ package chiselTests import chisel3._ import chisel3.core.Module -import chisel3.internal.Builder -import chisel3.internal.firrtl.{Emitter, Circuit} +import chisel3.internal.SignalId import chisel3.testers.BasicTester import org.scalatest._ -import org.scalatest.prop._ import scala.util.DynamicVariable -class SomeSubMod extends Module { +//scalastyle:off magic.number + +/** + * This Spec file illustrates use of Donggyu's component name API, it currently only + * uses three methods .signalName, .parentModName and .pathName + * + * This is also an illustration of how to implement an annotation system in chisel3 + * A local (my) Driver and Builder are created to provide thread-local access to + * an annotation map, and then a post elaboration annotation processor can resolve + * the keys and could serialize the annotations to a file for use by firrtl passes + */ + +class SomeSubMod(param1: Int, param2: Int) extends Module { val io = new Bundle { val in = UInt(INPUT, 16) val out = SInt(OUTPUT, 32) } - MyBuilder.myDynamicContext.annotationMap(AnnotationKey(io.in, AllRefs)) = "sub mod io.in" + MyBuilder.myDynamicContext.annotationMap(AnnotationKey(this, JustThisRef)) = s"SomeSubMod($param1, $param2)" + MyBuilder.myDynamicContext.annotationMap(AnnotationKey(io.in, AllRefs)) = "sub mod io.in" MyBuilder.myDynamicContext.annotationMap(AnnotationKey(io.out, JustThisRef)) = "sub mod io.out" } @@ -36,15 +47,17 @@ class AnnotatingExample extends Module { val x = Reg(UInt(width = 32)) val y = Reg(UInt(width = 32)) - val subModule1 = Module(new SomeSubMod) - val subModule2 = Module(new SomeSubMod) + val subModule1 = Module(new SomeSubMod(1, 2)) + val subModule2 = Module(new SomeSubMod(3, 4)) val annotate = MyBuilder.myDynamicContext.annotationMap + annotate(AnnotationKey(subModule2, AllRefs)) = s"SomeSubMod was used" + annotate(AnnotationKey(x, JustThisRef)) = "I am register X" annotate(AnnotationKey(io.a, JustThisRef)) = "I am io.a" - annotate(AnnotationKey(io.bun.nested_1, JustThisRef)) = "I am io.bun.nested_1" + annotate(AnnotationKey(io.bun.nested_1, AllRefs)) = "I am io.bun.nested_1" annotate(AnnotationKey(io.bun.nested_2, JustThisRef)) = "I am io.bun.nested_2" when (x > y) { x := x -% y } @@ -67,49 +80,78 @@ class AnnotatingExampleTester(a: Int, b: Int, z: Int) extends BasicTester { } } -class AnnotatingExampleSpec extends ChiselPropSpec { +class AnnotatingExampleSpec extends FlatSpec with Matchers { + behavior of "Annotating components of a circuit" - property("show node info") { - MyDriver.doStuff { () => new AnnotatingExampleTester(1, 2, 3) } + val annotationMap = MyDriver.doStuff { () => new AnnotatingExampleTester(1, 2, 3) } + it should "contain the following relative keys" in { + annotationMap.contains("SomeSubMod.io.in") should be(true) + annotationMap("SomeSubMod.io.in") should be("sub mod io.in") + } + it should "contain the following absolute keys" in { + annotationMap.contains("AnnotatingExampleTester.dut.subModule2.io.out") should be (true) + annotationMap("AnnotatingExampleTester.dut.subModule2.io.out") should be ("sub mod io.out") } - } trait AnnotationScope -case object Default extends AnnotationScope -case object AllRefs extends AnnotationScope +case object AllRefs extends AnnotationScope case object JustThisRef extends AnnotationScope -case class AnnotationKey(val component: Data, scope: AnnotationScope) +object AnnotationKey { + def apply(component: SignalId): AnnotationKey = { + AnnotationKey(component, AllRefs) + } +} +case class AnnotationKey(val component: SignalId, scope: AnnotationScope) { + override def toString: String = { + scope match { + case JustThisRef => + s"${component.pathName}" + case AllRefs => + s"${component.parentModName}.${component.signalName}" + case _ => + s"${component.toString}_unknown_scope" + } + } +} + +class AnnotationMap extends scala.collection.mutable.HashMap[AnnotationKey, String] class MyDynamicContext { - val annotationMap = new scala.collection.mutable.HashMap[AnnotationKey, String] + val annotationMap = new AnnotationMap } object MyBuilder { private val myDynamicContextVar = new DynamicVariable[Option[MyDynamicContext]](None) def myDynamicContext: MyDynamicContext = - myDynamicContextVar.value getOrElse (new MyDynamicContext) + myDynamicContextVar.value getOrElse new MyDynamicContext + + def processAnnotations(annotationMap: AnnotationMap): Map[String, String] = { + val list = annotationMap.map { case (k,v) => + k match { + case (AnnotationKey(signal, JustThisRef)) => + f"Just this ref $k%60s -> $v%40s component $signal" + case (AnnotationKey(signal, AllRefs)) => + f"All refs $k%60s -> $v%40s component $signal" + case _ => + s"Unknown annotation key $k" + } + }.toList.sorted.mkString("\n") + println(s"Sorted list of annotations\n$list") + + annotationMap.map { case (k,v) => k.toString -> v}.toMap + } - def build[T <: Module](f: => T): Unit = { + def build[T <: Module](f: => T): Map[String, String] = { myDynamicContextVar.withValue(Some(new MyDynamicContext)) { Driver.emit(() => f) - val list = myDynamicContextVar.value.get.annotationMap.map { case (k,v) => - k match { - case (AnnotationKey(signal, JustThisRef)) => - f"Just this ref ${signal.pathName + signal.signalName}%60s -> $v%30s component $signal" - case (AnnotationKey(signal, AllRefs)) => - f"All refs ${signal.signalName}%60s -> $v%30s component $signal" - case _ => - s"Unknown annotation key $k" - } - }.toList.sorted - println(list.mkString("\n")) + processAnnotations(myDynamicContextVar.value.get.annotationMap) } } } object MyDriver extends BackendCompilationUtilities { - def doStuff[T <: Module](gen: () => T): Unit = MyBuilder.build(Module(gen())) + def doStuff[T <: Module](gen: () => T): Map[String, String] = MyBuilder.build(Module(gen())) } \ No newline at end of file -- cgit v1.2.3 From a177f40f1ff2482ba268a27e0af02b57713e781a Mon Sep 17 00:00:00 2001 From: chick Date: Fri, 19 Aug 2016 12:28:35 -0700 Subject: AnnotatingExample: Removed extraneous logic Renamed doStuff to buildAnnotatedCircuit Removed println's --- src/test/scala/chiselTests/AnnotatingExample.scala | 54 +++++++++------------- 1 file changed, 21 insertions(+), 33 deletions(-) diff --git a/src/test/scala/chiselTests/AnnotatingExample.scala b/src/test/scala/chiselTests/AnnotatingExample.scala index 073355fc..a252309d 100644 --- a/src/test/scala/chiselTests/AnnotatingExample.scala +++ b/src/test/scala/chiselTests/AnnotatingExample.scala @@ -27,9 +27,11 @@ class SomeSubMod(param1: Int, param2: Int) extends Module { val in = UInt(INPUT, 16) val out = SInt(OUTPUT, 32) } - MyBuilder.myDynamicContext.annotationMap(AnnotationKey(this, JustThisRef)) = s"SomeSubMod($param1, $param2)" - MyBuilder.myDynamicContext.annotationMap(AnnotationKey(io.in, AllRefs)) = "sub mod io.in" - MyBuilder.myDynamicContext.annotationMap(AnnotationKey(io.out, JustThisRef)) = "sub mod io.out" + val annotate = MyBuilder.myDynamicContext.annotationMap + + annotate(AnnotationKey(this, JustThisRef)) = s"SomeSubMod($param1, $param2)" + annotate(AnnotationKey(io.in, AllRefs)) = "sub mod io.in" + annotate(AnnotationKey(io.out, JustThisRef)) = "sub mod io.out" } class AnnotatingExample extends Module { @@ -56,40 +58,35 @@ class AnnotatingExample extends Module { annotate(AnnotationKey(subModule2, AllRefs)) = s"SomeSubMod was used" annotate(AnnotationKey(x, JustThisRef)) = "I am register X" + annotate(AnnotationKey(y, AllRefs)) = "I am register Y" annotate(AnnotationKey(io.a, JustThisRef)) = "I am io.a" annotate(AnnotationKey(io.bun.nested_1, AllRefs)) = "I am io.bun.nested_1" annotate(AnnotationKey(io.bun.nested_2, JustThisRef)) = "I am io.bun.nested_2" - - when (x > y) { x := x -% y } - .otherwise { y := y -% x } - when (io.e) { x := io.a; y := io.b } - io.z := x - io.v := y === UInt(0) } -class AnnotatingExampleTester(a: Int, b: Int, z: Int) extends BasicTester { +class AnnotatingExampleTester extends BasicTester { val dut = Module(new AnnotatingExample) - val first = Reg(init=Bool(true)) - dut.io.a := UInt(a) - dut.io.b := UInt(b) - dut.io.e := first - when(first) { first := Bool(false) } - when(!first && dut.io.v) { - assert(dut.io.z === UInt(z)) - stop() - } + + stop() } class AnnotatingExampleSpec extends FlatSpec with Matchers { behavior of "Annotating components of a circuit" - val annotationMap = MyDriver.doStuff { () => new AnnotatingExampleTester(1, 2, 3) } it should "contain the following relative keys" in { + val annotationMap = MyDriver.buildAnnotatedCircuit { () => new AnnotatingExampleTester } + annotationMap.contains("SomeSubMod.io.in") should be(true) + annotationMap.contains("AnnotatingExample.y") should be(true) + annotationMap("SomeSubMod.io.in") should be("sub mod io.in") } it should "contain the following absolute keys" in { + val annotationMap = MyDriver.buildAnnotatedCircuit { () => new AnnotatingExampleTester } + annotationMap.contains("AnnotatingExampleTester.dut.subModule2.io.out") should be (true) + annotationMap.contains("AnnotatingExampleTester.dut.x") should be (true) + annotationMap("AnnotatingExampleTester.dut.subModule2.io.out") should be ("sub mod io.out") } } @@ -129,18 +126,6 @@ object MyBuilder { myDynamicContextVar.value getOrElse new MyDynamicContext def processAnnotations(annotationMap: AnnotationMap): Map[String, String] = { - val list = annotationMap.map { case (k,v) => - k match { - case (AnnotationKey(signal, JustThisRef)) => - f"Just this ref $k%60s -> $v%40s component $signal" - case (AnnotationKey(signal, AllRefs)) => - f"All refs $k%60s -> $v%40s component $signal" - case _ => - s"Unknown annotation key $k" - } - }.toList.sorted.mkString("\n") - println(s"Sorted list of annotations\n$list") - annotationMap.map { case (k,v) => k.toString -> v}.toMap } @@ -153,5 +138,8 @@ object MyBuilder { } object MyDriver extends BackendCompilationUtilities { - def doStuff[T <: Module](gen: () => T): Map[String, String] = MyBuilder.build(Module(gen())) + /** + * illustrates a chisel3 style driver that, annotations can only processed within this structure + */ + def buildAnnotatedCircuit[T <: Module](gen: () => T): Map[String, String] = MyBuilder.build(Module(gen())) } \ No newline at end of file -- cgit v1.2.3 From f5e9a6c6e55ba19a7c1f2353d0207189062db1c9 Mon Sep 17 00:00:00 2001 From: chick Date: Wed, 24 Aug 2016 17:09:41 -0700 Subject: Per Chisel meeting. signalName -> instanceName SignalId -> InstanceId Based on Stephen's comments on PR --- chiselFrontend/src/main/scala/chisel3/core/Module.scala | 2 +- .../src/main/scala/chisel3/internal/Builder.scala | 16 ++++++++-------- src/test/scala/chiselTests/AnnotatingExample.scala | 8 ++++---- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Module.scala b/chiselFrontend/src/main/scala/chisel3/core/Module.scala index eb48a14d..2426ae78 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Module.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Module.scala @@ -78,7 +78,7 @@ extends HasId { /** Signal name (for simulation). */ - override def signalName = + override def instanceName = if (_parent == None) name else _component match { case None => getRef.name case Some(c) => getRef fullName c diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index bf78c410..2dec78bb 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -59,14 +59,14 @@ private[chisel3] class IdGen { * currently, the node's name, the full path name, and references to its parent Module and component. * These are only valid once the design has been elaborated, and should not be used during its construction. */ -trait SignalId { - def signalName: String +trait InstanceId { + def instanceName: String def pathName: String def parentPathName: String def parentModName: String } -private[chisel3] trait HasId extends SignalId { +private[chisel3] trait HasId extends InstanceId { private[chisel3] def _onModuleClose {} // scalastyle:ignore method.name private[chisel3] val _parent = Builder.dynamicContext.currentModule _parent.foreach(_.addId(this)) @@ -108,7 +108,7 @@ private[chisel3] trait HasId extends SignalId { private[chisel3] def getRef: Arg = _ref.get // Implementation of public methods. - def signalName = _parent match { + def instanceName = _parent match { case Some(p) => p._component match { case Some(c) => getRef fullName c case None => throwException("signalName/pathName should be called after circuit elaboration") @@ -116,16 +116,16 @@ private[chisel3] trait HasId extends SignalId { case None => throwException("this cannot happen") } def pathName = _parent match { - case None => signalName - case Some(p) => s"${p.pathName}.$signalName" + case None => instanceName + case Some(p) => s"${p.pathName}.$instanceName" } def parentPathName = _parent match { case Some(p) => p.pathName - case None => throwException(s"$signalName doesn't have a parent") + case None => throwException(s"$instanceName doesn't have a parent") } def parentModName = _parent match { case Some(p) => p.modName - case None => throwException(s"$signalName doesn't have a parent") + case None => throwException(s"$instanceName doesn't have a parent") } } diff --git a/src/test/scala/chiselTests/AnnotatingExample.scala b/src/test/scala/chiselTests/AnnotatingExample.scala index a252309d..c84edf86 100644 --- a/src/test/scala/chiselTests/AnnotatingExample.scala +++ b/src/test/scala/chiselTests/AnnotatingExample.scala @@ -4,7 +4,7 @@ package chiselTests import chisel3._ import chisel3.core.Module -import chisel3.internal.SignalId +import chisel3.internal.InstanceId import chisel3.testers.BasicTester import org.scalatest._ @@ -96,17 +96,17 @@ case object AllRefs extends AnnotationScope case object JustThisRef extends AnnotationScope object AnnotationKey { - def apply(component: SignalId): AnnotationKey = { + def apply(component: InstanceId): AnnotationKey = { AnnotationKey(component, AllRefs) } } -case class AnnotationKey(val component: SignalId, scope: AnnotationScope) { +case class AnnotationKey(val component: InstanceId, scope: AnnotationScope) { override def toString: String = { scope match { case JustThisRef => s"${component.pathName}" case AllRefs => - s"${component.parentModName}.${component.signalName}" + s"${component.parentModName}.${component.instanceName}" case _ => s"${component.toString}_unknown_scope" } -- cgit v1.2.3 From 5ca2820216a4c4b8c28438967d6e4680412f6580 Mon Sep 17 00:00:00 2001 From: Donggyu Kim Date: Thu, 25 Aug 2016 14:05:31 -0700 Subject: fix a bug in setModName --- src/main/scala/chisel3/internal/firrtl/Emitter.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/chisel3/internal/firrtl/Emitter.scala b/src/main/scala/chisel3/internal/firrtl/Emitter.scala index 79f86ae9..8b94c68f 100644 --- a/src/main/scala/chisel3/internal/firrtl/Emitter.scala +++ b/src/main/scala/chisel3/internal/firrtl/Emitter.scala @@ -87,7 +87,7 @@ private class Emitter(circuit: Circuit) { "" case None => defnMap((m.id.desiredName, defn)) = m - m.id setModName m.id.name + m.id setModName m.name moduleDecl(m) + defn } } -- cgit v1.2.3