From 8bc25bbc0ff998565afd153a44bf8f11316ba0f0 Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Wed, 2 Jan 2019 17:37:18 -0800 Subject: Make GroupComponents run ResolveKinds This fixes an issue where expressions created by GroupComponents would be improperly lowered because they were not marked as references to instance ports. --- .../scala/firrtl/transforms/GroupComponents.scala | 4 +-- .../transforms/GroupComponentsSpec.scala | 36 ++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/main/scala/firrtl/transforms/GroupComponents.scala b/src/main/scala/firrtl/transforms/GroupComponents.scala index 55828e0a..805b534e 100644 --- a/src/main/scala/firrtl/transforms/GroupComponents.scala +++ b/src/main/scala/firrtl/transforms/GroupComponents.scala @@ -4,7 +4,7 @@ import firrtl._ import firrtl.Mappers._ import firrtl.ir._ import firrtl.annotations.{Annotation, ComponentName} -import firrtl.passes.{InferTypes, LowerTypes, MemPortUtils} +import firrtl.passes.{InferTypes, LowerTypes, MemPortUtils, ResolveKinds} import firrtl.Utils.kind import firrtl.graph.{DiGraph, MutableDiGraph} @@ -62,7 +62,7 @@ class GroupComponents extends firrtl.Transform { case other => Seq(other) } val cs = state.copy(circuit = state.circuit.copy(modules = newModules)) - val csx = InferTypes.execute(cs) + val csx = ResolveKinds.execute(InferTypes.execute(cs)) csx } diff --git a/src/test/scala/firrtlTests/transforms/GroupComponentsSpec.scala b/src/test/scala/firrtlTests/transforms/GroupComponentsSpec.scala index 3a32ec71..f51d44ae 100644 --- a/src/test/scala/firrtlTests/transforms/GroupComponentsSpec.scala +++ b/src/test/scala/firrtlTests/transforms/GroupComponentsSpec.scala @@ -3,6 +3,10 @@ package transforms import firrtl.annotations.{CircuitName, ComponentName, ModuleName} import firrtl.transforms.{GroupAnnotation, GroupComponents} +import firrtl._ +import firrtl.ir._ + +import FirrtlCheckers._ class GroupComponentsSpec extends LowTransformSpec { def transform = new GroupComponents() @@ -288,3 +292,35 @@ class GroupComponentsSpec extends LowTransformSpec { execute(input, check, groups) } } + +class GroupComponentsIntegrationSpec extends FirrtlFlatSpec { + def topComp(name: String): ComponentName = ComponentName(name, ModuleName("Top", CircuitName("Top"))) + "Grouping" should "properly set kinds" in { + val input = + """circuit Top : + | module Top : + | input clk: Clock + | input data: UInt<16> + | output out: UInt<16> + | reg r: UInt<16>, clk + | r <= data + | out <= r + """.stripMargin + val groups = Seq( + GroupAnnotation(Seq(topComp("r")), "MyModule", "inst", Some("_OUT"), Some("_IN")) + ) + val result = (new VerilogCompiler).compileAndEmit( + CircuitState(parse(input), ChirrtlForm, groups), + Seq(new GroupComponents) + ) + result should containTree { + case Connect(_, WSubField(WRef("inst",_, InstanceKind,_), "data_IN", _,_), WRef("data",_,_,_)) => true + } + result should containTree { + case Connect(_, WSubField(WRef("inst",_, InstanceKind,_), "clk_IN", _,_), WRef("clk",_,_,_)) => true + } + result should containTree { + case Connect(_, WRef("out",_,_,_), WSubField(WRef("inst",_, InstanceKind,_), "r_OUT", _,_)) => true + } + } +} -- cgit v1.2.3 From 1931649a050619a711c066f669d93d436bd03296 Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Fri, 4 Jan 2019 13:39:04 -0800 Subject: Fix GroupComponents to work with unused components Previously, components that did not affect the output would cause exceptions because they were missing from the label2group Map. This commit treats them as "reachable" by the ports so they are included in the default "ungrouped" group. --- .../scala/firrtl/transforms/GroupComponents.scala | 9 +++++- .../transforms/GroupComponentsSpec.scala | 37 ++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/main/scala/firrtl/transforms/GroupComponents.scala b/src/main/scala/firrtl/transforms/GroupComponents.scala index 805b534e..8c36bb6d 100644 --- a/src/main/scala/firrtl/transforms/GroupComponents.scala +++ b/src/main/scala/firrtl/transforms/GroupComponents.scala @@ -119,6 +119,11 @@ class GroupComponents extends firrtl.Transform { } } + // Unused nodes are not reachable from any group nor the root--add them to root group + for ((v, _) <- deps.getEdgeMap) { + reachableNodes.getOrElseUpdate(v, mutable.Set("")) + } + // Add nodes who are reached by a single group, to that group reachableNodes.foreach { case (node, membership) => if(membership.size == 1) { @@ -307,7 +312,9 @@ class GroupComponents extends firrtl.Transform { } def onStmt(stmt: Statement): Unit = stmt match { case w: WDefInstance => - case h: IsDeclaration => h map onExpr(WRef(h.name)) + case h: IsDeclaration => + bidirGraph.addVertex(h.name) + h map onExpr(WRef(h.name)) case Attach(_, exprs) => // Add edge between each expression exprs.tail map onExpr(getWRef(exprs.head)) case Connect(_, loc, expr) => diff --git a/src/test/scala/firrtlTests/transforms/GroupComponentsSpec.scala b/src/test/scala/firrtlTests/transforms/GroupComponentsSpec.scala index f51d44ae..c54e02e3 100644 --- a/src/test/scala/firrtlTests/transforms/GroupComponentsSpec.scala +++ b/src/test/scala/firrtlTests/transforms/GroupComponentsSpec.scala @@ -46,6 +46,43 @@ class GroupComponentsSpec extends LowTransformSpec { """.stripMargin execute(input, check, groups) } + "Grouping" should "work even when there are unused nodes" in { + val input = + s"""circuit $top : + | module $top : + | input in: UInt<16> + | output out: UInt<16> + | node n = UInt<16>("h0") + | wire w : UInt<16> + | wire a : UInt<16> + | wire b : UInt<16> + | a <= UInt<16>("h0") + | b <= a + | w <= in + | out <= w + """.stripMargin + val groups = Seq( + GroupAnnotation(Seq(topComp("w")), "Child", "inst", Some("_OUT"), Some("_IN")) + ) + val check = + s"""circuit Top : + | module $top : + | input in: UInt<16> + | output out: UInt<16> + | inst inst of Child + | node n = UInt<16>("h0") + | inst.in_IN <= in + | node a = UInt<16>("h0") + | node b = a + | out <= inst.w_OUT + | module Child : + | input in_IN : UInt<16> + | output w_OUT : UInt<16> + | node w = in_IN + | w_OUT <= w + """.stripMargin + execute(input, check, groups) + } "The two sets of instances" should "be grouped" in { val input = -- cgit v1.2.3