summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/scala/chiselTests/AsyncResetSpec.scala172
-rw-r--r--src/test/scala/chiselTests/CloneModuleSpec.scala4
-rw-r--r--src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala46
-rw-r--r--src/test/scala/chiselTests/ResetSpec.scala50
-rw-r--r--src/test/scala/examples/SimpleVendingMachine.scala2
5 files changed, 271 insertions, 3 deletions
diff --git a/src/test/scala/chiselTests/AsyncResetSpec.scala b/src/test/scala/chiselTests/AsyncResetSpec.scala
new file mode 100644
index 00000000..78a29e99
--- /dev/null
+++ b/src/test/scala/chiselTests/AsyncResetSpec.scala
@@ -0,0 +1,172 @@
+// See LICENSE for license details.
+
+package chiselTests
+
+import chisel3._
+import chisel3.util.{Counter, Queue}
+import chisel3.testers.BasicTester
+import firrtl.checks.CheckResets.NonLiteralAsyncResetValueException
+
+class AsyncResetTester extends BasicTester {
+ val (_, cDiv) = Counter(true.B, 4)
+ // First rising edge when count === 3
+ val slowClk = cDiv.asClock
+
+ val (count, done) = Counter(true.B, 16)
+
+ val asyncResetNext = RegInit(false.B)
+ asyncResetNext := count === 4.U
+ val asyncReset = asyncResetNext.asAsyncReset
+
+ val reg = withClockAndReset(slowClk, asyncReset) {
+ RegInit(123.U(8.W))
+ }
+ reg := 5.U // Normal connection
+
+ when (count === 3.U) {
+ assert(reg === 5.U)
+ }
+ when (count >= 5.U && count < 7.U) {
+ assert(reg === 123.U)
+ } .elsewhen (count >= 7.U) {
+ assert(reg === 5.U)
+ }
+
+ when (done) {
+ stop()
+ }
+}
+
+class AsyncResetAggregateTester extends BasicTester {
+ class MyBundle extends Bundle {
+ val x = UInt(8.W)
+ val y = UInt(8.W)
+ }
+ val (_, cDiv) = Counter(true.B, 4)
+ // First rising edge when count === 3
+ val slowClk = cDiv.asClock
+
+ val (count, done) = Counter(true.B, 16)
+
+ val asyncResetNext = RegInit(false.B)
+ asyncResetNext := count === 4.U
+ val asyncReset = asyncResetNext.asAsyncReset
+
+ val reg = withClockAndReset(slowClk, asyncReset) {
+ val init = Wire(Vec(2, new MyBundle))
+ init(0).x := 0.U
+ init(0).y := 0.U
+ init(1).x := 0.U
+ init(1).y := 0.U
+ RegInit(init)
+ }
+ reg(0).x := 5.U // Normal connections
+ reg(0).y := 6.U
+ reg(1).x := 7.U
+ reg(1).y := 8.U
+
+ when (count === 3.U) {
+ assert(reg(0).x === 5.U)
+ assert(reg(0).y === 6.U)
+ assert(reg(1).x === 7.U)
+ assert(reg(1).y === 8.U)
+ }
+ when (count >= 5.U && count < 7.U) {
+ assert(reg(0).x === 0.U)
+ assert(reg(0).y === 0.U)
+ assert(reg(1).x === 0.U)
+ assert(reg(1).y === 0.U)
+ } .elsewhen (count >= 7.U) {
+ assert(reg(0).x === 5.U)
+ assert(reg(0).y === 6.U)
+ assert(reg(1).x === 7.U)
+ assert(reg(1).y === 8.U)
+ }
+
+ when (done) {
+ stop()
+ }
+}
+
+class AsyncResetQueueTester extends BasicTester {
+ val (_, cDiv) = Counter(true.B, 4)
+ val slowClk = cDiv.asClock
+
+ val (count, done) = Counter(true.B, 16)
+
+ val asyncResetNext = RegNext(false.B, false.B)
+ val asyncReset = asyncResetNext.asAsyncReset
+
+ val queue = withClockAndReset (slowClk, asyncReset) {
+ Module(new Queue(UInt(8.W), 4))
+ }
+ queue.io.enq.valid := true.B
+ queue.io.enq.bits := count
+
+ queue.io.deq.ready := false.B
+
+ val doCheck = RegNext(false.B, false.B)
+ when (queue.io.count === 3.U) {
+ asyncResetNext := true.B
+ doCheck := true.B
+ }
+ when (doCheck) {
+ assert(queue.io.count === 0.U)
+ }
+
+ when (done) {
+ stop()
+ }
+}
+
+class AsyncResetSpec extends ChiselFlatSpec {
+
+ behavior of "AsyncReset"
+
+ it should "be allowed with literal reset values" in {
+ elaborate(new BasicTester {
+ withReset(reset.asAsyncReset)(RegInit(123.U))
+ })
+ }
+
+ it should "NOT be allowed with non-literal reset values" in {
+ a [NonLiteralAsyncResetValueException] shouldBe thrownBy {
+ compile(new BasicTester {
+ val x = WireInit(123.U + 456.U)
+ withReset(reset.asAsyncReset)(RegInit(x))
+ })
+ }
+ }
+
+ it should "NOT be allowed to connect directly to a Bool" in {
+ a [ChiselException] shouldBe thrownBy {
+ elaborate(new BasicTester {
+ val bool = Wire(Bool())
+ val areset = reset.asAsyncReset
+ bool := areset
+ })
+ }
+ }
+
+ it should "simulate correctly" in {
+ assertTesterPasses(new AsyncResetTester)
+ }
+
+ it should "simulate correctly with aggregates" in {
+ assertTesterPasses(new AsyncResetAggregateTester)
+ }
+
+ it should "allow casting to and from Bool" in {
+ elaborate(new BasicTester {
+ val r: Reset = reset
+ val a: AsyncReset = WireInit(r.asAsyncReset)
+ val b: Bool = a.asBool
+ val c: AsyncReset = b.asAsyncReset
+ })
+ }
+
+ it should "allow changing the reset type of whole modules like Queue" in {
+ assertTesterPasses(new AsyncResetQueueTester)
+ }
+
+}
diff --git a/src/test/scala/chiselTests/CloneModuleSpec.scala b/src/test/scala/chiselTests/CloneModuleSpec.scala
index 59ba2eb5..ca8bd007 100644
--- a/src/test/scala/chiselTests/CloneModuleSpec.scala
+++ b/src/test/scala/chiselTests/CloneModuleSpec.scala
@@ -9,7 +9,7 @@ import chisel3.testers.BasicTester
class MultiIOQueue[T <: Data](gen: T, val entries: Int) extends MultiIOModule {
val clk = IO(Input(Clock()))
- val rst = IO(Input(Bool()))
+ val rst = IO(Input(Reset()))
val enq = IO(Flipped(EnqIO(gen)))
val deq = IO(Flipped(DeqIO(gen)))
val count = IO(Output(UInt(log2Ceil(entries + 1).W)))
@@ -28,7 +28,7 @@ class QueueClone(multiIO: Boolean = false) extends Module {
q1.rst := reset
q1.enq <> io.enq
q2_io("clk").asInstanceOf[Clock] := clock
- q2_io("rst").asInstanceOf[Bool] := reset
+ q2_io("rst").asInstanceOf[Reset] := reset
q2_io("enq").asInstanceOf[q1.enq.type] <> q1.deq
io.deq <> q2_io("deq").asInstanceOf[q1.deq.type]
io.count := q1.count + q2_io("count").asInstanceOf[q1.count.type]
diff --git a/src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala b/src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala
index 861b3fdd..4ca7dcda 100644
--- a/src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala
+++ b/src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala
@@ -243,5 +243,51 @@ class CompatibiltyInteroperabilitySpec extends ChiselFlatSpec {
}
}
}
+
+ "Compatibility Modules" should "have Bool as their reset type" in {
+ compile {
+ import Chisel._
+ class Intf extends Bundle {
+ val in = Bool(INPUT)
+ val en = Bool(INPUT)
+ val out = Bool(OUTPUT)
+ }
+ class Child extends Module {
+ val io = new Intf
+ io.out := Mux(io.en, io.in, reset)
+ }
+ new Module {
+ val io = new Intf
+ val child = Module(new Child)
+ io <> child.io
+ }
+ }
+ }
+
+ "Compatibility Modules" should "be instantiable inside chisel3 Modules" in {
+ compile {
+ object Compat {
+ import Chisel._
+ class Intf extends Bundle {
+ val in = Input(UInt(8.W))
+ val out = Output(UInt(8.W))
+ }
+ class OldMod extends Module {
+ val io = IO(new Intf)
+ io.out := Reg(next = io.in)
+ }
+ }
+ import chisel3._
+ import Compat._
+ new Module {
+ val io = IO(new Intf)
+ io <> Module(new Module {
+ val io = IO(new Intf)
+ val inst = Module(new OldMod)
+ io <> inst.io
+ }).io
+ }
+ }
+ }
}
diff --git a/src/test/scala/chiselTests/ResetSpec.scala b/src/test/scala/chiselTests/ResetSpec.scala
new file mode 100644
index 00000000..297c5516
--- /dev/null
+++ b/src/test/scala/chiselTests/ResetSpec.scala
@@ -0,0 +1,50 @@
+// See LICENSE for license details.
+
+package chiselTests
+
+import chisel3._
+import chisel3.experimental.{IO, RawModule}
+import chisel3.util.{Counter, Queue}
+import chisel3.testers.BasicTester
+
+class ResetAgnosticModule extends RawModule {
+ val clk = IO(Input(Clock()))
+ val rst = IO(Input(Reset()))
+ val out = IO(Output(UInt(8.W)))
+
+ val reg = withClockAndReset(clk, rst)(RegInit(0.U(8.W)))
+ reg := reg + 1.U
+ out := reg
+}
+
+
+class ResetSpec extends ChiselFlatSpec {
+
+ behavior of "Reset"
+
+ it should "allow writing modules that are reset agnostic" in {
+ val sync = compile(new Module {
+ val io = IO(new Bundle {
+ val out = Output(UInt(8.W))
+ })
+ val inst = Module(new ResetAgnosticModule)
+ inst.clk := clock
+ inst.rst := reset
+ assert(inst.rst.isInstanceOf[chisel3.ResetType])
+ io.out := inst.out
+ })
+ sync should include ("always @(posedge clk)")
+
+ val async = compile(new Module {
+ val io = IO(new Bundle {
+ val out = Output(UInt(8.W))
+ })
+ val inst = Module(new ResetAgnosticModule)
+ inst.clk := clock
+ inst.rst := reset.asTypeOf(AsyncReset())
+ assert(inst.rst.isInstanceOf[chisel3.ResetType])
+ io.out := inst.out
+ })
+ async should include ("always @(posedge clk or posedge rst)")
+ }
+}
diff --git a/src/test/scala/examples/SimpleVendingMachine.scala b/src/test/scala/examples/SimpleVendingMachine.scala
index 4bb6027a..2021ece8 100644
--- a/src/test/scala/examples/SimpleVendingMachine.scala
+++ b/src/test/scala/examples/SimpleVendingMachine.scala
@@ -52,7 +52,7 @@ class VerilogVendingMachine extends BlackBox {
// Because this is a blackbox, we must explicity add clock and reset
val io = IO(new SimpleVendingMachineIO {
val clock = Input(Clock())
- val reset = Input(Bool())
+ val reset = Input(Reset())
})
}