summaryrefslogtreecommitdiff
path: root/chiselFrontend/src/main/scala
diff options
context:
space:
mode:
authorRichard Lin2017-08-17 17:24:02 -0700
committerJack Koenig2017-08-17 17:24:02 -0700
commit6e12ed9fd7a771eb30f44b8e1c4ab33f6ad8e0a6 (patch)
tree0ff452193d515adc32ecccacb2b58daa9a1d95cb /chiselFrontend/src/main/scala
parent802cfc4405c28ae212a955a92c7a6ad2d2b6f0c2 (diff)
More of the bindings refactor (#635)
Rest of the binding refactor
Diffstat (limited to 'chiselFrontend/src/main/scala')
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala162
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Data.scala48
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Mem.scala7
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Reg.scala2
4 files changed, 113 insertions, 106 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
index ca46323b..8700b444 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
@@ -76,7 +76,7 @@ sealed abstract class Aggregate extends Data {
private[core] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo,
compileOptions: CompileOptions): Unit = {
var i = 0
- val bits = Wire(UInt(this.width), init=that) // handles width padding
+ val bits = WireInit(UInt(this.width), that) // handles width padding
for (x <- flatten) {
x.connectFromBits(bits(i + x.getWidth - 1, i))
i += x.getWidth
@@ -84,96 +84,18 @@ sealed abstract class Aggregate extends Data {
}
}
-object Vec {
+trait VecFactory {
/** Creates a new [[Vec]] with `n` entries of the specified data type.
*
* @note elements are NOT assigned by default and have no value
*/
- def apply[T <: Data](n: Int, gen: T)(implicit sourceInfo: SourceInfo, 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)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = new Vec(gen.chiselCloneType, n)
-
- /** Creates a new [[Vec]] composed of elements of the input Seq of [[Data]]
- * nodes.
- *
- * @note input elements should be of the same type (this is checked at the
- * FIRRTL level, but not at the Scala / Chisel level)
- * @note the width of all output elements is the width of the largest input
- * element
- * @note output elements are connected from the input elements
- */
- def apply[T <: Data](elts: Seq[T]): Vec[T] = macro VecTransform.apply_elts
-
- 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
- // changing apply(elt0, elts*) to apply(elts*) causes a function collision
- // with apply(Seq) after type erasure. Workarounds by either introducing a
- // DummyImplicit or additional type parameter will break some code.
-
- // Check that types are homogeneous. Width mismatch for Elements is safe.
- require(!elts.isEmpty)
- elts.foreach(requireIsHardware(_, "vec element"))
-
- val vec = Wire(new Vec(cloneSupertype(elts, "Vec"), elts.length))
-
- // TODO: try to remove the logic for this mess
- elts.head.direction match {
- case ActualDirection.Input | ActualDirection.Output | ActualDirection.Unspecified =>
- // When internal wires are involved, driver / sink must be specified explicitly, otherwise
- // the system is unable to infer which is driver / sink
- (vec zip elts).foreach(x => x._1 := x._2)
- case ActualDirection.Bidirectional(_) =>
- // For bidirectional, must issue a bulk connect so subelements are resolved correctly.
- // Bulk connecting two wires may not succeed because Chisel frontend does not infer
- // directions.
- (vec zip elts).foreach(x => x._1 <> x._2)
+ def apply[T <: Data](n: Int, gen: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = {
+ if (compileOptions.declaredTypeMustBeUnbound) {
+ requireIsChiselType(gen, "vec type")
}
- vec
+ new Vec(gen.chiselCloneType, n)
}
- /** Creates a new [[Vec]] composed of the input [[Data]] nodes.
- *
- * @note input elements should be of the same type (this is checked at the
- * FIRRTL level, but not at the Scala / Chisel level)
- * @note the width of all output elements is the width of the largest input
- * element
- * @note output elements are connected from the input elements
- */
- 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, compileOptions: CompileOptions): Vec[T] =
- apply(elt0 +: elts.toSeq)
-
- /** Creates a new [[Vec]] of length `n` composed of the results of the given
- * function applied over a range of integer values starting from 0.
- *
- * @param n number of elements in the vector (the function is applied from
- * 0 to `n-1`)
- * @param gen function that takes in an Int (the index) and returns a
- * [[Data]] that becomes the output element
- */
- 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, 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
- * function repeatedly applied.
- *
- * @param n number of elements (amd the number of times the function is
- * called)
- * @param gen function that generates the [[Data]] that becomes the output
- * element
- */
- @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, compileOptions: CompileOptions): Vec[T] =
- apply(Seq.fill(n)(gen))
-
/** Truncate an index to implement modulo-power-of-2 addressing. */
private[core] def truncateIndex(idx: UInt, n: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = {
val w = BigInt(n-1).bitLength
@@ -184,6 +106,8 @@ object Vec {
}
}
+object Vec extends VecFactory
+
/** A vector (array) of [[Data]] elements. Provides hardware versions of various
* collection transformation functions found in software array implementations.
*
@@ -208,7 +132,7 @@ object Vec {
* - when multiple conflicting assignments are performed on a Vec element, the last one takes effect (unlike Mem, where the result is undefined)
* - 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[core] (gen: => T, val length: Int)
extends Aggregate with VecLike[T] {
private[core] override def typeEquivalent(that: Data): Boolean = that match {
case that: Vec[T] =>
@@ -326,6 +250,74 @@ sealed class Vec[T <: Data] private (gen: => T, val length: Int)
}
}
+object VecInit {
+ /** Creates a new [[Vec]] composed of elements of the input Seq of [[Data]]
+ * nodes.
+ *
+ * @note input elements should be of the same type (this is checked at the
+ * FIRRTL level, but not at the Scala / Chisel level)
+ * @note the width of all output elements is the width of the largest input
+ * element
+ * @note output elements are connected from the input elements
+ */
+ def apply[T <: Data](elts: Seq[T]): Vec[T] = macro VecTransform.apply_elts
+
+ 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
+ // changing apply(elt0, elts*) to apply(elts*) causes a function collision
+ // with apply(Seq) after type erasure. Workarounds by either introducing a
+ // DummyImplicit or additional type parameter will break some code.
+
+ // Check that types are homogeneous. Width mismatch for Elements is safe.
+ require(!elts.isEmpty)
+ elts.foreach(requireIsHardware(_, "vec element"))
+
+ val vec = Wire(new Vec(cloneSupertype(elts, "Vec"), elts.length))
+
+ // TODO: try to remove the logic for this mess
+ elts.head.direction match {
+ case ActualDirection.Input | ActualDirection.Output | ActualDirection.Unspecified =>
+ // When internal wires are involved, driver / sink must be specified explicitly, otherwise
+ // the system is unable to infer which is driver / sink
+ (vec zip elts).foreach(x => x._1 := x._2)
+ case ActualDirection.Bidirectional(_) =>
+ // For bidirectional, must issue a bulk connect so subelements are resolved correctly.
+ // Bulk connecting two wires may not succeed because Chisel frontend does not infer
+ // directions.
+ (vec zip elts).foreach(x => x._1 <> x._2)
+ }
+ vec
+ }
+
+ /** Creates a new [[Vec]] composed of the input [[Data]] nodes.
+ *
+ * @note input elements should be of the same type (this is checked at the
+ * FIRRTL level, but not at the Scala / Chisel level)
+ * @note the width of all output elements is the width of the largest input
+ * element
+ * @note output elements are connected from the input elements
+ */
+ 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, compileOptions: CompileOptions): Vec[T] =
+ apply(elt0 +: elts.toSeq)
+
+ /** Creates a new [[Vec]] of length `n` composed of the results of the given
+ * function applied over a range of integer values starting from 0.
+ *
+ * @param n number of elements in the vector (the function is applied from
+ * 0 to `n-1`)
+ * @param gen function that takes in an Int (the index) and returns a
+ * [[Data]] that becomes the output element
+ */
+ 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, compileOptions: CompileOptions): Vec[T] =
+ apply((0 until n).map(i => gen(i)))
+}
+
/** A trait for [[Vec]]s containing common hardware generators for collection
* operations.
*/
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala
index be1fe753..f61478c8 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala
@@ -83,8 +83,11 @@ object DataMirror {
requireIsHardware(target, "node requested directionality on")
target.direction
}
- // TODO: really not a reflection-style API, but a workaround for dir in the compatibility package
- def isSynthesizable(target: Data) = target.hasBinding
+
+ // Internal reflection-style APIs, subject to change and removal whenever.
+ object internal {
+ def isSynthesizable(target: Data) = target.hasBinding
+ }
}
/** Creates a clone of the super-type of the input elements. Super-type is defined as:
@@ -379,9 +382,27 @@ abstract class Data extends HasId {
def toPrintable: Printable
}
-object Wire {
- // 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 = {
+trait WireFactory {
+ def apply[T <: Data](t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
+ if (compileOptions.declaredTypeMustBeUnbound) {
+ requireIsChiselType(t, "wire type")
+ }
+ val x = t.chiselCloneType
+
+ // Bind each element of x to being a Wire
+ x.bind(WireBinding(Builder.forcedUserModule))
+
+ pushCommand(DefWire(sourceInfo, x))
+ pushCommand(DefInvalid(sourceInfo, x.ref))
+
+ x
+ }
+}
+
+object Wire extends WireFactory
+
+object WireInit {
+ def apply[T <: Data](init: T)(implicit sourceInfo: SourceInfo, 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
@@ -393,24 +414,11 @@ object Wire {
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 = {
+ def apply[T <: Data](t: T, init: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
implicit val noSourceInfo = UnlocatableSourceInfo
- val x = apply(t)
+ val x = Wire(t)
requireIsHardware(init, "wire initializer")
x := init
x
}
-
- 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
- x.bind(WireBinding(Builder.forcedUserModule))
-
- pushCommand(DefWire(sourceInfo, x))
- pushCommand(DefInvalid(sourceInfo, x.ref))
-
- x
- }
}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Mem.scala b/chiselFrontend/src/main/scala/chisel3/core/Mem.scala
index 47d48061..1e7a795a 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Mem.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Mem.scala
@@ -20,8 +20,10 @@ object Mem {
*/
def apply[T <: Data](size: Int, t: T): Mem[T] = macro MemTransform.apply[T]
def do_apply[T <: Data](size: Int, t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Mem[T] = {
+ if (compileOptions.declaredTypeMustBeUnbound) {
+ requireIsChiselType(t, "memory type")
+ }
val mt = t.chiselCloneType
-
val mem = new Mem(mt, size)
pushCommand(DefMemory(sourceInfo, mem, mt, size))
mem
@@ -121,6 +123,9 @@ object SyncReadMem {
def apply[T <: Data](size: Int, t: T): SyncReadMem[T] = macro MemTransform.apply[T]
def do_apply[T <: Data](size: Int, t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SyncReadMem[T] = {
+ if (compileOptions.declaredTypeMustBeUnbound) {
+ requireIsChiselType(t, "memory type")
+ }
val mt = t.chiselCloneType
val mem = new SyncReadMem(mt, size)
pushCommand(DefSeqMemory(sourceInfo, mem, mt, size))
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Reg.scala b/chiselFrontend/src/main/scala/chisel3/core/Reg.scala
index 3fdb3398..19bbee1c 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Reg.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Reg.scala
@@ -40,6 +40,7 @@ object RegNext {
}).asInstanceOf[T]
val reg = Reg(model)
+ requireIsHardware(next, "reg next")
reg := next
reg
@@ -56,6 +57,7 @@ object RegNext {
}).asInstanceOf[T]
val reg = RegInit(model, init) // TODO: this makes NO sense
+ requireIsHardware(next, "reg next")
reg := next
reg