summaryrefslogtreecommitdiff
path: root/chiselFrontend/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'chiselFrontend/src/main')
-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
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 {