diff options
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Assert.scala | 4 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Bits.scala | 24 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Module.scala | 2 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/MultiClock.scala | 6 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Printf.scala | 2 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/UserModule.scala | 4 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/internal/Builder.scala | 2 | ||||
| -rw-r--r-- | src/main/scala/chisel3/compatibility.scala | 3 | ||||
| -rw-r--r-- | src/main/scala/chisel3/testers/BasicTester.scala | 2 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/AsTypeOfTester.scala (renamed from src/test/scala/chiselTests/FromBitsTester.scala) | 33 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/Assert.scala | 6 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/CompatibilitySpec.scala | 12 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/MultiClockSpec.scala | 2 |
13 files changed, 70 insertions, 32 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Assert.scala b/chiselFrontend/src/main/scala/chisel3/core/Assert.scala index 8616154b..7f67f244 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Assert.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Assert.scala @@ -51,7 +51,7 @@ object assert { // scalastyle:ignore object.name } def apply_impl_do(cond: Bool, line: String, message: Option[String], data: Bits*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) { - when (!(cond || Builder.forcedReset)) { + when (!(cond || Module.reset.toBool)) { val fmt = message match { case Some(str) => s"Assertion failed: $str\n at $line\n" case None => s"Assertion failed\n at $line\n" @@ -77,7 +77,7 @@ object assert { // scalastyle:ignore object.name object stop { // scalastyle:ignore object.name /** Terminate execution with a failure code. */ def apply(code: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit = { - when (!Builder.forcedReset) { + when (!Module.reset.toBool) { pushCommand(Stop(sourceInfo, Node(Builder.forcedClock), code)) } } diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala index f61ca5a9..090c320b 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala @@ -36,12 +36,26 @@ abstract class Element(private[chisel3] val width: Width) extends Data { pushCommand(Connect(sourceInfo, this.lref, that.ref)) } +/** Exists to unify common interfaces of [[Bits]] and [[Reset]] + * Workaround because macros cannot override abstract methods + */ +private[chisel3] sealed trait ToBoolable extends Element { + + /** Casts this object to a [[Bool]] + * + * @note Width must be known and equal to 1 + */ + final def toBool(): Bool = macro SourceInfoWhiteboxTransform.noArg + + def do_toBool(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool +} + /** A data type for values represented by a single bitvector. Provides basic * bitwise operations. */ //scalastyle:off number.of.methods sealed abstract class Bits(width: Width, override val litArg: Option[LitArg]) - extends Element(width) { + extends Element(width) with ToBoolable { // TODO: perhaps make this concrete? // Arguments for: self-checking code (can't do arithmetic on bits) // Arguments against: generates down to a FIRRTL UInt anyways @@ -266,9 +280,7 @@ sealed abstract class Bits(width: Width, override val litArg: Option[LitArg]) @deprecated("Use asUInt, which makes the reinterpret cast more explicit", "chisel3") final def toUInt(implicit compileOptions: CompileOptions): UInt = do_asUInt(DeprecatedSourceInfo, compileOptions) - final def toBool(): Bool = macro SourceInfoTransform.noArg - - def do_toBool(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = { + final def do_toBool(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = { width match { case KnownWidth(1) => this(0) case _ => throwException(s"can't covert UInt<$width> to Bool") @@ -699,11 +711,13 @@ trait SIntFactory { object SInt extends SIntFactory +sealed trait Reset extends Element with ToBoolable + // REVIEW TODO: Why does this extend UInt and not Bits? Does defining airth // operations on a Bool make sense? /** A data type for booleans, defined as a single bit indicating true or false. */ -sealed class Bool(lit: Option[ULit] = None) extends UInt(1.W, lit) { +sealed class Bool(lit: Option[ULit] = None) extends UInt(1.W, lit) with Reset { private[core] override def cloneTypeWidth(w: Width): this.type = { require(!w.known || w.get == 1) new Bool().asInstanceOf[this.type] diff --git a/chiselFrontend/src/main/scala/chisel3/core/Module.scala b/chiselFrontend/src/main/scala/chisel3/core/Module.scala index dfb9081c..0e919d3c 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Module.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Module.scala @@ -70,7 +70,7 @@ object Module { /** Returns the implicit Clock */ def clock: Clock = Builder.forcedClock /** Returns the implicit Reset */ - def reset: Bool = Builder.forcedReset + def reset: Reset = Builder.forcedReset } /** Abstract base class for Modules, an instantiable organizational unit for RTL. diff --git a/chiselFrontend/src/main/scala/chisel3/core/MultiClock.scala b/chiselFrontend/src/main/scala/chisel3/core/MultiClock.scala index 62163318..6af4da41 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/MultiClock.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/MultiClock.scala @@ -9,7 +9,7 @@ import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl._ import chisel3.internal.sourceinfo.{SourceInfo} -private[chisel3] final case class ClockAndReset(clock: Clock, reset: Bool) +private[chisel3] final case class ClockAndReset(clock: Clock, reset: Reset) object withClockAndReset { // scalastyle:ignore object.name /** Creates a new Clock and Reset scope @@ -19,7 +19,7 @@ object withClockAndReset { // scalastyle:ignore object.name * @param block the block of code to run with new implicit Clock and Reset * @return the result of the block */ - def apply[T](clock: Clock, reset: Bool)(block: => T): T = { + def apply[T](clock: Clock, reset: Reset)(block: => T): T = { // Save parentScope val parentScope = Builder.currentClockAndReset Builder.currentClockAndReset = Some(ClockAndReset(clock, reset)) @@ -48,7 +48,7 @@ object withReset { // scalastyle:ignore object.name * @param block the block of code to run with new implicit Reset * @return the result of the block */ - def apply[T](reset: Bool)(block: => T): T = + def apply[T](reset: Reset)(block: => T): T = withClockAndReset(Module.clock, reset)(block) } diff --git a/chiselFrontend/src/main/scala/chisel3/core/Printf.scala b/chiselFrontend/src/main/scala/chisel3/core/Printf.scala index d6e2c8de..87134eda 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Printf.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Printf.scala @@ -55,7 +55,7 @@ object printf { // scalastyle:ignore object.name * @param pable [[Printable]] to print */ def apply(pable: Printable)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit = { - when (!Builder.forcedReset) { + when (!Module.reset.toBool) { printfWithoutReset(pable) } } diff --git a/chiselFrontend/src/main/scala/chisel3/core/UserModule.scala b/chiselFrontend/src/main/scala/chisel3/core/UserModule.scala index 8b176c3b..218b27c6 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/UserModule.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/UserModule.scala @@ -88,8 +88,8 @@ abstract class UserModule(implicit moduleCompileOptions: CompileOptions) abstract class ImplicitModule(implicit moduleCompileOptions: CompileOptions) extends UserModule { // Implicit clock and reset pins - val clock = IO(Input(Clock())) - val reset = IO(Input(Bool())) + val clock: Clock = IO(Input(Clock())) + val reset: Reset = IO(Input(Bool())) // Setup ClockAndReset Builder.currentClockAndReset = Some(ClockAndReset(clock, reset)) diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index 1d7a45e0..8af1835d 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -205,7 +205,7 @@ private[chisel3] object Builder { case None => throwException("Error: No implicit clock and reset.") } def forcedClock: Clock = forcedClockAndReset.clock - def forcedReset: Bool = forcedClockAndReset.reset + def forcedReset: Reset = forcedClockAndReset.reset // TODO(twigg): Ideally, binding checks and new bindings would all occur here // However, rest of frontend can't support this yet. diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala index e169fb8f..4d2d9311 100644 --- a/src/main/scala/chisel3/compatibility.scala +++ b/src/main/scala/chisel3/compatibility.scala @@ -195,6 +195,9 @@ package object Chisel { // scalastyle:ignore package.object.name type Bool = chisel3.core.Bool object Bool extends BoolFactory val Mux = chisel3.core.Mux + type Reset = chisel3.core.Reset + + implicit def resetToBool(reset: Reset): Bool = reset.toBool import chisel3.core.Param abstract class BlackBox(params: Map[String, Param] = Map.empty[String, Param]) extends chisel3.core.BlackBox(params) { diff --git a/src/main/scala/chisel3/testers/BasicTester.scala b/src/main/scala/chisel3/testers/BasicTester.scala index bd7d4027..6d1a4913 100644 --- a/src/main/scala/chisel3/testers/BasicTester.scala +++ b/src/main/scala/chisel3/testers/BasicTester.scala @@ -25,7 +25,7 @@ class BasicTester extends Module() { */ def stop()(implicit sourceInfo: SourceInfo) { // TODO: rewrite this using library-style SourceInfo passing. - when (!reset) { + when (!reset.toBool) { pushCommand(Stop(sourceInfo, Node(clock), 0)) } } diff --git a/src/test/scala/chiselTests/FromBitsTester.scala b/src/test/scala/chiselTests/AsTypeOfTester.scala index e916272f..75a2dc8a 100644 --- a/src/test/scala/chiselTests/FromBitsTester.scala +++ b/src/test/scala/chiselTests/AsTypeOfTester.scala @@ -9,7 +9,7 @@ import chisel3.experimental.{DataMirror, FixedPoint} import chisel3.testers.BasicTester import chisel3.util._ -class FromBitsBundleTester extends BasicTester { +class AsTypeOfBundleTester extends BasicTester { class MultiTypeBundle extends Bundle { val u = UInt(4.W) val s = SInt(4.W) @@ -18,16 +18,16 @@ class FromBitsBundleTester extends BasicTester { val bun = new MultiTypeBundle - val bunFromBits = ((4 << 8) + (15 << 4) + (12 << 0)).U.asTypeOf(bun) + val bunAsTypeOf = ((4 << 8) + (15 << 4) + (12 << 0)).U.asTypeOf(bun) - assert(bunFromBits.u === 4.U) - assert(bunFromBits.s === -1.S) - assert(bunFromBits.fp === FixedPoint.fromDouble(-0.5, 4.W, 3.BP)) + assert(bunAsTypeOf.u === 4.U) + assert(bunAsTypeOf.s === -1.S) + assert(bunAsTypeOf.fp === FixedPoint.fromDouble(-0.5, 4.W, 3.BP)) stop() } -class FromBitsVecTester extends BasicTester { +class AsTypeOfVecTester extends BasicTester { val vec = ((15 << 12) + (0 << 8) + (1 << 4) + (2 << 0)).U.asTypeOf(Vec(4, SInt(4.W))) assert(vec(0) === 2.S) @@ -38,7 +38,7 @@ class FromBitsVecTester extends BasicTester { stop() } -class FromBitsTruncationTester extends BasicTester { +class AsTypeOfTruncationTester extends BasicTester { val truncate = (64 + 3).U.asTypeOf(UInt(3.W)) val expand = 1.U.asTypeOf(UInt(3.W)) @@ -50,18 +50,27 @@ class FromBitsTruncationTester extends BasicTester { stop() } -class FromBitsSpec extends ChiselFlatSpec { - behavior of "fromBits" +class ResetAsTypeOfBoolTester extends BasicTester { + assert(reset.asTypeOf(Bool()) === reset.toBool) + stop() +} + +class AsTypeOfSpec extends ChiselFlatSpec { + behavior of "asTypeOf" it should "work with Bundles containing Bits Types" in { - assertTesterPasses{ new FromBitsBundleTester } + assertTesterPasses{ new AsTypeOfBundleTester } } it should "work with Vecs containing Bits Types" in { - assertTesterPasses{ new FromBitsVecTester } + assertTesterPasses{ new AsTypeOfVecTester } } it should "expand and truncate UInts of different width" in { - assertTesterPasses{ new FromBitsTruncationTester } + assertTesterPasses{ new AsTypeOfTruncationTester } + } + + it should "work for casting implicit Reset to Bool" in { + assertTesterPasses{ new ResetAsTypeOfBoolTester } } } diff --git a/src/test/scala/chiselTests/Assert.scala b/src/test/scala/chiselTests/Assert.scala index 92559123..994a16fd 100644 --- a/src/test/scala/chiselTests/Assert.scala +++ b/src/test/scala/chiselTests/Assert.scala @@ -10,7 +10,7 @@ import chisel3.util._ class FailingAssertTester() extends BasicTester { assert(false.B) // Wait to come out of reset - val (_, done) = Counter(!reset, 4) + val (_, done) = Counter(!reset.toBool, 4) when (done) { stop() } @@ -19,7 +19,7 @@ class FailingAssertTester() extends BasicTester { class SucceedingAssertTester() extends BasicTester { assert(true.B) // Wait to come out of reset - val (_, done) = Counter(!reset, 4) + val (_, done) = Counter(!reset.toBool, 4) when (done) { stop() } @@ -38,7 +38,7 @@ class PipelinedResetTester extends BasicTester { module.reset := RegNext(RegNext(RegNext(reset))) - val (_, done) = Counter(!reset, 4) + val (_, done) = Counter(!reset.toBool, 4) when (done) { stop() } diff --git a/src/test/scala/chiselTests/CompatibilitySpec.scala b/src/test/scala/chiselTests/CompatibilitySpec.scala index 52a93aed..7feee96f 100644 --- a/src/test/scala/chiselTests/CompatibilitySpec.scala +++ b/src/test/scala/chiselTests/CompatibilitySpec.scala @@ -270,6 +270,17 @@ class CompatibiltySpec extends ChiselFlatSpec with GeneratorDrivenPropertyChecks }) } + "Reset" should "still walk, talk, and quack like a Bool" in { + import Chisel._ + elaborate(new Module { + val io = new Bundle { + val in = Bool(INPUT) + val out = Bool(OUTPUT) + } + io.out := io.in && reset + }) + } + "Data.dir" should "give the correct direction for io" in { import Chisel._ elaborate(new Module { @@ -292,4 +303,5 @@ class CompatibiltySpec extends ChiselFlatSpec with GeneratorDrivenPropertyChecks }) } } + } diff --git a/src/test/scala/chiselTests/MultiClockSpec.scala b/src/test/scala/chiselTests/MultiClockSpec.scala index ada0b9b0..3f9ad895 100644 --- a/src/test/scala/chiselTests/MultiClockSpec.scala +++ b/src/test/scala/chiselTests/MultiClockSpec.scala @@ -55,7 +55,7 @@ class MultiClockSubModuleTest extends BasicTester { /** Test withReset changing the reset of a Reg */ class WithResetTest extends BasicTester { val reset2 = Wire(init = false.B) - val reg = withReset(reset2 || reset) { RegInit(0.U(8.W)) } + val reg = withReset(reset2 || reset.toBool) { RegInit(0.U(8.W)) } reg := reg + 1.U val (cycle, done) = Counter(true.B, 10) |
