aboutsummaryrefslogtreecommitdiff
path: root/src/test/scala/firrtlTests
diff options
context:
space:
mode:
authorDavid Biancolin2019-01-21 18:50:51 -0500
committerGitHub2019-01-21 18:50:51 -0500
commit10586d6a141859b843057ec9979011e26ad207f1 (patch)
treeff23c30013159cdd1879b1e5c3dd5baca5bf4867 /src/test/scala/firrtlTests
parent73ae6257fce586ac145b6ab348ce1b47634e7a46 (diff)
parentdf3a34f01d227ff9ad0e63a41ff10001ac01c01d (diff)
Merge branch 'master' into top-wiring-aggregates
Diffstat (limited to 'src/test/scala/firrtlTests')
-rw-r--r--src/test/scala/firrtlTests/CheckCombLoopsSpec.scala86
-rw-r--r--src/test/scala/firrtlTests/ChirrtlMemSpec.scala17
-rw-r--r--src/test/scala/firrtlTests/ConstantPropagationTests.scala89
-rw-r--r--src/test/scala/firrtlTests/UniquifySpec.scala28
-rw-r--r--src/test/scala/firrtlTests/transforms/GroupComponentsSpec.scala73
5 files changed, 293 insertions, 0 deletions
diff --git a/src/test/scala/firrtlTests/CheckCombLoopsSpec.scala b/src/test/scala/firrtlTests/CheckCombLoopsSpec.scala
index 8fc7dda9..98472f14 100644
--- a/src/test/scala/firrtlTests/CheckCombLoopsSpec.scala
+++ b/src/test/scala/firrtlTests/CheckCombLoopsSpec.scala
@@ -165,6 +165,92 @@ class CheckCombLoopsSpec extends SimpleTransformSpec {
}
}
+ "Combinational loop through an annotated ExtModule" should "throw an exception" in {
+ val input = """circuit hasloops :
+ | extmodule blackbox :
+ | input in : UInt<1>
+ | output out : UInt<1>
+ | module hasloops :
+ | input clk : Clock
+ | input a : UInt<1>
+ | input b : UInt<1>
+ | output c : UInt<1>
+ | output d : UInt<1>
+ | wire y : UInt<1>
+ | wire z : UInt<1>
+ | c <= b
+ | inst inner of blackbox
+ | inner.in <= y
+ | z <= inner.out
+ | y <= z
+ | d <= z
+ |""".stripMargin
+
+ val mt = ModuleTarget("hasloops", "blackbox")
+ val annos = AnnotationSeq(Seq(ExtModulePathAnnotation(mt.ref("in"), mt.ref("out"))))
+ val writer = new java.io.StringWriter
+ intercept[CheckCombLoops.CombLoopException] {
+ compile(CircuitState(parse(input), ChirrtlForm, annos), writer)
+ }
+ }
+
+ "Loop-free circuit with ExtModulePathAnnotations" should "not throw an exception" in {
+ val input = """circuit hasnoloops :
+ | extmodule blackbox :
+ | input in1 : UInt<1>
+ | input in2 : UInt<1>
+ | output out1 : UInt<1>
+ | output out2 : UInt<1>
+ | module hasnoloops :
+ | input clk : Clock
+ | input a : UInt<1>
+ | output b : UInt<1>
+ | wire x : UInt<1>
+ | inst inner of blackbox
+ | inner.in1 <= a
+ | x <= inner.out1
+ | inner.in2 <= x
+ | b <= inner.out2
+ |""".stripMargin
+
+ val mt = ModuleTarget("hasnoloops", "blackbox")
+ val annos = AnnotationSeq(Seq(
+ ExtModulePathAnnotation(mt.ref("in1"), mt.ref("out1")),
+ ExtModulePathAnnotation(mt.ref("in2"), mt.ref("out2"))))
+ val writer = new java.io.StringWriter
+ compile(CircuitState(parse(input), ChirrtlForm, annos), writer)
+ }
+
+ "Combinational loop through an output RHS reference" should "throw an exception" in {
+ val input = """circuit hasloops :
+ | module thru :
+ | input in : UInt<1>
+ | output tmp : UInt<1>
+ | output out : UInt<1>
+ | tmp <= in
+ | out <= tmp
+ | module hasloops :
+ | input clk : Clock
+ | input a : UInt<1>
+ | input b : UInt<1>
+ | output c : UInt<1>
+ | output d : UInt<1>
+ | wire y : UInt<1>
+ | wire z : UInt<1>
+ | c <= b
+ | inst inner of thru
+ | inner.in <= y
+ | z <= inner.out
+ | y <= z
+ | d <= z
+ |""".stripMargin
+
+ val writer = new java.io.StringWriter
+ intercept[CheckCombLoops.CombLoopException] {
+ compile(CircuitState(parse(input), ChirrtlForm), writer)
+ }
+ }
+
"Multiple simple loops in one SCC" should "throw an exception" in {
val input = """circuit hasloops :
| module hasloops :
diff --git a/src/test/scala/firrtlTests/ChirrtlMemSpec.scala b/src/test/scala/firrtlTests/ChirrtlMemSpec.scala
index 74d39286..a4473fe7 100644
--- a/src/test/scala/firrtlTests/ChirrtlMemSpec.scala
+++ b/src/test/scala/firrtlTests/ChirrtlMemSpec.scala
@@ -108,6 +108,23 @@ circuit foo :
parse(res.getEmittedCircuit.value)
}
+ "An mport that refers to an undefined memory" should "have a helpful error message" in {
+ val input =
+ """circuit testTestModule :
+ | module testTestModule :
+ | input clock : Clock
+ | input reset : UInt<1>
+ | output io : {flip in : UInt<10>, out : UInt<10>}
+ |
+ | node _T_10 = bits(io.in, 1, 0)
+ | read mport _T_11 = m[_T_10], clock
+ | io.out <= _T_11""".stripMargin
+
+ intercept[PassException]{
+ (new LowFirrtlCompiler).compile(CircuitState(parse(input), ChirrtlForm), Seq()).circuit
+ }.getMessage should startWith ("Undefined memory m referenced by mport _T_11")
+ }
+
ignore should "Memories should not have validif on port clocks when declared in a when" in {
val input =
""";buildInfoPackage: chisel3, version: 3.0-SNAPSHOT, scalaVersion: 2.11.11, sbtVersion: 0.13.16, builtAtString: 2017-10-06 20:55:20.367, builtAtMillis: 1507323320367
diff --git a/src/test/scala/firrtlTests/ConstantPropagationTests.scala b/src/test/scala/firrtlTests/ConstantPropagationTests.scala
index 603ddc25..8a69fcaa 100644
--- a/src/test/scala/firrtlTests/ConstantPropagationTests.scala
+++ b/src/test/scala/firrtlTests/ConstantPropagationTests.scala
@@ -734,6 +734,24 @@ class ConstantPropagationSingleModule extends ConstantPropagationSpec {
""".stripMargin
(parse(exec(input))) should be(parse(check))
}
+
+ // Optimizing this mux gives: z <= pad(UInt<2>(0), 4)
+ // Thus this checks that we then optimize that pad
+ "ConstProp" should "optimize nested Expressions" in {
+ val input =
+ """circuit Top :
+ | module Top :
+ | output z : UInt<4>
+ | z <= mux(UInt(1), UInt<2>(0), UInt<4>(0))
+ """.stripMargin
+ val check =
+ """circuit Top :
+ | module Top :
+ | output z : UInt<4>
+ | z <= UInt<4>("h0")
+ """.stripMargin
+ (parse(exec(input))) should be(parse(check))
+ }
}
// More sophisticated tests of the full compiler
@@ -1104,6 +1122,77 @@ class ConstantPropagationIntegrationSpec extends LowTransformSpec {
| z <= _T_61""".stripMargin
execute(input, check, Seq.empty)
}
+
+ behavior of "ConstProp"
+
+ it should "optimize shl of constants" in {
+ val input =
+ """circuit Top :
+ | module Top :
+ | output z : UInt<7>
+ | z <= shl(UInt(5), 4)
+ """.stripMargin
+ val check =
+ """circuit Top :
+ | module Top :
+ | output z : UInt<7>
+ | z <= UInt<7>("h50")
+ """.stripMargin
+ execute(input, check, Seq.empty)
+ }
+
+ it should "optimize shr of constants" in {
+ val input =
+ """circuit Top :
+ | module Top :
+ | output z : UInt<1>
+ | z <= shr(UInt(5), 2)
+ """.stripMargin
+ val check =
+ """circuit Top :
+ | module Top :
+ | output z : UInt<1>
+ | z <= UInt<1>("h1")
+ """.stripMargin
+ execute(input, check, Seq.empty)
+ }
+
+ // Due to #866, we need dshl optimized away or it'll become a dshlw and error in parsing
+ // Include cat to verify width is correct
+ it should "optimize dshl of constant" in {
+ val input =
+ """circuit Top :
+ | module Top :
+ | output z : UInt<8>
+ | node n = dshl(UInt<1>(0), UInt<2>(0))
+ | z <= cat(UInt<4>("hf"), n)
+ """.stripMargin
+ val check =
+ """circuit Top :
+ | module Top :
+ | output z : UInt<8>
+ | z <= UInt<8>("hf0")
+ """.stripMargin
+ execute(input, check, Seq.empty)
+ }
+
+ // Include cat and constants to verify width is correct
+ it should "optimize dshr of constant" in {
+ val input =
+ """circuit Top :
+ | module Top :
+ | output z : UInt<8>
+ | node n = dshr(UInt<4>(0), UInt<2>(2))
+ | z <= cat(UInt<4>("hf"), n)
+ """.stripMargin
+ val check =
+ """circuit Top :
+ | module Top :
+ | output z : UInt<8>
+ | z <= UInt<8>("hf0")
+ """.stripMargin
+ execute(input, check, Seq.empty)
+ }
}
diff --git a/src/test/scala/firrtlTests/UniquifySpec.scala b/src/test/scala/firrtlTests/UniquifySpec.scala
index 43d1e733..561f0a84 100644
--- a/src/test/scala/firrtlTests/UniquifySpec.scala
+++ b/src/test/scala/firrtlTests/UniquifySpec.scala
@@ -12,6 +12,7 @@ import firrtl._
import firrtl.annotations._
import firrtl.annotations.TargetToken._
import firrtl.transforms.DontTouchAnnotation
+import firrtl.util.TestOptions
class UniquifySpec extends FirrtlFlatSpec {
@@ -283,4 +284,31 @@ class UniquifySpec extends FirrtlFlatSpec {
executeTest(input, expected)
}
+
+ it should "quickly rename deep bundles" in {
+ // We use a fixed time to determine if this test passed or failed.
+ // This test would pass under normal conditions, but would fail during coverage tests.
+ // Since executions times vary significantly under coverage testing, we check a global
+ // to see if timing measurements are accurate enough to enforce the timing checks.
+ val maxMs = 8000.0
+
+ def mkType(i: Int): String = {
+ if(i == 0) "UInt<8>" else s"{x: ${mkType(i - 1)}}"
+ }
+
+ val depth = 500
+
+ val input =
+ s"""circuit Test:
+ | module Test :
+ | input in: ${mkType(depth)}
+ | output out: ${mkType(depth)}
+ | out <= in
+ |""".stripMargin
+
+ val (renameMs, _) = Utils.time(compileToVerilog(input))
+
+ if (TestOptions.accurateTiming)
+ renameMs shouldBe < (maxMs)
+ }
}
diff --git a/src/test/scala/firrtlTests/transforms/GroupComponentsSpec.scala b/src/test/scala/firrtlTests/transforms/GroupComponentsSpec.scala
index 3a32ec71..c54e02e3 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()
@@ -42,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 =
@@ -288,3 +329,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
+ }
+ }
+}