diff options
Diffstat (limited to 'chiselFrontend')
7 files changed, 130 insertions, 17 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 { |
