aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Waterman2019-01-23 13:27:19 -0800
committerAdam Izraelevitz2019-01-23 13:27:19 -0800
commit1738c1ef0ac95fae25d52586b3b0348de80de2ff (patch)
treee28d770a8ad05b7f9635365248ee6a44a766714e /src
parentdf3c3fb5eedd3e2ac95b9f210268e4e515d6344c (diff)
Improve Shl codegen; eliminate Shlw WIR node (#994)
* Improve Shl codegen; eliminate Shlw WIR node If we emit shl(x, k) as {x, k'h0} instead of (x << k), then there's no need for Verilog-specific padding in the PadWidths pass. Avoiding the redundant padding improves compiler/simulator performance and renders Shlw unnecessary. * [skip formal checks] Add test
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/firrtl/Emitter.scala3
-rw-r--r--src/main/scala/firrtl/WIR.scala2
-rw-r--r--src/main/scala/firrtl/passes/PadWidths.scala3
-rw-r--r--src/test/scala/firrtlTests/UnitTests.scala12
4 files changed, 13 insertions, 7 deletions
diff --git a/src/main/scala/firrtl/Emitter.scala b/src/main/scala/firrtl/Emitter.scala
index 8547f9b9..67bd1583 100644
--- a/src/main/scala/firrtl/Emitter.scala
+++ b/src/main/scala/firrtl/Emitter.scala
@@ -303,8 +303,7 @@ class VerilogEmitter extends SeqTransform with Emitter {
case (_: SIntType) => Seq(cast(a0)," >>> ", a1)
case (_) => Seq(cast(a0), " >> ", a1)
}
- case Shlw => Seq(cast(a0), " << ", c0)
- case Shl => Seq(cast(a0), " << ", c0)
+ case Shl => if (c0 > 0) Seq("{", cast(a0), s", $c0'h0}") else Seq(cast(a0))
case Shr if c0 >= bitWidth(a0.tpe) =>
error("Verilog emitter does not support SHIFT_RIGHT >= arg width")
case Shr => Seq(a0,"[", bitWidth(a0.tpe) - 1, ":", c0, "]")
diff --git a/src/main/scala/firrtl/WIR.scala b/src/main/scala/firrtl/WIR.scala
index a5d2571d..0c5c250f 100644
--- a/src/main/scala/firrtl/WIR.scala
+++ b/src/main/scala/firrtl/WIR.scala
@@ -152,8 +152,6 @@ case object Addw extends PrimOp { override def toString = "addw" }
case object Subw extends PrimOp { override def toString = "subw" }
// Resultant width is the same as input argument width
case object Dshlw extends PrimOp { override def toString = "dshlw" }
-// Resultant width is the same as input argument width
-case object Shlw extends PrimOp { override def toString = "shlw" }
object WrappedExpression {
def apply(e: Expression) = new WrappedExpression(e)
diff --git a/src/main/scala/firrtl/passes/PadWidths.scala b/src/main/scala/firrtl/passes/PadWidths.scala
index c9aa1539..cbd8250a 100644
--- a/src/main/scala/firrtl/passes/PadWidths.scala
+++ b/src/main/scala/firrtl/passes/PadWidths.scala
@@ -44,9 +44,6 @@ object PadWidths extends Pass {
case Dshl =>
// special case as args aren't all same width
ex copy (op = Dshlw, args = Seq(fixup(width(ex.tpe))(ex.args.head), ex.args(1)))
- case Shl =>
- // special case as arg should be same width as result
- ex copy (op = Shlw, args = Seq(fixup(width(ex.tpe))(ex.args.head)))
case _ => ex
}
case ex => ex
diff --git a/src/test/scala/firrtlTests/UnitTests.scala b/src/test/scala/firrtlTests/UnitTests.scala
index 2cf9c001..b3af920c 100644
--- a/src/test/scala/firrtlTests/UnitTests.scala
+++ b/src/test/scala/firrtlTests/UnitTests.scala
@@ -437,4 +437,16 @@ class UnitTests extends FirrtlFlatSpec {
result should containTree { case Connect(_, `out`, mgen) => true }
}
+
+ "Shl" should "be emitted in Verilog as concat" in {
+ val input =
+ """circuit Unit :
+ | module Unit :
+ | input in : UInt<4>
+ | output out : UInt<8>
+ | out <= shl(in, 4)
+ |""".stripMargin
+ val res = (new VerilogCompiler).compileAndEmit(CircuitState(parse(input), ChirrtlForm))
+ res should containLine ("assign out = {in, 4'h0};")
+ }
}