From 24dddea6dccea5a570cece78324a5db624c7303a Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Tue, 13 Aug 2019 15:06:58 +0530 Subject: Add support for asynchronous reset (#1011) Adds new AsyncReset and "abstract" Reset types. Reset is inferred in FIRRTL to be either AsyncReset or Bool. The "reset type" of a register is set by the type of its reset signal: val asyncReset: AsyncReset = IO(Input(AsyncReset())) val syncReset: Bool = IO(Input(Bool())) val abstractReset: Reset = IO(Input(Reset())) val asyncReg = withReset(asyncReset) { RegInit(0.U) } val syncReg = withReset(syncReset) { RegInit(0.U) } val inferredReg = withReset(abstractReset) { RegInit(0.U) } AsyncReset can be cast to and from Bool. Whereas synchronous reset is equivalent to a mux in front of a flip-flop and thus can be driven by logic, asynchronous reset requires that the reset value is a constant. This is checked in FIRRTL. Inference of the concrete type of a Reset occurs based on the type the Reset's drivers. This inference is very simple, it is simple forward propagation of the type, but it allows for writing blocks and modules that are agnostic to the reset type. In particular, the implicit `reset` value in MultiIOModule and thus Module is now concretely an instance of Reset and thus will be inferred in FIRRTL.--- chiselFrontend/src/main/scala/chisel3/internal/MonoConnect.scala | 4 ++++ chiselFrontend/src/main/scala/chisel3/internal/firrtl/Converter.scala | 2 ++ chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala | 1 + 3 files changed, 7 insertions(+) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') 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 { -- cgit v1.2.3