aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorJack Koenig2019-12-26 13:27:39 -0800
committerJack Koenig2019-12-30 21:24:20 -0800
commit1f63318b849012ba5655ac26774db383cf57f37d (patch)
tree258b18b1d36c2ac853d933caa90df9d958604a97 /src/test
parent70088cd22d842fd757d39150062e81c32e427dde (diff)
Respect last connect semantics in InferResets
InferResets will now support last connect semantics (within the same scope) when determining the concrete reset type for components of type Reset. This only includes *unconditional* last connects; it remains illegal to drive a component of type Reset with different concrete types under differing when conditions. For example, the following is now legal: input a : UInt<1> input b : AsyncReset output z : Reset z <= a z <= b The second connect will when and z will be of type AsyncReset. The following remains illegal: input a : UInt<1> input b : AsyncReset input c : UInt<1> output z : Reset z <= a when c : z <= b This commit also ensures that components of type Reset with no drivers (or only invalidation) default to type UInt<1>. This fixes a bug where the transform would crash with such input.
Diffstat (limited to 'src/test')
-rw-r--r--src/test/scala/firrtlTests/InferResetsSpec.scala97
1 files changed, 78 insertions, 19 deletions
diff --git a/src/test/scala/firrtlTests/InferResetsSpec.scala b/src/test/scala/firrtlTests/InferResetsSpec.scala
index ac13033a..501dce20 100644
--- a/src/test/scala/firrtlTests/InferResetsSpec.scala
+++ b/src/test/scala/firrtlTests/InferResetsSpec.scala
@@ -4,7 +4,7 @@ package firrtlTests
import firrtl._
import firrtl.ir._
-import firrtl.passes.{CheckHighForm, CheckTypes}
+import firrtl.passes.{CheckHighForm, CheckTypes, CheckInitialization}
import firrtl.transforms.InferResets
import FirrtlCheckers._
@@ -37,7 +37,6 @@ class InferResetsSpec extends FirrtlFlatSpec {
| y <= asFixedPoint(r, 0)
| z <= asAsyncReset(r)""".stripMargin
)
- println(result.getEmittedCircuit)
result should containLine ("wire r : UInt<1>")
result should containLine ("r <= a")
result should containLine ("v <= asUInt(r)")
@@ -125,44 +124,68 @@ class InferResetsSpec extends FirrtlFlatSpec {
result should containTree { case Port(_, "buzz_bar_1_b", Input, AsyncResetType) => true }
}
- it should "NOT allow last connect semantics to pick the right type for Reset" in {
- an [InferResets.DifferingDriverTypesException] shouldBe thrownBy {
+ it should "not crash if a ResetType has no drivers" in {
+ a [CheckInitialization.RefNotInitializedException] shouldBe thrownBy {
+ compile(s"""
+ |circuit test :
+ | module test :
+ | output out : Reset
+ | wire w : Reset
+ | out <= w
+ | out <= UInt(1)
+ |""".stripMargin
+ )
+ }
+ }
+
+ it should "allow last connect semantics to pick the right type for Reset" in {
+ val result =
compile(s"""
|circuit top :
| module top :
| input reset0 : AsyncReset
| input reset1 : UInt<1>
| output out : Reset
+ | wire w0 : Reset
| wire w1 : Reset
- | wire w2 : Reset
- | w1 <= reset0
- | w2 <= reset1
+ | w0 <= reset0
+ | w1 <= reset1
+ | out <= w0
| out <= w1
- | out <= w2
|""".stripMargin
)
- }
+ result should containTree { case DefWire(_, "w0", AsyncResetType) => true }
+ result should containTree { case DefWire(_, "w1", BoolType) => true }
+ result should containTree { case Port(_, "out", Output, BoolType) => true }
}
- it should "NOT support last connect semantics across whens" in {
- an [InferResets.DifferingDriverTypesException] shouldBe thrownBy {
+ it should "support last connect semantics across whens" in {
+ val result =
compile(s"""
|circuit top :
| module top :
| input reset0 : AsyncReset
- | input reset1 : UInt<1>
- | input en0 : UInt<1>
+ | input reset1 : AsyncReset
+ | input reset2 : UInt<1>
+ | input en : UInt<1>
| output out : Reset
+ | wire w0 : Reset
| wire w1 : Reset
| wire w2 : Reset
- | w1 <= reset0
- | w2 <= reset1
- | out <= w1
- | when en0 :
- | out <= w2
+ | w0 <= reset0
+ | w1 <= reset1
+ | w2 <= reset2
+ | out <= w2
+ | when en :
+ | out <= w0
+ | else :
+ | out <= w1
|""".stripMargin
)
- }
+ result should containTree { case DefWire(_, "w0", AsyncResetType) => true }
+ result should containTree { case DefWire(_, "w1", AsyncResetType) => true }
+ result should containTree { case DefWire(_, "w2", BoolType) => true }
+ result should containTree { case Port(_, "out", Output, AsyncResetType) => true }
}
it should "not allow different Reset Types to drive a single Reset" in {
@@ -186,6 +209,42 @@ class InferResetsSpec extends FirrtlFlatSpec {
}
}
+ it should "allow concrete reset types to overrule invalidation" in {
+ val result = compile(s"""
+ |circuit test :
+ | module test :
+ | input in : AsyncReset
+ | output out : Reset
+ | out is invalid
+ | out <= in
+ |""".stripMargin)
+ result should containTree { case Port(_, "out", Output, AsyncResetType) => true }
+ }
+
+ it should "default to BoolType for Resets that are only invalidated" in {
+ val result = compile(s"""
+ |circuit test :
+ | module test :
+ | output out : Reset
+ | out is invalid
+ |""".stripMargin)
+ result should containTree { case Port(_, "out", Output, BoolType) => true }
+ }
+
+ it should "not error if component of ResetType is invalidated and connected to an AsyncResetType" in {
+ val result = compile(s"""
+ |circuit test :
+ | module test :
+ | input cond : UInt<1>
+ | input in : AsyncReset
+ | output out : Reset
+ | out is invalid
+ | when cond :
+ | out <= in
+ |""".stripMargin)
+ result should containTree { case Port(_, "out", Output, AsyncResetType) => true }
+ }
+
it should "allow ResetType to drive AsyncResets or UInt<1>" in {
val result1 = compile(s"""
|circuit top :