diff options
| author | Jack Koenig | 2018-06-06 21:13:24 -0700 |
|---|---|---|
| committer | GitHub | 2018-06-06 21:13:24 -0700 |
| commit | 7c49fa1726ab1860fbb3616156467807de2d7e3c (patch) | |
| tree | f3fd0f149f22811acd6048ad4bb58722351873e3 | |
| parent | c9d40a022efc2d4380186912e61c2c91d07e8958 (diff) | |
ConstProp attached wires if there is also a port (#818)
This enables the pattern of attaching "through" a wire to give better
Verilog that also works in Verilator
Use WrappedExpression when combining attaches in ExpandWhens
to ensure no duplication of references in resulting, combined attaches
| -rw-r--r-- | src/main/scala/firrtl/passes/ExpandWhens.scala | 9 | ||||
| -rw-r--r-- | src/main/scala/firrtl/transforms/ConstantPropagation.scala | 3 | ||||
| -rw-r--r-- | src/test/scala/firrtlTests/AttachSpec.scala | 32 |
3 files changed, 34 insertions, 10 deletions
diff --git a/src/main/scala/firrtl/passes/ExpandWhens.scala b/src/main/scala/firrtl/passes/ExpandWhens.scala index 4abae636..3665590f 100644 --- a/src/main/scala/firrtl/passes/ExpandWhens.scala +++ b/src/main/scala/firrtl/passes/ExpandWhens.scala @@ -235,11 +235,12 @@ object ExpandWhens extends Pass { */ private def combineAttaches(attaches: Seq[Attach]): Seq[Attach] = { // Helper type to add an ordering index to attached Expressions - case class AttachAcc(exprs: Seq[Expression], idx: Int) + case class AttachAcc(exprs: Seq[WrappedExpression], idx: Int) // Map from every attached expression to its corresponding AttachAcc // (many keys will point to same value) val attachMap = mutable.HashMap.empty[WrappedExpression, AttachAcc] - for (Attach(_, exprs) <- attaches) { + for (Attach(_, es) <- attaches) { + val exprs = es.map(we(_)) val acc = exprs.map(attachMap.get(_)).flatten match { case Seq() => // None of these expressions is present in the attachMap AttachAcc(exprs, attachMap.size) @@ -247,9 +248,9 @@ object ExpandWhens extends Pass { val sorted = accs sortBy (_.idx) AttachAcc((sorted.map(_.exprs) :+ exprs).flatten.distinct, sorted.head.idx) } - attachMap ++= acc.exprs.map(e => (we(e) -> acc)) + attachMap ++= acc.exprs.map(_ -> acc) } - attachMap.values.toList.distinct.map(acc => Attach(NoInfo, acc.exprs)) + attachMap.values.toList.distinct.map(acc => Attach(NoInfo, acc.exprs.map(_.e1))) } // Searches nested scopes of defaults for lvalue // defaults uses mutable Map because we are searching LinkedHashMaps and conversion to immutable is VERY slow diff --git a/src/main/scala/firrtl/transforms/ConstantPropagation.scala b/src/main/scala/firrtl/transforms/ConstantPropagation.scala index 5e9a7850..4a4f41d1 100644 --- a/src/main/scala/firrtl/transforms/ConstantPropagation.scala +++ b/src/main/scala/firrtl/transforms/ConstantPropagation.scala @@ -396,6 +396,9 @@ class ConstantPropagation extends Transform { // Propagate connections to references case Connect(info, lhs, rref @ WRef(rname, _, NodeKind, _)) if !dontTouches.contains(rname) => Connect(info, lhs, nodeMap(rname)) + // If an Attach has at least 1 port, any wires are redundant and can be removed + case Attach(info, exprs) if exprs.exists(kind(_) == PortKind) => + Attach(info, exprs.filterNot(kind(_) == WireKind)) case other => other } } diff --git a/src/test/scala/firrtlTests/AttachSpec.scala b/src/test/scala/firrtlTests/AttachSpec.scala index c9c609df..9bf5fefd 100644 --- a/src/test/scala/firrtlTests/AttachSpec.scala +++ b/src/test/scala/firrtlTests/AttachSpec.scala @@ -107,6 +107,31 @@ class InoutVerilogSpec extends FirrtlFlatSpec { executeTest(input, check, compiler, Seq(dontTouch("Attaching.x"))) } + it should "attach port to submodule port through a wire" in { + val compiler = new VerilogCompiler + val input = + """circuit Attaching : + | module Attaching : + | input an: Analog<3> + | wire x: Analog + | inst a of A + | attach (x, a.an) + | attach (x, an) + | module A: + | input an: Analog<3> """.stripMargin + val check = + """module Attaching( + | inout [2:0] an + |); + | A a ( + | .an(an) + | ); + |endmodule + |""".stripMargin.split("\n") map normalized + executeTest(input, check, compiler, Seq(dontTouch("Attaching.x"))) + } + + it should "attach multiple sources" in { val compiler = new VerilogCompiler val input = @@ -121,18 +146,13 @@ class InoutVerilogSpec extends FirrtlFlatSpec { | inout [2:0] a1, | inout [2:0] a2 |); - | wire [2:0] x; | `ifdef SYNTHESIS - | assign x = a1; - | assign a1 = x; - | assign x = a2; - | assign a2 = x; | assign a1 = a2; | assign a2 = a1; | `elsif verilator | `error "Verilator does not support alias and thus cannot arbirarily connect bidirectional wires and ports" | `else - | alias x = a1 = a2; + | alias a1 = a2; | `endif |endmodule |""".stripMargin.split("\n") map normalized |
