diff options
| author | Andrew Waterman | 2016-10-27 18:41:51 -0700 |
|---|---|---|
| committer | Jack Koenig | 2016-10-28 00:35:04 -0700 |
| commit | 224ee397db324067b35874bf22c76a63e9ca531b (patch) | |
| tree | e49b3d11759db94de50940ac1eb19fff95974c30 /chiselFrontend | |
| parent | 09282f32bec847bcd0b652f778f42be13c7d027e (diff) | |
Plug holes where defaultCompileOptions leaked in
defaultCompileOptions is convenient, but it frequently foils the
compatibility layer by providing strict defaults rather than passing
through the user's CompileOptions. This notably manifests for
chiselCloneType, which has different behavior for chisel3 and Chisel.
Ideally, we'd get rid of defaultCompileOptions within chisel3.core
and only supply it to people who import chisel3._ (attn. @ucbjrl).
That would statically prevent further regressions of this nature
within the core.
The change to Vec.truncateIndex seems extraneous, but I chose an
alternate implementation rather than requiring compileOptions in
another place.
Diffstat (limited to 'chiselFrontend')
5 files changed, 32 insertions, 29 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 677fa43e..de7af462 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -9,7 +9,7 @@ import scala.language.experimental.macros import chisel3.internal._ import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl._ -import chisel3.internal.sourceinfo.{SourceInfo, DeprecatedSourceInfo, VecTransform, SourceInfoTransform, UnlocatableSourceInfo} +import chisel3.internal.sourceinfo._ /** An abstract class for data types that solely consist of (are an aggregate * of) other Data objects. @@ -28,10 +28,12 @@ object Vec { * * @note elements are NOT assigned by default and have no value */ - def apply[T <: Data](n: Int, gen: T): Vec[T] = new Vec(gen, n) + def apply[T <: Data](n: Int, gen: T)(implicit compileOptions: CompileOptions): Vec[T] = + new Vec(gen.chiselCloneType, n) @deprecated("Vec argument order should be size, t; this will be removed by the official release", "chisel3") - def apply[T <: Data](gen: T, n: Int): Vec[T] = new Vec(gen, n) + def apply[T <: Data](gen: T, n: Int)(implicit compileOptions: CompileOptions): Vec[T] = + apply(n, gen) /** Creates a new [[Vec]] composed of elements of the input Seq of [[Data]] * nodes. @@ -44,7 +46,7 @@ object Vec { */ def apply[T <: Data](elts: Seq[T]): Vec[T] = macro VecTransform.apply_elts - def do_apply[T <: Data](elts: Seq[T])(implicit sourceInfo: SourceInfo): Vec[T] = { + def do_apply[T <: Data](elts: Seq[T])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = { // REVIEW TODO: this should be removed in favor of the apply(elts: T*) // varargs constructor, which is more in line with the style of the Scala // collection API. However, a deprecation phase isn't possible, since @@ -64,7 +66,7 @@ object Vec { require(eltsCompatible(t, e), s"can't create Vec of heterogeneous types ${t.getClass} and ${e.getClass}") val maxWidth = elts.map(_.width).reduce(_ max _) - val vec = Wire(new Vec(t.cloneTypeWidth(maxWidth), elts.length)) + val vec = Wire(new Vec(t.cloneTypeWidth(maxWidth).chiselCloneType, elts.length)) def doConnect(sink: T, source: T) = { if (elts.head.flatten.exists(_.dir != Direction.Unspecified)) { sink bulkConnect source @@ -88,7 +90,7 @@ object Vec { */ def apply[T <: Data](elt0: T, elts: T*): Vec[T] = macro VecTransform.apply_elt0 - def do_apply[T <: Data](elt0: T, elts: T*)(implicit sourceInfo: SourceInfo): Vec[T] = + def do_apply[T <: Data](elt0: T, elts: T*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = apply(elt0 +: elts.toSeq) /** Creates a new [[Vec]] of length `n` composed of the results of the given @@ -101,7 +103,7 @@ object Vec { */ def tabulate[T <: Data](n: Int)(gen: (Int) => T): Vec[T] = macro VecTransform.tabulate - def do_tabulate[T <: Data](n: Int)(gen: (Int) => T)(implicit sourceInfo: SourceInfo): Vec[T] = + def do_tabulate[T <: Data](n: Int)(gen: (Int) => T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = apply((0 until n).map(i => gen(i))) /** Creates a new [[Vec]] of length `n` composed of the result of the given @@ -115,7 +117,7 @@ object Vec { @deprecated("Vec.fill(n)(gen) is deprecated. Please use Vec(Seq.fill(n)(gen))", "chisel3") def fill[T <: Data](n: Int)(gen: => T): Vec[T] = macro VecTransform.fill - def do_fill[T <: Data](n: Int)(gen: => T)(implicit sourceInfo: SourceInfo): Vec[T] = + def do_fill[T <: Data](n: Int)(gen: => T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = apply(Seq.fill(n)(gen)) /** Truncate an index to implement modulo-power-of-2 addressing. */ @@ -124,7 +126,7 @@ object Vec { if (n <= 1) UInt(0) else if (idx.width.known && idx.width.get <= w) idx else if (idx.width.known) idx(w-1,0) - else Wire(UInt(width = w), init = idx) + else (idx | UInt(0, w))(w-1,0) } } @@ -137,12 +139,12 @@ object Vec { * @note Vecs, unlike classes in Scala's collection library, are propagated * intact to FIRRTL as a vector type, which may make debugging easier */ -sealed class Vec[T <: Data] private (gen: T, val length: Int) +sealed class Vec[T <: Data] private (gen: => T, val length: Int) extends Aggregate with VecLike[T] { // Note: the constructor takes a gen() function instead of a Seq to enforce // that all elements must be the same and because it makes FIRRTL generation // simpler. - private val self: Seq[T] = Vector.fill(length)(gen.chiselCloneType) + private val self: Seq[T] = Vector.fill(length)(gen) /** * sample_element 'tracks' all changes to the elements of self. @@ -151,7 +153,7 @@ sealed class Vec[T <: Data] private (gen: T, val length: Int) * * Needed specifically for the case when the Vec is length 0. */ - private[core] val sample_element: T = gen.chiselCloneType + private[core] val sample_element: T = gen // allElements current includes sample_element // This is somewhat weird although I think the best course of action here is @@ -190,7 +192,7 @@ sealed class Vec[T <: Data] private (gen: T, val length: Int) */ def apply(idx: UInt): T = { Binding.checkSynthesizable(idx ,s"'idx' ($idx)") - val port = sample_element.chiselCloneType + val port = gen val i = Vec.truncateIndex(idx, length)(UnlocatableSourceInfo) port.setRef(this, i) @@ -216,7 +218,7 @@ sealed class Vec[T <: Data] private (gen: T, val length: Int) } override def cloneType: this.type = { - Vec(length, gen).asInstanceOf[this.type] + new Vec(gen, length).asInstanceOf[this.type] } private[chisel3] def toType: String = s"${sample_element.toType}[$length]" @@ -312,9 +314,9 @@ trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId { * true is NOT checked (useful in cases where the condition doesn't always * hold, but the results are not used in those cases) */ - def onlyIndexWhere(p: T => Bool): UInt = macro SourceInfoTransform.pArg + def onlyIndexWhere(p: T => Bool): UInt = macro CompileOptionsTransform.pArg - def do_onlyIndexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo): UInt = + def do_onlyIndexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = SeqUtils.oneHotMux(indexWhereHelper(p)) } diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala index 7ee11b92..4a09c70e 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala @@ -294,7 +294,7 @@ sealed abstract class Bits(width: Width, override val litArg: Option[LitArg]) pushOp(DefPrim(sourceInfo, UInt(w), ConcatOp, this.ref, that.ref)) } - override def do_fromBits(that: Bits)(implicit sourceInfo: SourceInfo): this.type = { + override def do_fromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): this.type = { val res = Wire(this, null).asInstanceOf[this.type] res := that res diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala index 2d3bfa2b..2f18e726 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala @@ -7,7 +7,7 @@ import scala.language.experimental.macros import chisel3.internal._ import chisel3.internal.Builder.{pushCommand, pushOp} import chisel3.internal.firrtl._ -import chisel3.internal.sourceinfo.{SourceInfo, DeprecatedSourceInfo, UnlocatableSourceInfo, WireTransform, SourceInfoTransform} +import chisel3.internal.sourceinfo._ import chisel3.internal.firrtl.PrimOp.AsUIntOp sealed abstract class Direction(name: String) { @@ -236,9 +236,9 @@ abstract class Data extends HasId { * @note does NOT check bit widths, may drop bits during assignment * @note what fromBits assigs to must have known widths */ - def fromBits(that: Bits): this.type = macro SourceInfoTransform.thatArg + def fromBits(that: Bits): this.type = macro CompileOptionsTransform.thatArg - def do_fromBits(that: Bits)(implicit sourceInfo: SourceInfo): this.type = { + def do_fromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): this.type = { var i = 0 val wire = Wire(this.chiselCloneType) val bits = @@ -286,14 +286,14 @@ 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): T = - do_apply(null.asInstanceOf[T], init)(UnlocatableSourceInfo) + def apply[T <: Data](dummy: Int = 0, init: T)(implicit compileOptions: CompileOptions): T = + do_apply(null.asInstanceOf[T], init)(UnlocatableSourceInfo, compileOptions) // No source info since Scala macros don't yet support named / default arguments. - def apply[T <: Data](t: T, init: T): T = - do_apply(t, init)(UnlocatableSourceInfo) + def apply[T <: Data](t: T, init: T)(implicit compileOptions: CompileOptions): T = + do_apply(t, init)(UnlocatableSourceInfo, compileOptions) - def do_apply[T <: Data](t: T, init: T)(implicit sourceInfo: SourceInfo): T = { + 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) // Bind each element of x to being a Wire @@ -311,7 +311,7 @@ object Wire { object Clock { def apply(): Clock = new Clock - def apply(dir: Direction): Clock = { + def apply(dir: Direction)(implicit compileOptions: CompileOptions): Clock = { val result = apply() dir match { case Direction.Input => Input(result) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Reg.scala b/chiselFrontend/src/main/scala/chisel3/core/Reg.scala index 9d380695..57979be0 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Reg.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Reg.scala @@ -9,6 +9,7 @@ import chisel3.internal.sourceinfo.{SourceInfo, UnlocatableSourceInfo} 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?") diff --git a/chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala b/chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala index 0d8604cd..558dea7a 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala @@ -4,7 +4,7 @@ package chisel3.core import scala.language.experimental.macros -import chisel3.internal.sourceinfo.{SourceInfo, SourceInfoTransform} +import chisel3.internal.sourceinfo._ private[chisel3] object SeqUtils { /** Concatenates the data elements of the input sequence, in sequence order, together. @@ -51,9 +51,9 @@ private[chisel3] object SeqUtils { * * @note assumes exactly one true predicate, results undefined otherwise */ - def oneHotMux[T <: Data](in: Iterable[(Bool, T)]): T = macro SourceInfoTransform.inArg + def oneHotMux[T <: Data](in: Iterable[(Bool, T)]): T = macro CompileOptionsTransform.inArg - def do_oneHotMux[T <: Data](in: Iterable[(Bool, T)])(implicit sourceInfo: SourceInfo): T = { + def do_oneHotMux[T <: Data](in: Iterable[(Bool, T)])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { if (in.tail.isEmpty) { in.head._2 } else { |
