summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chiselFrontend/src/main/scala/chisel3/Bits.scala105
-rw-r--r--chiselFrontend/src/main/scala/chisel3/CompileOptions.scala12
-rw-r--r--chiselFrontend/src/main/scala/chisel3/RawModule.scala17
-rw-r--r--chiselFrontend/src/main/scala/chisel3/Reg.scala6
-rw-r--r--chiselFrontend/src/main/scala/chisel3/internal/MonoConnect.scala4
-rw-r--r--chiselFrontend/src/main/scala/chisel3/internal/firrtl/Converter.scala2
-rw-r--r--chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala1
-rw-r--r--src/main/scala/chisel3/internal/firrtl/Emitter.scala4
-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
13 files changed, 404 insertions, 21 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/Bits.scala b/chiselFrontend/src/main/scala/chisel3/Bits.scala
index f50512f0..5a6db7c1 100644
--- a/chiselFrontend/src/main/scala/chisel3/Bits.scala
+++ b/chiselFrontend/src/main/scala/chisel3/Bits.scala
@@ -1183,7 +1183,106 @@ trait SIntFactory {
object SInt extends SIntFactory
-sealed trait Reset extends Element with ToBoolable
+sealed trait Reset extends Element with ToBoolable {
+ /** Casts this $coll to an [[AsyncReset]] */
+ final def asAsyncReset(): AsyncReset = macro SourceInfoWhiteboxTransform.noArg
+
+ /** @group SourceInfoTransformMacro */
+ def do_asAsyncReset(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): AsyncReset
+}
+
+object Reset {
+ def apply(): Reset = new ResetType
+}
+
+/** "Abstract" Reset Type inferred in FIRRTL to either [[AsyncReset]] or [[Bool]]
+ *
+ * @note This shares a common interface with [[AsyncReset]] and [[Bool]] but is not their actual
+ * super type due to Bool inheriting from abstract class UInt
+ */
+final class ResetType(private[chisel3] val width: Width = Width(1)) extends Element with Reset {
+ override def toString: String = s"Reset$bindingToString"
+
+ def cloneType: this.type = Reset().asInstanceOf[this.type]
+
+ private[chisel3] def typeEquivalent(that: Data): Boolean =
+ this.getClass == that.getClass
+
+ override def connect(that: Data)(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): Unit = that match {
+ case _: Reset => super.connect(that)(sourceInfo, connectCompileOptions)
+ case _ => super.badConnect(that)(sourceInfo)
+ }
+
+ override def litOption = None
+
+ /** Not really supported */
+ def toPrintable: Printable = PString("Reset")
+
+ override def do_asUInt(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): UInt = pushOp(DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref))
+
+ private[chisel3] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo,
+ compileOptions: CompileOptions): Unit = {
+ this := that
+ }
+
+ /** @group SourceInfoTransformMacro */
+ def do_asAsyncReset(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): AsyncReset =
+ pushOp(DefPrim(sourceInfo, AsyncReset(), AsAsyncResetOp, ref))
+
+ /** @group SourceInfoTransformMacro */
+ def do_asBool(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
+ pushOp(DefPrim(sourceInfo, Bool(), AsUIntOp, ref))
+
+ /** @group SourceInfoTransformMacro */
+ def do_toBool(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = do_asBool
+}
+
+object AsyncReset {
+ def apply(): AsyncReset = new AsyncReset
+}
+
+/** Data type representing asynchronous reset signals
+ *
+ * These signals are similar to [[Clock]]s in that they must be glitch-free for proper circuit
+ * operation. [[Reg]]s defined with the implicit reset being an [[AsyncReset]] will be
+ * asychronously reset registers.
+ */
+sealed class AsyncReset(private[chisel3] val width: Width = Width(1)) extends Element with Reset {
+ override def toString: String = s"AsyncReset$bindingToString"
+
+ def cloneType: this.type = AsyncReset().asInstanceOf[this.type]
+
+ private[chisel3] def typeEquivalent(that: Data): Boolean =
+ this.getClass == that.getClass
+
+ override def connect(that: Data)(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): Unit = that match {
+ case _: AsyncReset => super.connect(that)(sourceInfo, connectCompileOptions)
+ case _ => super.badConnect(that)(sourceInfo)
+ }
+
+ override def litOption = None
+
+ /** Not really supported */
+ def toPrintable: Printable = PString("AsyncReset")
+
+ override def do_asUInt(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): UInt = pushOp(DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref))
+
+ // TODO Is this right?
+ private[chisel3] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo,
+ compileOptions: CompileOptions): Unit = {
+ this := that.asBool.asAsyncReset
+ }
+
+ /** @group SourceInfoTransformMacro */
+ def do_asAsyncReset(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): AsyncReset = this
+
+ /** @group SourceInfoTransformMacro */
+ def do_asBool(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
+ pushOp(DefPrim(sourceInfo, Bool(), AsUIntOp, ref))
+
+ /** @group SourceInfoTransformMacro */
+ def do_toBool(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = do_asBool
+}
// REVIEW TODO: Why does this extend UInt and not Bits? Does defining airth
// operations on a Bool make sense?
@@ -1286,6 +1385,10 @@ sealed class Bool() extends UInt(1.W) with Reset {
/** @group SourceInfoTransformMacro */
def do_asClock(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Clock = pushOp(DefPrim(sourceInfo, Clock(), AsClockOp, ref))
+
+ /** @group SourceInfoTransformMacro */
+ def do_asAsyncReset(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): AsyncReset =
+ pushOp(DefPrim(sourceInfo, AsyncReset(), AsAsyncResetOp, ref))
}
trait BoolFactory {
diff --git a/chiselFrontend/src/main/scala/chisel3/CompileOptions.scala b/chiselFrontend/src/main/scala/chisel3/CompileOptions.scala
index 33a41b72..ed410c6e 100644
--- a/chiselFrontend/src/main/scala/chisel3/CompileOptions.scala
+++ b/chiselFrontend/src/main/scala/chisel3/CompileOptions.scala
@@ -20,6 +20,8 @@ trait CompileOptions {
val checkSynthesizable: Boolean
// Require explicit assignment of DontCare to generate "x is invalid"
val explicitInvalidate: Boolean
+ // Should the reset type of Module be a Bool or a Reset
+ val inferModuleReset: Boolean
}
object CompileOptions {
@@ -48,7 +50,9 @@ object ExplicitCompileOptions {
// Check that referenced Data have actually been declared.
val checkSynthesizable: Boolean,
// Require an explicit DontCare assignment to generate a firrtl DefInvalid
- val explicitInvalidate: Boolean
+ val explicitInvalidate: Boolean,
+ // Should the reset type of Module be a Bool or a Reset
+ val inferModuleReset: Boolean
) extends CompileOptions
// Collection of "not strict" connection compile options.
@@ -59,7 +63,8 @@ object ExplicitCompileOptions {
dontTryConnectionsSwapped = false,
dontAssumeDirectionality = false,
checkSynthesizable = false,
- explicitInvalidate = false
+ explicitInvalidate = false,
+ inferModuleReset = false
)
// Collection of "strict" connection compile options, preferred for new code.
@@ -69,6 +74,7 @@ object ExplicitCompileOptions {
dontTryConnectionsSwapped = true,
dontAssumeDirectionality = true,
checkSynthesizable = true,
- explicitInvalidate = true
+ explicitInvalidate = true,
+ inferModuleReset = true
)
}
diff --git a/chiselFrontend/src/main/scala/chisel3/RawModule.scala b/chiselFrontend/src/main/scala/chisel3/RawModule.scala
index 6d316074..8f201ce6 100644
--- a/chiselFrontend/src/main/scala/chisel3/RawModule.scala
+++ b/chiselFrontend/src/main/scala/chisel3/RawModule.scala
@@ -143,7 +143,11 @@ abstract class MultiIOModule(implicit moduleCompileOptions: CompileOptions)
extends RawModule {
// Implicit clock and reset pins
val clock: Clock = IO(Input(Clock()))
- val reset: Reset = IO(Input(Bool()))
+ val reset: Reset = {
+ // Top module and compatibility mode use Bool for reset
+ val inferReset = _parent.isDefined && moduleCompileOptions.inferModuleReset
+ IO(Input(if (inferReset) Reset() else Bool()))
+ }
// Setup ClockAndReset
Builder.currentClock = Some(clock)
@@ -219,14 +223,7 @@ abstract class LegacyModule(implicit moduleCompileOptions: CompileOptions)
pushCommand(DefInvalid(sourceInfo, io.ref))
}
- override_clock match {
- case Some(override_clock) => clock := override_clock
- case _ => clock := Builder.forcedClock
- }
-
- override_reset match {
- case Some(override_reset) => reset := override_reset
- case _ => reset := Builder.forcedReset
- }
+ clock := override_clock.getOrElse(Builder.forcedClock)
+ reset := override_reset.getOrElse(Builder.forcedReset)
}
}
diff --git a/chiselFrontend/src/main/scala/chisel3/Reg.scala b/chiselFrontend/src/main/scala/chisel3/Reg.scala
index 8d3a915d..51c59bdb 100644
--- a/chiselFrontend/src/main/scala/chisel3/Reg.scala
+++ b/chiselFrontend/src/main/scala/chisel3/Reg.scala
@@ -152,12 +152,12 @@ object RegInit {
requireIsChiselType(t, "reg type")
}
val reg = t.cloneTypeFull
- val clock = Builder.forcedClock.ref
- val reset = Builder.forcedReset.ref
+ val clock = Builder.forcedClock
+ val reset = Builder.forcedReset
reg.bind(RegBinding(Builder.forcedUserModule))
requireIsHardware(init, "reg initializer")
- pushCommand(DefRegInit(sourceInfo, reg, clock, reset, init.ref))
+ pushCommand(DefRegInit(sourceInfo, reg, clock.ref, reset.ref, init.ref))
reg
}
diff --git a/chiselFrontend/src/main/scala/chisel3/internal/MonoConnect.scala b/chiselFrontend/src/main/scala/chisel3/internal/MonoConnect.scala
index e07f980d..ace7be20 100644
--- a/chiselFrontend/src/main/scala/chisel3/internal/MonoConnect.scala
+++ b/chiselFrontend/src/main/scala/chisel3/internal/MonoConnect.scala
@@ -87,6 +87,10 @@ private[chisel3] object MonoConnect {
elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod)
case (sink_e: Clock, source_e: Clock) =>
elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod)
+ case (sink_e: AsyncReset, source_e: AsyncReset) =>
+ elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod)
+ case (sink_e: ResetType, source_e: Reset) =>
+ elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod)
case (sink_e: EnumType, source_e: UnsafeEnum) =>
elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod)
case (sink_e: EnumType, source_e: EnumType) if sink_e.typeEquivalent(source_e) =>
diff --git a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/Converter.scala b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/Converter.scala
index cdc55b59..5309609b 100644
--- a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/Converter.scala
+++ b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/Converter.scala
@@ -214,6 +214,8 @@ private[chisel3] object Converter {
def extractType(data: Data, clearDir: Boolean = false): fir.Type = data match { // scalastyle:ignore cyclomatic.complexity line.size.limit
case _: Clock => fir.ClockType
+ case _: AsyncReset => fir.AsyncResetType
+ case _: ResetType => fir.ResetType
case d: EnumType => fir.UIntType(convert(d.width))
case d: UInt => fir.UIntType(convert(d.width))
case d: SInt => fir.SIntType(convert(d.width))
diff --git a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala
index 2cb4d092..e4b660dd 100644
--- a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala
+++ b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala
@@ -47,6 +47,7 @@ object PrimOp {
val AsFixedPointOp = PrimOp("asFixedPoint")
val SetBinaryPoint = PrimOp("bpset")
val AsClockOp = PrimOp("asClock")
+ val AsAsyncResetOp = PrimOp("asAsyncReset")
}
abstract class Arg {
diff --git a/src/main/scala/chisel3/internal/firrtl/Emitter.scala b/src/main/scala/chisel3/internal/firrtl/Emitter.scala
index 2f1b75b0..3d10670e 100644
--- a/src/main/scala/chisel3/internal/firrtl/Emitter.scala
+++ b/src/main/scala/chisel3/internal/firrtl/Emitter.scala
@@ -27,7 +27,9 @@ private class Emitter(circuit: Circuit) {
private def emitType(d: Data, clearDir: Boolean = false): String = d match { // scalastyle:ignore cyclomatic.complexity line.size.limit
case d: Clock => "Clock"
- case d: EnumType => s"UInt${d.width}"
+ case _: AsyncReset => "AsyncReset"
+ case _: ResetType => "Reset"
+ case d: chisel3.core.EnumType => s"UInt${d.width}"
case d: UInt => s"UInt${d.width}"
case d: SInt => s"SInt${d.width}"
case d: FixedPoint => s"Fixed${d.width}${d.binaryPoint}"
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())
})
}