aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdam Izraelevitz2016-10-31 17:05:08 -0700
committerGitHub2016-10-31 17:05:08 -0700
commita399dc8afe1de04266bbe08108d067ca84089511 (patch)
tree6ac3cb30ff24b88b3aca62b7ed66e02415c91176 /src
parent77f55128e55c0f5511c609d2cb4f7fa2cd0aa427 (diff)
Fixed Verilog emission of andr, orr, and xorr (#357)
Fixed Verilog emission reduce ops with efficient implementation
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/firrtl/Emitter.scala9
-rw-r--r--src/test/scala/firrtlTests/VerilogEmitterTests.scala103
2 files changed, 106 insertions, 6 deletions
diff --git a/src/main/scala/firrtl/Emitter.scala b/src/main/scala/firrtl/Emitter.scala
index 5a4420c6..7b198149 100644
--- a/src/main/scala/firrtl/Emitter.scala
+++ b/src/main/scala/firrtl/Emitter.scala
@@ -223,12 +223,9 @@ class VerilogEmitter extends Emitter {
case And => Seq(cast_as(a0), " & ", cast_as(a1))
case Or => Seq(cast_as(a0), " | ", cast_as(a1))
case Xor => Seq(cast_as(a0), " ^ ", cast_as(a1))
- case Andr => (0 until bitWidth(doprim.tpe).toInt) map (
- Seq(cast(a0), "[", _, "]")) reduce (_ + " & " + _)
- case Orr => (0 until bitWidth(doprim.tpe).toInt) map (
- Seq(cast(a0), "[", _, "]")) reduce (_ + " | " + _)
- case Xorr => (0 until bitWidth(doprim.tpe).toInt) map (
- Seq(cast(a0), "[", _, "]")) reduce (_ + " ^ " + _)
+ case Andr => Seq("&", cast(a0))
+ case Orr => Seq("|", cast(a0))
+ case Xorr => Seq("^", cast(a0))
case Cat => Seq("{", cast(a0), ",", cast(a1), "}")
// If selecting zeroth bit and single-bit wire, just emit the wire
case Bits if c0 == 0 && c1 == 0 && bitWidth(a0.tpe) == BigInt(1) => Seq(a0)
diff --git a/src/test/scala/firrtlTests/VerilogEmitterTests.scala b/src/test/scala/firrtlTests/VerilogEmitterTests.scala
new file mode 100644
index 00000000..1f6142bc
--- /dev/null
+++ b/src/test/scala/firrtlTests/VerilogEmitterTests.scala
@@ -0,0 +1,103 @@
+/*
+Copyright (c) 2014 - 2016 The Regents of the University of
+California (Regents). All Rights Reserved. Redistribution and use in
+source and binary forms, with or without modification, are permitted
+provided that the following conditions are met:
+ * Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the following
+ two paragraphs of disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ two paragraphs of disclaimer in the documentation and/or other materials
+ provided with the distribution.
+ * Neither the name of the Regents nor the names of its contributors
+ may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
+ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
+REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF
+ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION
+TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+MODIFICATIONS.
+*/
+
+package firrtlTests
+
+import java.io._
+import org.scalatest._
+import org.scalatest.prop._
+import firrtl._
+import firrtl.Annotations._
+import firrtl.ir.Circuit
+import firrtl.passes._
+import firrtl.Parser.IgnoreInfo
+
+class DoPrimVerilog extends FirrtlFlatSpec {
+ def parse (input:String) = Parser.parse(input.split("\n").toIterator, IgnoreInfo)
+ private def executeTest(input: String, expected: Seq[String], compiler: Compiler) = {
+ val writer = new StringWriter()
+ compiler.compile(parse(input), new AnnotationMap(Seq.empty), writer)
+ val lines = writer.toString().split("\n") map normalized
+ expected foreach { e =>
+ lines should contain(e)
+ }
+ }
+ "Xorr" should "emit correctly" in {
+ val compiler = new VerilogCompiler
+ val input =
+ """circuit Xorr :
+ | module Xorr :
+ | input a: UInt<4>
+ | output b: UInt<1>
+ | b <= xorr(a)""".stripMargin
+ val check =
+ """module Xorr(
+ | input [3:0] a,
+ | output b
+ |);
+ | assign b = ^a;
+ |endmodule
+ |""".stripMargin.split("\n") map normalized
+ executeTest(input, check, compiler)
+ }
+ "Andr" should "emit correctly" in {
+ val compiler = new VerilogCompiler
+ val input =
+ """circuit Andr :
+ | module Andr :
+ | input a: UInt<4>
+ | output b: UInt<1>
+ | b <= andr(a)""".stripMargin
+ val check =
+ """module Andr(
+ | input [3:0] a,
+ | output b
+ |);
+ | assign b = &a;
+ |endmodule
+ |""".stripMargin.split("\n") map normalized
+ executeTest(input, check, compiler)
+ }
+ "Orr" should "emit correctly" in {
+ val compiler = new VerilogCompiler
+ val input =
+ """circuit Orr :
+ | module Orr :
+ | input a: UInt<4>
+ | output b: UInt<1>
+ | b <= orr(a)""".stripMargin
+ val check =
+ """module Orr(
+ | input [3:0] a,
+ | output b
+ |);
+ | assign b = |a;
+ |endmodule
+ |""".stripMargin.split("\n") map normalized
+ executeTest(input, check, compiler)
+ }
+}