diff options
| author | Richard Lin | 2017-03-08 17:38:14 -0800 |
|---|---|---|
| committer | GitHub | 2017-03-08 17:38:14 -0800 |
| commit | a290d77ef3e88b200ab61cd41fcd1a1138321b66 (patch) | |
| tree | 3cbabf2a20dc34f9d60a585834f532070bcd5235 /chiselFrontend/src | |
| parent | 09e95c484e145e2a1b2f0a1aacf549c7354a1eca (diff) | |
Deprecate old Reg with nulls constructor (#455)
Diffstat (limited to 'chiselFrontend/src')
4 files changed, 100 insertions, 79 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala index fccc6f08..240f5c83 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala @@ -529,6 +529,7 @@ sealed class UInt private[core] (width: Width, lit: Option[ULit] = None) throwException(s"cannot call $this.asFixedPoint(binaryPoint=$binaryPoint), you must specify a known binaryPoint") } } + private[core] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit = { this := that.asUInt @@ -672,6 +673,7 @@ sealed class SInt private[core] (width: Width, lit: Option[SLit] = None) throwException(s"cannot call $this.asFixedPoint(binaryPoint=$binaryPoint), you must specify a known binaryPoint") } } + private[core] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) { this := that.asSInt } @@ -897,6 +899,7 @@ sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint, lit override def do_asUInt(implicit sourceInfo: SourceInfo): UInt = pushOp(DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref)) override def do_asSInt(implicit sourceInfo: SourceInfo): SInt = pushOp(DefPrim(sourceInfo, SInt(this.width), AsSIntOp, ref)) + override def do_asFixedPoint(binaryPoint: BinaryPoint)(implicit sourceInfo: SourceInfo): FixedPoint = { binaryPoint match { case KnownBinaryPoint(value) => diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala index 410f498e..66720f7c 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala @@ -334,28 +334,37 @@ abstract class Data extends HasId { } object Wire { - def apply[T <: Data](t: T): T = macro WireTransform.apply[T] - // No source info since Scala macros don't yet support named / default arguments. - def apply[T <: Data](dummy: Int = 0, init: T)(implicit compileOptions: CompileOptions): T = - do_apply(null.asInstanceOf[T], init)(UnlocatableSourceInfo, compileOptions) + def apply[T <: Data](dummy: Int = 0, init: T)(implicit compileOptions: CompileOptions): T = { + val model = (init.litArg match { + // For e.g. Wire(init=0.U(k.W)), fix the Reg's width to k + case Some(lit) if lit.forcedWidth => init.chiselCloneType + case _ => init match { + case init: Bits => init.cloneTypeWidth(Width()) + case init => init.chiselCloneType + } + }).asInstanceOf[T] + apply(model, init) + } // No source info since Scala macros don't yet support named / default arguments. - def apply[T <: Data](t: T, init: T)(implicit compileOptions: CompileOptions): T = - do_apply(t, init)(UnlocatableSourceInfo, compileOptions) + def apply[T <: Data](t: T, init: T)(implicit compileOptions: CompileOptions): T = { + implicit val noSourceInfo = UnlocatableSourceInfo + val x = apply(t) + Binding.checkSynthesizable(init, s"'init' ($init)") + x := init + x + } - def do_apply[T <: Data](t: T, init: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { - val x = Reg.makeType(chisel3.core.ExplicitCompileOptions.NotStrict, t, null.asInstanceOf[T], init) + def apply[T <: Data](t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { + val x = t.chiselCloneType // Bind each element of x to being a Wire Binding.bind(x, WireBinder(Builder.forcedModule), "Error: t") pushCommand(DefWire(sourceInfo, x)) pushCommand(DefInvalid(sourceInfo, x.ref)) - if (init != null) { - Binding.checkSynthesizable(init, s"'init' ($init)") - x := init - } + x } } diff --git a/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala b/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala index 8b264801..9511fdc9 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala @@ -5,7 +5,7 @@ package chisel3.core import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl.Connect import scala.language.experimental.macros -import chisel3.internal.sourceinfo.{DeprecatedSourceInfo, SourceInfo, SourceInfoTransform, UnlocatableSourceInfo, WireTransform} +import chisel3.internal.sourceinfo.SourceInfo /** * MonoConnect.connect executes a mono-directional connection element-wise. diff --git a/chiselFrontend/src/main/scala/chisel3/core/Reg.scala b/chiselFrontend/src/main/scala/chisel3/core/Reg.scala index 1287ac2f..715bdd70 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Reg.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Reg.scala @@ -2,88 +2,97 @@ package chisel3.core +import scala.language.experimental.macros + import chisel3.internal._ import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl._ -import chisel3.internal.sourceinfo.{SourceInfo, UnlocatableSourceInfo} +import chisel3.internal.sourceinfo.{SourceInfo} object Reg { - private[core] def makeType[T <: Data](compileOptions: CompileOptions, t: T = null, next: T = null, init: T = null): T = { - implicit val myCompileOptions = compileOptions - if (t ne null) { - if (compileOptions.declaredTypeMustBeUnbound) { - Binding.checkUnbound(t, s"t ($t) must be unbound Type. Try using cloneType?") - } - t.chiselCloneType - } else if (next ne null) { - (next match { - case next: Bits => next.cloneTypeWidth(Width()) - case _ => next.chiselCloneType - }).asInstanceOf[T] - - } else if (init ne null) { - init.litArg match { - // For e.g. Reg(init=UInt(0, k)), fix the Reg's width to k - case Some(lit) if lit.forcedWidth => init.chiselCloneType - case _ => (init match { - case init: Bits => init.cloneTypeWidth(Width()) - case _ => init.chiselCloneType - }).asInstanceOf[T] - } - } else { - throwException("cannot infer type") + /** Creates a register without initialization (reset is ignored). Value does + * not change unless assigned to (using the := operator). + * + * @param t: data type for the register + */ + def apply[T <: Data](t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { + if (compileOptions.declaredTypeMustBeUnbound) { + Binding.checkUnbound(t, s"t ($t) must be unbound Type. Try using cloneType?") } + val reg = t.chiselCloneType + val clock = Node(Builder.forcedClock) + + Binding.bind(reg, RegBinder(Builder.forcedModule), "Error: t") + pushCommand(DefReg(sourceInfo, reg, clock)) + reg } +} - /** Creates a register with optional next and initialization values. +object RegNext { + /** Returns a register with the specified next and no reset initialization. * - * @param t: data type for the register - * @param next: new value register is to be updated with every cycle (or - * empty to not update unless assigned to using the := operator) - * @param init: initialization value on reset (or empty for uninitialized, - * where the register value persists across a reset) - * - * @note this may result in a type error if called from a type parameterized - * function, since the Scala compiler isn't smart enough to know that null - * is a valid value. In those cases, you can either use the outType only Reg - * constructor or pass in `null.asInstanceOf[T]`. + * Essentially a 1-cycle delayed version of the input signal. */ - def apply[T <: Data](t: T = null, next: T = null, init: T = null)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = - // Scala macros can't (yet) handle named or default arguments. - do_apply(t, next, init)(sourceInfo, compileOptions) + def apply[T <: Data](next: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { + val model = (next match { + case next: Bits => next.cloneTypeWidth(Width()) + case next => next.chiselCloneType + }).asInstanceOf[T] + val reg = Reg(model) - /** Creates a register without initialization (reset is ignored). Value does - * not change unless assigned to (using the := operator). + Binding.checkSynthesizable(next, s"'next' ($next)") // TODO: move into connect? + reg := next + + reg + } + + /** Returns a register with the specified next and reset initialization. * - * @param outType: data type for the register + * Essentially a 1-cycle delayed version of the input signal. */ - def apply[T <: Data](outType: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = Reg[T](outType, null.asInstanceOf[T], null.asInstanceOf[T])(sourceInfo, compileOptions) + def apply[T <: Data](next: T, init: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { + val model = (next match { + case next: Bits => next.cloneTypeWidth(Width()) + case next => next.chiselCloneType + }).asInstanceOf[T] + val reg = RegInit(model, init) // TODO: this makes NO sense - def do_apply[T <: Data](t: T, next: T, init: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions = chisel3.core.ExplicitCompileOptions.NotStrict): T = { - // TODO: write this in a way that doesn't need nulls (bad Scala style), - // null.asInstanceOf[T], and two constructors. Using Option types are an - // option, but introduces cumbersome syntax (wrap everything in a Some()). - // Implicit conversions to Option (or similar) types were also considered, - // but Scala's type inferencer and implicit insertion isn't smart enough - // to resolve all use cases. If the type inferencer / implicit resolution - // system improves, this may be changed. - val x = makeType(compileOptions, t, next, init) - val clock = Node(Builder.forcedClock) - val reset = Node(Builder.forcedReset) + Binding.checkSynthesizable(next, s"'next' ($next)") // TODO: move into connect? + reg := next - // Bind each element of x to being a Reg - Binding.bind(x, RegBinder(Builder.forcedModule), "Error: t") + reg + } +} - if (init == null) { - pushCommand(DefReg(sourceInfo, x, clock)) - } else { - Binding.checkSynthesizable(init, s"'init' ($init)") - pushCommand(DefRegInit(sourceInfo, x, clock, reset, init.ref)) - } - if (next != null) { - Binding.checkSynthesizable(next, s"'next' ($next)") - x := next +object RegInit { + /** Returns a register pre-initialized (on reset) to the specified value. + * Register type is inferred from the initializer. + */ + def apply[T <: Data](init: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { + val model = (init.litArg match { + // For e.g. Reg(init=UInt(0, k)), fix the Reg's width to k + case Some(lit) if lit.forcedWidth => init.chiselCloneType + case _ => init match { + case init: Bits => init.cloneTypeWidth(Width()) + case init => init.chiselCloneType + } + }).asInstanceOf[T] + RegInit(model, init) + } + + /** Creates a register given an explicit type and an initialization (reset) value. + */ + def apply[T <: Data](t: T, init: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { + if (compileOptions.declaredTypeMustBeUnbound) { + Binding.checkUnbound(t, s"t ($t) must be unbound Type. Try using cloneType?") } - x + val reg = t.chiselCloneType + val clock = Node(Builder.forcedClock) + val reset = Node(Builder.forcedReset) + + Binding.bind(reg, RegBinder(Builder.forcedModule), "Error: t") + Binding.checkSynthesizable(init, s"'init' ($init)") + pushCommand(DefRegInit(sourceInfo, reg, clock, reset, init.ref)) + reg } } |
