diff options
| author | Jack Koenig | 2019-08-13 15:06:58 +0530 |
|---|---|---|
| committer | GitHub | 2019-08-13 15:06:58 +0530 |
| commit | 24dddea6dccea5a570cece78324a5db624c7303a (patch) | |
| tree | b03fa616d0b8796548604a3d2b564fd17cf4e2d8 /chiselFrontend/src/main/scala/chisel3/Bits.scala | |
| parent | fddb5943b1d36925a5435d327c3312572e98ca58 (diff) | |
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.
Diffstat (limited to 'chiselFrontend/src/main/scala/chisel3/Bits.scala')
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/Bits.scala | 105 |
1 files changed, 104 insertions, 1 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 { |
