summaryrefslogtreecommitdiff
path: root/chiselFrontend/src/main/scala/Chisel
diff options
context:
space:
mode:
Diffstat (limited to 'chiselFrontend/src/main/scala/Chisel')
-rw-r--r--chiselFrontend/src/main/scala/Chisel/Aggregate.scala377
-rw-r--r--chiselFrontend/src/main/scala/Chisel/Assert.scala73
-rw-r--r--chiselFrontend/src/main/scala/Chisel/Bits.scala756
-rw-r--r--chiselFrontend/src/main/scala/Chisel/BlackBox.scala55
-rw-r--r--chiselFrontend/src/main/scala/Chisel/Data.scala161
-rw-r--r--chiselFrontend/src/main/scala/Chisel/Mem.scala134
-rw-r--r--chiselFrontend/src/main/scala/Chisel/Module.scala119
-rw-r--r--chiselFrontend/src/main/scala/Chisel/Printf.scala36
-rw-r--r--chiselFrontend/src/main/scala/Chisel/Reg.scala71
-rw-r--r--chiselFrontend/src/main/scala/Chisel/SeqUtils.scala59
-rw-r--r--chiselFrontend/src/main/scala/Chisel/When.scala59
-rw-r--r--chiselFrontend/src/main/scala/Chisel/internal/Builder.scala123
-rw-r--r--chiselFrontend/src/main/scala/Chisel/internal/Error.scala91
-rw-r--r--chiselFrontend/src/main/scala/Chisel/internal/SourceInfo.scala51
-rw-r--r--chiselFrontend/src/main/scala/Chisel/internal/firrtl/IR.scala188
15 files changed, 0 insertions, 2353 deletions
diff --git a/chiselFrontend/src/main/scala/Chisel/Aggregate.scala b/chiselFrontend/src/main/scala/Chisel/Aggregate.scala
deleted file mode 100644
index 1eef5d69..00000000
--- a/chiselFrontend/src/main/scala/Chisel/Aggregate.scala
+++ /dev/null
@@ -1,377 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-import scala.collection.immutable.ListMap
-import scala.collection.mutable.{ArrayBuffer, HashSet, LinkedHashMap}
-import scala.language.experimental.macros
-
-import internal._
-import internal.Builder.pushCommand
-import internal.firrtl._
-import internal.sourceinfo.{SourceInfo, DeprecatedSourceInfo, VecTransform, SourceInfoTransform}
-
-/** An abstract class for data types that solely consist of (are an aggregate
- * of) other Data objects.
- */
-sealed abstract class Aggregate(dirArg: Direction) extends Data(dirArg) {
- private[Chisel] def cloneTypeWidth(width: Width): this.type = cloneType
- def width: Width = flatten.map(_.width).reduce(_ + _)
-}
-
-object Vec {
- /** 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): Vec[T] = new Vec(gen.cloneType, 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.cloneType, 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): 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.
- require(!elts.isEmpty)
- val width = elts.map(_.width).reduce(_ max _)
- val vec = Wire(new Vec(elts.head.cloneTypeWidth(width), elts.length))
- for ((v, e) <- vec zip elts)
- v := e
- 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): 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): 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
- */
- 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] =
- apply(Seq.fill(n)(gen))
-}
-
-/** A vector (array) of [[Data]] elements. Provides hardware versions of various
- * collection transformation functions found in software array implementations.
- *
- * @tparam T type of elements
- * @note when multiple conflicting assignments are performed on a Vec element,
- * the last one takes effect (unlike Mem, where the result is undefined)
- * @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)
- extends Aggregate(gen.dir) 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 = IndexedSeq.fill(length)(gen)
-
- override def <> (that: Data)(implicit sourceInfo: SourceInfo): Unit = this := that
-
- /** Strong bulk connect, assigning elements in this Vec from elements in a Seq.
- *
- * @note the length of this Vec must match the length of the input Seq
- */
- def <> (that: Seq[T])(implicit sourceInfo: SourceInfo): Unit = this := that
-
- // TODO: eliminate once assign(Seq) isn't ambiguous with assign(Data) since Vec extends Seq and Data
- def <> (that: Vec[T])(implicit sourceInfo: SourceInfo): Unit = this := that.asInstanceOf[Data]
-
- override def := (that: Data)(implicit sourceInfo: SourceInfo): Unit = that match {
- case _: Vec[_] => this connect that
- case _ => this badConnect that
- }
-
- /** Strong bulk connect, assigning elements in this Vec from elements in a Seq.
- *
- * @note the length of this Vec must match the length of the input Seq
- */
- def := (that: Seq[T])(implicit sourceInfo: SourceInfo): Unit = {
- require(this.length == that.length)
- for ((a, b) <- this zip that)
- a := b
- }
-
- // TODO: eliminate once assign(Seq) isn't ambiguous with assign(Data) since Vec extends Seq and Data
- def := (that: Vec[T])(implicit sourceInfo: SourceInfo): Unit = this connect that
-
- /** Creates a dynamically indexed read or write accessor into the array.
- */
- def apply(idx: UInt): T = {
- val x = gen
- x.setRef(this, idx)
- x
- }
-
- /** Creates a statically indexed read or write accessor into the array.
- */
- def apply(idx: Int): T = self(idx)
-
- @deprecated("Use Vec.apply instead", "chisel3")
- def read(idx: UInt): T = apply(idx)
-
- @deprecated("Use Vec.apply instead", "chisel3")
- def write(idx: UInt, data: T): Unit = apply(idx).:=(data)(DeprecatedSourceInfo)
-
- override def cloneType: this.type =
- Vec(length, gen).asInstanceOf[this.type]
-
- private val t = gen
- private[Chisel] def toType: String = s"${t.toType}[$length]"
- private[Chisel] lazy val flatten: IndexedSeq[Bits] =
- (0 until length).flatMap(i => this.apply(i).flatten)
-
- for ((elt, i) <- self zipWithIndex)
- elt.setRef(this, i)
-}
-
-/** A trait for [[Vec]]s containing common hardware generators for collection
- * operations.
- */
-trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId {
- def apply(idx: UInt): T
-
- // IndexedSeq has its own hashCode/equals that we must not use
- override def hashCode: Int = super[HasId].hashCode
- override def equals(that: Any): Boolean = super[HasId].equals(that)
-
- @deprecated("Use Vec.apply instead", "chisel3")
- def read(idx: UInt): T
-
- @deprecated("Use Vec.apply instead", "chisel3")
- def write(idx: UInt, data: T): Unit
-
- /** Outputs true if p outputs true for every element.
- */
- def forall(p: T => Bool): Bool = macro SourceInfoTransform.pArg
-
- def do_forall(p: T => Bool)(implicit sourceInfo: SourceInfo): Bool =
- (this map p).fold(Bool(true))(_ && _)
-
- /** Outputs true if p outputs true for at least one element.
- */
- def exists(p: T => Bool): Bool = macro SourceInfoTransform.pArg
-
- def do_exists(p: T => Bool)(implicit sourceInfo: SourceInfo): Bool =
- (this map p).fold(Bool(false))(_ || _)
-
- /** Outputs true if the vector contains at least one element equal to x (using
- * the === operator).
- */
- def contains(x: T)(implicit ev: T <:< UInt): Bool = macro VecTransform.contains
-
- def do_contains(x: T)(implicit sourceInfo: SourceInfo, ev: T <:< UInt): Bool =
- this.exists(_ === x)
-
- /** Outputs the number of elements for which p is true.
- */
- def count(p: T => Bool): UInt = macro SourceInfoTransform.pArg
-
- def do_count(p: T => Bool)(implicit sourceInfo: SourceInfo): UInt =
- SeqUtils.count(this map p)
-
- /** Helper function that appends an index (literal value) to each element,
- * useful for hardware generators which output an index.
- */
- private def indexWhereHelper(p: T => Bool) = this map p zip (0 until length).map(i => UInt(i))
-
- /** Outputs the index of the first element for which p outputs true.
- */
- def indexWhere(p: T => Bool): UInt = macro SourceInfoTransform.pArg
-
- def do_indexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo): UInt =
- SeqUtils.priorityMux(indexWhereHelper(p))
-
- /** Outputs the index of the last element for which p outputs true.
- */
- def lastIndexWhere(p: T => Bool): UInt = macro SourceInfoTransform.pArg
-
- def do_lastIndexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo): UInt =
- SeqUtils.priorityMux(indexWhereHelper(p).reverse)
-
- /** Outputs the index of the element for which p outputs true, assuming that
- * the there is exactly one such element.
- *
- * The implementation may be more efficient than a priority mux, but
- * incorrect results are possible if there is not exactly one true element.
- *
- * @note the assumption that there is only one element for which p outputs
- * 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 do_onlyIndexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo): UInt =
- SeqUtils.oneHotMux(indexWhereHelper(p))
-}
-
-/** Base class for data types defined as a bundle of other data types.
- *
- * Usage: extend this class (either as an anonymous or named class) and define
- * members variables of [[Data]] subtypes to be elements in the Bundle.
- */
-class Bundle extends Aggregate(NO_DIR) {
- private val _namespace = Builder.globalNamespace.child
-
- // TODO: replace with better defined FIRRTL weak-connect operator
- /** Connect elements in this Bundle to elements in `that` on a best-effort
- * (weak) basis, matching by type, orientation, and name.
- *
- * @note unconnected elements will NOT generate errors or warnings
- *
- * @example
- * {{{
- * // Pass through wires in this module's io to those mySubModule's io,
- * // matching by type, orientation, and name, and ignoring extra wires.
- * mySubModule.io <> io
- * }}}
- */
- override def <> (that: Data)(implicit sourceInfo: SourceInfo): Unit = that match {
- case _: Bundle => this bulkConnect that
- case _ => this badConnect that
- }
-
- // TODO: replace with better defined FIRRTL strong-connect operator
- override def := (that: Data)(implicit sourceInfo: SourceInfo): Unit = this <> that
-
- lazy val elements: ListMap[String, Data] = ListMap(namedElts:_*)
-
- /** Returns a best guess at whether a field in this Bundle is a user-defined
- * Bundle element without looking at type signatures.
- */
- private def isBundleField(m: java.lang.reflect.Method) =
- m.getParameterTypes.isEmpty &&
- !java.lang.reflect.Modifier.isStatic(m.getModifiers) &&
- !(Bundle.keywords contains m.getName) && !(m.getName contains '$')
-
- /** Returns a field's contained user-defined Bundle element if it appears to
- * be one, otherwise returns None.
- */
- private def getBundleField(m: java.lang.reflect.Method): Option[Data] = {
- if (isBundleField(m) &&
- (classOf[Data].isAssignableFrom(m.getReturnType) ||
- classOf[Option[_]].isAssignableFrom(m.getReturnType))) {
- m.invoke(this) match {
- case d: Data =>
- Some(d)
- case o: Option[_] =>
- o.getOrElse(None) match {
- case d: Data =>
- Some(d)
- case _ => None
- }
- case _ => None
- }
- } else {
- None
- }
- }
-
- /** Returns a list of elements in this Bundle.
- */
- private[Chisel] lazy val namedElts = {
- val nameMap = LinkedHashMap[String, Data]()
- val seen = HashSet[Data]()
- for (m <- getClass.getMethods.sortWith(_.getName < _.getName)) {
- getBundleField(m) match {
- case Some(d) =>
- if (nameMap contains m.getName) {
- require(nameMap(m.getName) eq d)
- } else if (!seen(d)) {
- nameMap(m.getName) = d; seen += d
- }
- case None =>
- }
- }
- ArrayBuffer(nameMap.toSeq:_*) sortWith {case ((an, a), (bn, b)) => (a._id > b._id) || ((a eq b) && (an > bn))}
- }
- private[Chisel] def toType = {
- def eltPort(elt: Data): String = {
- val flipStr = if (elt.isFlip) "flip " else ""
- s"${flipStr}${elt.getRef.name} : ${elt.toType}"
- }
- s"{${namedElts.reverse.map(e => eltPort(e._2)).mkString(", ")}}"
- }
- private[Chisel] lazy val flatten = namedElts.flatMap(_._2.flatten)
- private[Chisel] def addElt(name: String, elt: Data): Unit =
- namedElts += name -> elt
- private[Chisel] override def _onModuleClose: Unit = // scalastyle:ignore method.name
- for ((name, elt) <- namedElts) { elt.setRef(this, _namespace.name(name)) }
-
- override def cloneType : this.type = {
- // If the user did not provide a cloneType method, try invoking one of
- // the following constructors, not all of which necessarily exist:
- // - A zero-parameter constructor
- // - A one-paramater constructor, with null as the argument
- // - A one-parameter constructor for a nested Bundle, with the enclosing
- // parent Module as the argument
- val constructor = this.getClass.getConstructors.head
- try {
- val args = Seq.fill(constructor.getParameterTypes.size)(null)
- constructor.newInstance(args:_*).asInstanceOf[this.type]
- } catch {
- case e: java.lang.reflect.InvocationTargetException if e.getCause.isInstanceOf[java.lang.NullPointerException] =>
- try {
- constructor.newInstance(_parent.get).asInstanceOf[this.type]
- } catch {
- case _: java.lang.reflect.InvocationTargetException | _: java.lang.IllegalArgumentException =>
- Builder.error(s"Parameterized Bundle ${this.getClass} needs cloneType method. You are probably using " +
- "an anonymous Bundle object that captures external state and hence is un-cloneTypeable")
- this
- }
- case _: java.lang.reflect.InvocationTargetException | _: java.lang.IllegalArgumentException =>
- Builder.error(s"Parameterized Bundle ${this.getClass} needs cloneType method")
- this
- }
- }
-}
-
-private[Chisel] object Bundle {
- val keywords = List("flip", "asInput", "asOutput", "cloneType", "toBits")
-}
diff --git a/chiselFrontend/src/main/scala/Chisel/Assert.scala b/chiselFrontend/src/main/scala/Chisel/Assert.scala
deleted file mode 100644
index c086f014..00000000
--- a/chiselFrontend/src/main/scala/Chisel/Assert.scala
+++ /dev/null
@@ -1,73 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-import scala.reflect.macros.blackbox.Context
-import scala.language.experimental.macros
-
-import internal._
-import internal.Builder.pushCommand
-import internal.firrtl._
-import internal.sourceinfo.SourceInfo
-
-object assert { // scalastyle:ignore object.name
- /** Checks for a condition to be valid in the circuit at all times. If the
- * condition evaluates to false, the circuit simulation stops with an error.
- *
- * Does not fire when in reset (defined as the encapsulating Module's
- * reset). If your definition of reset is not the encapsulating Module's
- * reset, you will need to gate this externally.
- *
- * May be called outside of a Module (like defined in a function), so
- * functions using assert make the standard Module assumptions (single clock
- * and single reset).
- *
- * @param cond condition, assertion fires (simulation fails) when false
- * @param message optional message to print when the assertion fires
- *
- * @note currently cannot be used in core Chisel / libraries because macro
- * defs need to be compiled first and the SBT project is not set up to do
- * that
- */
- // Macros currently can't take default arguments, so we need two functions to emulate defaults.
- def apply(cond: Bool, message: String)(implicit sourceInfo: SourceInfo): Unit = macro apply_impl_msg
- def apply(cond: Bool)(implicit sourceInfo: SourceInfo): Unit = macro apply_impl
-
- def apply_impl_msg(c: Context)(cond: c.Tree, message: c.Tree)(sourceInfo: c.Tree): c.Tree = {
- import c.universe._
- val p = c.enclosingPosition
- val condStr = s"${p.source.file.name}:${p.line} ${p.lineContent.trim}"
- val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("apply_impl_do"))
- q"$apply_impl_do($cond, $condStr, _root_.scala.Some($message))($sourceInfo)"
- }
-
- def apply_impl(c: Context)(cond: c.Tree)(sourceInfo: c.Tree): c.Tree = {
- import c.universe._
- val p = c.enclosingPosition
- val condStr = s"${p.source.file.name}:${p.line} ${p.lineContent.trim}"
- val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("apply_impl_do"))
- q"$apply_impl_do($cond, $condStr, _root_.scala.None)($sourceInfo)"
- }
-
- def apply_impl_do(cond: Bool, line: String, message: Option[String])(implicit sourceInfo: SourceInfo) {
- when (!(cond || Builder.dynamicContext.currentModule.get.reset)) {
- message match {
- case Some(str) => printf.printfWithoutReset(s"Assertion failed: $str\n at $line\n")
- case None => printf.printfWithoutReset(s"Assertion failed\n at $line\n")
- }
- pushCommand(Stop(sourceInfo, Node(Builder.dynamicContext.currentModule.get.clock), 1))
- }
- }
-
- /** An elaboration-time assertion, otherwise the same as the above run-time
- * assertion. */
- def apply(cond: Boolean, message: => String) {
- Predef.assert(cond, message)
- }
-
- /** A workaround for default-value overloading problems in Scala, just
- * 'assert(cond, "")' */
- def apply(cond: Boolean) {
- Predef.assert(cond, "")
- }
-}
diff --git a/chiselFrontend/src/main/scala/Chisel/Bits.scala b/chiselFrontend/src/main/scala/Chisel/Bits.scala
deleted file mode 100644
index bc8cc8e2..00000000
--- a/chiselFrontend/src/main/scala/Chisel/Bits.scala
+++ /dev/null
@@ -1,756 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-import scala.language.experimental.macros
-
-import internal._
-import internal.Builder.pushOp
-import internal.firrtl._
-import internal.sourceinfo.{SourceInfo, DeprecatedSourceInfo, SourceInfoTransform, SourceInfoWhiteboxTransform,
- UIntTransform, MuxTransform}
-import firrtl.PrimOp._
-
-/** Element is a leaf data type: it cannot contain other Data objects. Example
- * uses are for representing primitive data types, like integers and bits.
- */
-abstract class Element(dirArg: Direction, val width: Width) extends Data(dirArg)
-
-/** A data type for values represented by a single bitvector. Provides basic
- * bitwise operations.
- */
-sealed abstract class Bits(dirArg: Direction, width: Width, override val litArg: Option[LitArg])
- extends Element(dirArg, width) {
- // 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
-
- private[Chisel] def fromInt(x: BigInt, w: Int): this.type
-
- private[Chisel] def flatten: IndexedSeq[Bits] = IndexedSeq(this)
-
- def cloneType: this.type = cloneTypeWidth(width)
-
- override def <> (that: Data)(implicit sourceInfo: SourceInfo): Unit = this := that
-
- final def tail(n: Int): UInt = macro SourceInfoTransform.nArg
- final def head(n: Int): UInt = macro SourceInfoTransform.nArg
-
- def do_tail(n: Int)(implicit sourceInfo: SourceInfo): UInt = {
- val w = width match {
- case KnownWidth(x) =>
- require(x >= n, s"Can't tail($n) for width $x < $n")
- Width(x - n)
- case UnknownWidth() => Width()
- }
- binop(sourceInfo, UInt(width = w), TailOp, n)
- }
-
-
- def do_head(n: Int)(implicit sourceInfo: SourceInfo): UInt = {
- width match {
- case KnownWidth(x) => require(x >= n, s"Can't head($n) for width $x < $n")
- case UnknownWidth() =>
- }
- binop(sourceInfo, UInt(width = n), HeadOp, n)
- }
-
- /** Returns the specified bit on this wire as a [[Bool]], statically
- * addressed.
- */
- final def apply(x: BigInt): Bool = macro SourceInfoTransform.xArg
-
- final def do_apply(x: BigInt)(implicit sourceInfo: SourceInfo): Bool = {
- if (x < 0) {
- Builder.error(s"Negative bit indices are illegal (got $x)")
- }
- if (isLit()) {
- Bool(((litValue() >> x.toInt) & 1) == 1)
- } else {
- pushOp(DefPrim(sourceInfo, Bool(), BitsExtractOp, this.ref, ILit(x), ILit(x)))
- }
- }
-
- /** Returns the specified bit on this wire as a [[Bool]], statically
- * addressed.
- *
- * @note convenience method allowing direct use of Ints without implicits
- */
- final def apply(x: Int): Bool = macro SourceInfoTransform.xArg
-
- final def do_apply(x: Int)(implicit sourceInfo: SourceInfo): Bool = apply(BigInt(x))
-
- /** Returns the specified bit on this wire as a [[Bool]], dynamically
- * addressed.
- */
- final def apply(x: UInt): Bool = macro SourceInfoTransform.xArg
-
- final def do_apply(x: UInt)(implicit sourceInfo: SourceInfo): Bool = {
- (this >> x)(0)
- }
-
- /** Returns a subset of bits on this wire from `hi` to `lo` (inclusive),
- * statically addressed.
- *
- * @example
- * {{{
- * myBits = 0x5 = 0b101
- * myBits(1,0) => 0b01 // extracts the two least significant bits
- * }}}
- */
- final def apply(x: Int, y: Int): UInt = macro SourceInfoTransform.xyArg
-
- final def do_apply(x: Int, y: Int)(implicit sourceInfo: SourceInfo): UInt = {
- if (x < y || y < 0) {
- Builder.error(s"Invalid bit range ($x,$y)")
- }
- val w = x - y + 1
- if (isLit()) {
- UInt((litValue >> y) & ((BigInt(1) << w) - 1), w)
- } else {
- pushOp(DefPrim(sourceInfo, UInt(width = w), BitsExtractOp, this.ref, ILit(x), ILit(y)))
- }
- }
-
- // REVIEW TODO: again, is this necessary? Or just have this and use implicits?
- final def apply(x: BigInt, y: BigInt): UInt = macro SourceInfoTransform.xyArg
-
- final def do_apply(x: BigInt, y: BigInt)(implicit sourceInfo: SourceInfo): UInt =
- apply(x.toInt, y.toInt)
-
- private[Chisel] def unop[T <: Data](sourceInfo: SourceInfo, dest: T, op: PrimOp): T =
- pushOp(DefPrim(sourceInfo, dest, op, this.ref))
- private[Chisel] def binop[T <: Data](sourceInfo: SourceInfo, dest: T, op: PrimOp, other: BigInt): T =
- pushOp(DefPrim(sourceInfo, dest, op, this.ref, ILit(other)))
- private[Chisel] def binop[T <: Data](sourceInfo: SourceInfo, dest: T, op: PrimOp, other: Bits): T =
- pushOp(DefPrim(sourceInfo, dest, op, this.ref, other.ref))
-
- private[Chisel] def compop(sourceInfo: SourceInfo, op: PrimOp, other: Bits): Bool =
- pushOp(DefPrim(sourceInfo, Bool(), op, this.ref, other.ref))
- private[Chisel] def redop(sourceInfo: SourceInfo, op: PrimOp): Bool =
- pushOp(DefPrim(sourceInfo, Bool(), op, this.ref))
-
- /** Returns this wire zero padded up to the specified width.
- *
- * @note for SInts only, this does sign extension
- */
- final def pad(that: Int): this.type = macro SourceInfoTransform.thatArg
-
- def do_pad(that: Int)(implicit sourceInfo: SourceInfo): this.type =
- binop(sourceInfo, cloneTypeWidth(this.width max Width(that)), PadOp, that)
-
- /** Returns this wire bitwise-inverted. */
- final def unary_~ (): Bits = macro SourceInfoWhiteboxTransform.noArg
-
- def do_unary_~ (implicit sourceInfo: SourceInfo): Bits
-
-
- /** Shift left operation */
- // REVIEW TODO: redundant
- // REVIEW TODO: should these return this.type or Bits?
- final def << (that: BigInt): Bits = macro SourceInfoWhiteboxTransform.thatArg
-
- def do_<< (that: BigInt)(implicit sourceInfo: SourceInfo): Bits
-
- /** Returns this wire statically left shifted by the specified amount,
- * inserting zeros into the least significant bits.
- *
- * The width of the output is `other` larger than the input.
- */
- final def << (that: Int): Bits = macro SourceInfoWhiteboxTransform.thatArg
-
- def do_<< (that: Int)(implicit sourceInfo: SourceInfo): Bits
-
- /** Returns this wire dynamically left shifted by the specified amount,
- * inserting zeros into the least significant bits.
- *
- * The width of the output is `pow(2, width(other))` larger than the input.
- */
- final def << (that: UInt): Bits = macro SourceInfoWhiteboxTransform.thatArg
-
- def do_<< (that: UInt)(implicit sourceInfo: SourceInfo): Bits
-
- /** Shift right operation */
- // REVIEW TODO: redundant
- final def >> (that: BigInt): Bits = macro SourceInfoWhiteboxTransform.thatArg
-
- def do_>> (that: BigInt)(implicit sourceInfo: SourceInfo): Bits
-
- /** Returns this wire statically right shifted by the specified amount,
- * inserting zeros into the most significant bits.
- *
- * The width of the output is the same as the input.
- */
- final def >> (that: Int): Bits = macro SourceInfoWhiteboxTransform.thatArg
-
- def do_>> (that: Int)(implicit sourceInfo: SourceInfo): Bits
-
- /** Returns this wire dynamically right shifted by the specified amount,
- * inserting zeros into the most significant bits.
- *
- * The width of the output is the same as the input.
- */
- final def >> (that: UInt): Bits = macro SourceInfoWhiteboxTransform.thatArg
-
- def do_>> (that: UInt)(implicit sourceInfo: SourceInfo): Bits
-
- /** Returns the contents of this wire as a [[Vec]] of [[Bool]]s.
- */
- final def toBools(): Seq[Bool] = macro SourceInfoTransform.noArg
-
- def toBools(implicit sourceInfo: SourceInfo): Seq[Bool] =
- Seq.tabulate(this.getWidth)(i => this(i))
-
- /** Reinterpret cast to a SInt.
- *
- * @note value not guaranteed to be preserved: for example, an UInt of width
- * 3 and value 7 (0b111) would become a SInt with value -1
- */
- final def asSInt(): SInt = macro SourceInfoTransform.noArg
-
- def do_asSInt(implicit sourceInfo: SourceInfo): SInt
-
- /** Reinterpret cast to an UInt.
- *
- * @note value not guaranteed to be preserved: for example, a SInt of width
- * 3 and value -1 (0b111) would become an UInt with value 7
- */
- final def asUInt(): UInt = macro SourceInfoTransform.noArg
-
- def do_asUInt(implicit sourceInfo: SourceInfo): UInt
-
- /** Reinterpret cast to Bits. */
- final def asBits(): Bits = macro SourceInfoTransform.noArg
-
- def do_asBits(implicit sourceInfo: SourceInfo): Bits = asUInt()
-
- @deprecated("Use asSInt, which makes the reinterpret cast more explicit", "chisel3")
- final def toSInt(): SInt = do_asSInt(DeprecatedSourceInfo)
- @deprecated("Use asUInt, which makes the reinterpret cast more explicit", "chisel3")
- final def toUInt(): UInt = do_asUInt(DeprecatedSourceInfo)
-
- final def toBool(): Bool = macro SourceInfoTransform.noArg
-
- def do_toBool(implicit sourceInfo: SourceInfo): Bool = {
- width match {
- case KnownWidth(1) => this(0)
- case _ => throwException(s"can't covert UInt<$width> to Bool")
- }
- }
-
- /** Returns this wire concatenated with `other`, where this wire forms the
- * most significant part and `other` forms the least significant part.
- *
- * The width of the output is sum of the inputs.
- */
- final def ## (that: Bits): UInt = macro SourceInfoTransform.thatArg
-
- def do_## (that: Bits)(implicit sourceInfo: SourceInfo): UInt = {
- val w = this.width + that.width
- pushOp(DefPrim(sourceInfo, UInt(w), ConcatOp, this.ref, that.ref))
- }
-
- @deprecated("Use asBits, which makes the reinterpret cast more explicit and actually returns Bits", "chisel3")
- override def toBits: UInt = do_asUInt(DeprecatedSourceInfo)
-
- override def do_fromBits(that: Bits)(implicit sourceInfo: SourceInfo): this.type = {
- val res = Wire(this, null).asInstanceOf[this.type]
- res := that
- res
- }
-}
-
-/** Provides a set of operations to create UInt types and literals.
- * Identical in functionality to the UInt companion object.
- */
-object Bits extends UIntFactory
-
-// REVIEW TODO: Further discussion needed on what Num actually is.
-/** Abstract trait defining operations available on numeric-like wire data
- * types.
- */
-abstract trait Num[T <: Data] {
- // def << (b: T): T
- // def >> (b: T): T
- //def unary_-(): T
-
- // REVIEW TODO: double check ops conventions against FIRRTL
-
- /** Outputs the sum of `this` and `b`. The resulting width is the max of the
- * operands plus 1 (should not overflow).
- */
- final def + (that: T): T = macro SourceInfoTransform.thatArg
-
- def do_+ (that: T)(implicit sourceInfo: SourceInfo): T
-
- /** Outputs the product of `this` and `b`. The resulting width is the sum of
- * the operands.
- *
- * @note can generate a single-cycle multiplier, which can result in
- * significant cycle time and area costs
- */
- final def * (that: T): T = macro SourceInfoTransform.thatArg
-
- def do_* (that: T)(implicit sourceInfo: SourceInfo): T
-
- /** Outputs the quotient of `this` and `b`.
- *
- * TODO: full rules
- */
- final def / (that: T): T = macro SourceInfoTransform.thatArg
-
- def do_/ (that: T)(implicit sourceInfo: SourceInfo): T
-
- final def % (that: T): T = macro SourceInfoTransform.thatArg
-
- def do_% (that: T)(implicit sourceInfo: SourceInfo): T
-
- /** Outputs the difference of `this` and `b`. The resulting width is the max
- * of the operands plus 1 (should not overflow).
- */
- final def - (that: T): T = macro SourceInfoTransform.thatArg
-
- def do_- (that: T)(implicit sourceInfo: SourceInfo): T
-
- /** Outputs true if `this` < `b`.
- */
- final def < (that: T): Bool = macro SourceInfoTransform.thatArg
-
- def do_< (that: T)(implicit sourceInfo: SourceInfo): Bool
-
- /** Outputs true if `this` <= `b`.
- */
- final def <= (that: T): Bool = macro SourceInfoTransform.thatArg
-
- def do_<= (that: T)(implicit sourceInfo: SourceInfo): Bool
-
- /** Outputs true if `this` > `b`.
- */
- final def > (that: T): Bool = macro SourceInfoTransform.thatArg
-
- def do_> (that: T)(implicit sourceInfo: SourceInfo): Bool
-
- /** Outputs true if `this` >= `b`.
- */
- final def >= (that: T): Bool = macro SourceInfoTransform.thatArg
-
- def do_>= (that: T)(implicit sourceInfo: SourceInfo): Bool
-
- /** Outputs the minimum of `this` and `b`. The resulting width is the max of
- * the operands.
- */
- final def min(that: T): T = macro SourceInfoTransform.thatArg
-
- def do_min(that: T)(implicit sourceInfo: SourceInfo): T =
- Mux(this < that, this.asInstanceOf[T], that)
-
- /** Outputs the maximum of `this` and `b`. The resulting width is the max of
- * the operands.
- */
- final def max(that: T): T = macro SourceInfoTransform.thatArg
-
- def do_max(that: T)(implicit sourceInfo: SourceInfo): T =
- Mux(this < that, that, this.asInstanceOf[T])
-}
-
-/** A data type for unsigned integers, represented as a binary bitvector.
- * Defines arithmetic operations between other integer types.
- */
-sealed class UInt private[Chisel] (dir: Direction, width: Width, lit: Option[ULit] = None)
- extends Bits(dir, width, lit) with Num[UInt] {
- private[Chisel] override def cloneTypeWidth(w: Width): this.type =
- new UInt(dir, w).asInstanceOf[this.type]
- private[Chisel] def toType = s"UInt$width"
-
- override private[Chisel] def fromInt(value: BigInt, width: Int): this.type =
- UInt(value, width).asInstanceOf[this.type]
-
- override def := (that: Data)(implicit sourceInfo: SourceInfo): Unit = that match {
- case _: UInt => this connect that
- case _ => this badConnect that
- }
-
- // TODO: refactor to share documentation with Num or add independent scaladoc
- final def unary_- (): UInt = macro SourceInfoTransform.noArg
- final def unary_-% (): UInt = macro SourceInfoTransform.noArg
-
- def do_unary_- (implicit sourceInfo: SourceInfo) : UInt = UInt(0) - this
- def do_unary_-% (implicit sourceInfo: SourceInfo): UInt = UInt(0) -% this
-
- override def do_+ (that: UInt)(implicit sourceInfo: SourceInfo): UInt = this +% that
- override def do_- (that: UInt)(implicit sourceInfo: SourceInfo): UInt = this -% that
- override def do_/ (that: UInt)(implicit sourceInfo: SourceInfo): UInt =
- binop(sourceInfo, UInt(this.width), DivideOp, that)
- override def do_% (that: UInt)(implicit sourceInfo: SourceInfo): UInt =
- binop(sourceInfo, UInt(this.width), RemOp, that)
- override def do_* (that: UInt)(implicit sourceInfo: SourceInfo): UInt =
- binop(sourceInfo, UInt(this.width + that.width), TimesOp, that)
-
- final def * (that: SInt): SInt = macro SourceInfoTransform.thatArg
- def do_* (that: SInt)(implicit sourceInfo: SourceInfo): SInt = that * this
-
- final def +& (that: UInt): UInt = macro SourceInfoTransform.thatArg
- final def +% (that: UInt): UInt = macro SourceInfoTransform.thatArg
- final def -& (that: UInt): UInt = macro SourceInfoTransform.thatArg
- final def -% (that: UInt): UInt = macro SourceInfoTransform.thatArg
-
- def do_+& (that: UInt)(implicit sourceInfo: SourceInfo): UInt =
- binop(sourceInfo, UInt((this.width max that.width) + 1), AddOp, that)
- def do_+% (that: UInt)(implicit sourceInfo: SourceInfo): UInt =
- (this +& that).tail(1)
- def do_-& (that: UInt)(implicit sourceInfo: SourceInfo): UInt =
- binop(sourceInfo, UInt((this.width max that.width) + 1), SubOp, that)
- def do_-% (that: UInt)(implicit sourceInfo: SourceInfo): UInt =
- (this -& that).tail(1)
-
- final def & (that: UInt): UInt = macro SourceInfoTransform.thatArg
- final def | (that: UInt): UInt = macro SourceInfoTransform.thatArg
- final def ^ (that: UInt): UInt = macro SourceInfoTransform.thatArg
-
- def do_& (that: UInt)(implicit sourceInfo: SourceInfo): UInt =
- binop(sourceInfo, UInt(this.width max that.width), BitAndOp, that)
- def do_| (that: UInt)(implicit sourceInfo: SourceInfo): UInt =
- binop(sourceInfo, UInt(this.width max that.width), BitOrOp, that)
- def do_^ (that: UInt)(implicit sourceInfo: SourceInfo): UInt =
- binop(sourceInfo, UInt(this.width max that.width), BitXorOp, that)
-
- /** Returns this wire bitwise-inverted. */
- def do_unary_~ (implicit sourceInfo: SourceInfo): UInt =
- unop(sourceInfo, UInt(width = width), BitNotOp)
-
- // REVIEW TODO: Can this be defined on Bits?
- final def orR(): Bool = macro SourceInfoTransform.noArg
- final def andR(): Bool = macro SourceInfoTransform.noArg
- final def xorR(): Bool = macro SourceInfoTransform.noArg
-
- def do_orR(implicit sourceInfo: SourceInfo): Bool = this != UInt(0)
- def do_andR(implicit sourceInfo: SourceInfo): Bool = ~this === UInt(0)
- def do_xorR(implicit sourceInfo: SourceInfo): Bool = redop(sourceInfo, XorReduceOp)
-
- override def do_< (that: UInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, LessOp, that)
- override def do_> (that: UInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, GreaterOp, that)
- override def do_<= (that: UInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, LessEqOp, that)
- override def do_>= (that: UInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, GreaterEqOp, that)
-
- final def != (that: UInt): Bool = macro SourceInfoTransform.thatArg
- final def =/= (that: UInt): Bool = macro SourceInfoTransform.thatArg
- final def === (that: UInt): Bool = macro SourceInfoTransform.thatArg
-
- def do_!= (that: UInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, NotEqualOp, that)
- def do_=/= (that: UInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, NotEqualOp, that)
- def do_=== (that: UInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, EqualOp, that)
-
- final def unary_! () : Bool = macro SourceInfoTransform.noArg
-
- def do_unary_! (implicit sourceInfo: SourceInfo) : Bool = this === Bits(0)
-
- override def do_<< (that: Int)(implicit sourceInfo: SourceInfo): UInt =
- binop(sourceInfo, UInt(this.width + that), ShiftLeftOp, that)
- override def do_<< (that: BigInt)(implicit sourceInfo: SourceInfo): UInt =
- this << that.toInt
- override def do_<< (that: UInt)(implicit sourceInfo: SourceInfo): UInt =
- binop(sourceInfo, UInt(this.width.dynamicShiftLeft(that.width)), DynamicShiftLeftOp, that)
- override def do_>> (that: Int)(implicit sourceInfo: SourceInfo): UInt =
- binop(sourceInfo, UInt(this.width.shiftRight(that)), ShiftRightOp, that)
- override def do_>> (that: BigInt)(implicit sourceInfo: SourceInfo): UInt =
- this >> that.toInt
- override def do_>> (that: UInt)(implicit sourceInfo: SourceInfo): UInt =
- binop(sourceInfo, UInt(this.width), DynamicShiftRightOp, that)
-
- final def bitSet(off: UInt, dat: Bool): UInt = macro UIntTransform.bitset
-
- def do_bitSet(off: UInt, dat: Bool)(implicit sourceInfo: SourceInfo): UInt = {
- val bit = UInt(1, 1) << off
- Mux(dat, this | bit, ~(~this | bit))
- }
-
- /** Returns this UInt as a [[SInt]] with an additional zero in the MSB.
- */
- // TODO: this eventually will be renamed as toSInt, once the existing toSInt
- // completes its deprecation phase.
- final def zext(): SInt = macro SourceInfoTransform.noArg
- def do_zext(implicit sourceInfo: SourceInfo): SInt =
- pushOp(DefPrim(sourceInfo, SInt(width + 1), ConvertOp, ref))
-
- /** Returns this UInt as a [[SInt]], without changing width or bit value. The
- * SInt is not guaranteed to have the same value (for example, if the MSB is
- * high, it will be interpreted as a negative value).
- */
- override def do_asSInt(implicit sourceInfo: SourceInfo): SInt =
- pushOp(DefPrim(sourceInfo, SInt(width), AsSIntOp, ref))
- override def do_asUInt(implicit sourceInfo: SourceInfo): UInt = this
-}
-
-// This is currently a factory because both Bits and UInt inherit it.
-private[Chisel] sealed trait UIntFactory {
- /** Create a UInt type with inferred width. */
- def apply(): UInt = apply(NO_DIR, Width())
- /** Create a UInt type or port with fixed width. */
- def apply(dir: Direction = NO_DIR, width: Int): UInt = apply(dir, Width(width))
- /** Create a UInt port with inferred width. */
- def apply(dir: Direction): UInt = apply(dir, Width())
-
- /** Create a UInt literal with inferred width. */
- def apply(value: BigInt): UInt = apply(value, Width())
- /** Create a UInt literal with fixed width. */
- def apply(value: BigInt, width: Int): UInt = apply(value, Width(width))
- /** Create a UInt literal with inferred width. */
- def apply(n: String): UInt = apply(parse(n), parsedWidth(n))
- /** Create a UInt literal with fixed width. */
- def apply(n: String, width: Int): UInt = apply(parse(n), width)
-
- /** Create a UInt type with specified width. */
- def apply(width: Width): UInt = apply(NO_DIR, width)
- /** Create a UInt port with specified width. */
- def apply(dir: Direction, width: Width): UInt = new UInt(dir, width)
- /** Create a UInt literal with specified width. */
- def apply(value: BigInt, width: Width): UInt = {
- val lit = ULit(value, width)
- new UInt(NO_DIR, lit.width, Some(lit))
- }
-
- private def parse(n: String) = {
- val (base, num) = n.splitAt(1)
- val radix = base match {
- case "x" | "h" => 16
- case "d" => 10
- case "o" => 8
- case "b" => 2
- case _ => Builder.error(s"Invalid base $base"); 2
- }
- BigInt(num.filterNot(_ == '_'), radix)
- }
-
- private def parsedWidth(n: String) =
- if (n(0) == 'b') {
- Width(n.length-1)
- } else if (n(0) == 'h') {
- Width((n.length-1) * 4)
- } else {
- Width()
- }
-}
-
-object UInt extends UIntFactory
-
-sealed class SInt private (dir: Direction, width: Width, lit: Option[SLit] = None)
- extends Bits(dir, width, lit) with Num[SInt] {
- private[Chisel] override def cloneTypeWidth(w: Width): this.type =
- new SInt(dir, w).asInstanceOf[this.type]
- private[Chisel] def toType = s"SInt$width"
-
- override def := (that: Data)(implicit sourceInfo: SourceInfo): Unit = that match {
- case _: SInt => this connect that
- case _ => this badConnect that
- }
-
- override private[Chisel] def fromInt(value: BigInt, width: Int): this.type =
- SInt(value, width).asInstanceOf[this.type]
-
- final def unary_- (): SInt = macro SourceInfoTransform.noArg
- final def unary_-% (): SInt = macro SourceInfoTransform.noArg
-
- def unary_- (implicit sourceInfo: SourceInfo): SInt = SInt(0) - this
- def unary_-% (implicit sourceInfo: SourceInfo): SInt = SInt(0) -% this
-
- /** add (default - no growth) operator */
- override def do_+ (that: SInt)(implicit sourceInfo: SourceInfo): SInt =
- this +% that
- /** subtract (default - no growth) operator */
- override def do_- (that: SInt)(implicit sourceInfo: SourceInfo): SInt =
- this -% that
- override def do_* (that: SInt)(implicit sourceInfo: SourceInfo): SInt =
- binop(sourceInfo, SInt(this.width + that.width), TimesOp, that)
- override def do_/ (that: SInt)(implicit sourceInfo: SourceInfo): SInt =
- binop(sourceInfo, SInt(this.width), DivideOp, that)
- override def do_% (that: SInt)(implicit sourceInfo: SourceInfo): SInt =
- binop(sourceInfo, SInt(this.width), RemOp, that)
-
- final def * (that: UInt): SInt = macro SourceInfoTransform.thatArg
- def do_* (that: UInt)(implicit sourceInfo: SourceInfo): SInt =
- binop(sourceInfo, SInt(this.width + that.width), TimesOp, that)
-
- /** add (width +1) operator */
- final def +& (that: SInt): SInt = macro SourceInfoTransform.thatArg
- /** add (no growth) operator */
- final def +% (that: SInt): SInt = macro SourceInfoTransform.thatArg
- /** subtract (width +1) operator */
- final def -& (that: SInt): SInt = macro SourceInfoTransform.thatArg
- /** subtract (no growth) operator */
- final def -% (that: SInt): SInt = macro SourceInfoTransform.thatArg
-
- def do_+& (that: SInt)(implicit sourceInfo: SourceInfo): SInt =
- binop(sourceInfo, SInt((this.width max that.width) + 1), AddOp, that)
- def do_+% (that: SInt)(implicit sourceInfo: SourceInfo): SInt =
- (this +& that).tail(1).asSInt
- def do_-& (that: SInt)(implicit sourceInfo: SourceInfo): SInt =
- binop(sourceInfo, SInt((this.width max that.width) + 1), SubOp, that)
- def do_-% (that: SInt)(implicit sourceInfo: SourceInfo): SInt =
- (this -& that).tail(1).asSInt
-
- final def & (that: SInt): SInt = macro SourceInfoTransform.thatArg
- final def | (that: SInt): SInt = macro SourceInfoTransform.thatArg
- final def ^ (that: SInt): SInt = macro SourceInfoTransform.thatArg
-
- def do_& (that: SInt)(implicit sourceInfo: SourceInfo): SInt =
- binop(sourceInfo, UInt(this.width max that.width), BitAndOp, that).asSInt
- def do_| (that: SInt)(implicit sourceInfo: SourceInfo): SInt =
- binop(sourceInfo, UInt(this.width max that.width), BitOrOp, that).asSInt
- def do_^ (that: SInt)(implicit sourceInfo: SourceInfo): SInt =
- binop(sourceInfo, UInt(this.width max that.width), BitXorOp, that).asSInt
-
- /** Returns this wire bitwise-inverted. */
- def do_unary_~ (implicit sourceInfo: SourceInfo): SInt =
- unop(sourceInfo, UInt(width = width), BitNotOp).asSInt
-
- override def do_< (that: SInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, LessOp, that)
- override def do_> (that: SInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, GreaterOp, that)
- override def do_<= (that: SInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, LessEqOp, that)
- override def do_>= (that: SInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, GreaterEqOp, that)
-
- final def != (that: SInt): Bool = macro SourceInfoTransform.thatArg
- final def =/= (that: SInt): Bool = macro SourceInfoTransform.thatArg
- final def === (that: SInt): Bool = macro SourceInfoTransform.thatArg
-
- def do_!= (that: SInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, NotEqualOp, that)
- def do_=/= (that: SInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, NotEqualOp, that)
- def do_=== (that: SInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, EqualOp, that)
-
- final def abs(): UInt = macro SourceInfoTransform.noArg
-
- def do_abs(implicit sourceInfo: SourceInfo): UInt = Mux(this < SInt(0), (-this).asUInt, this.asUInt)
-
- override def do_<< (that: Int)(implicit sourceInfo: SourceInfo): SInt =
- binop(sourceInfo, SInt(this.width + that), ShiftLeftOp, that)
- override def do_<< (that: BigInt)(implicit sourceInfo: SourceInfo): SInt =
- this << that.toInt
- override def do_<< (that: UInt)(implicit sourceInfo: SourceInfo): SInt =
- binop(sourceInfo, SInt(this.width.dynamicShiftLeft(that.width)), DynamicShiftLeftOp, that)
- override def do_>> (that: Int)(implicit sourceInfo: SourceInfo): SInt =
- binop(sourceInfo, SInt(this.width.shiftRight(that)), ShiftRightOp, that)
- override def do_>> (that: BigInt)(implicit sourceInfo: SourceInfo): SInt =
- this >> that.toInt
- override def do_>> (that: UInt)(implicit sourceInfo: SourceInfo): SInt =
- binop(sourceInfo, SInt(this.width), DynamicShiftRightOp, that)
-
- override def do_asUInt(implicit sourceInfo: SourceInfo): UInt = pushOp(DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref))
- override def do_asSInt(implicit sourceInfo: SourceInfo): SInt = this
-}
-
-object SInt {
- /** Create an SInt type with inferred width. */
- def apply(): SInt = apply(NO_DIR, Width())
- /** Create an SInt type or port with fixed width. */
- def apply(dir: Direction = NO_DIR, width: Int): SInt = apply(dir, Width(width))
- /** Create an SInt port with inferred width. */
- def apply(dir: Direction): SInt = apply(dir, Width())
-
- /** Create an SInt literal with inferred width. */
- def apply(value: BigInt): SInt = apply(value, Width())
- /** Create an SInt literal with fixed width. */
- def apply(value: BigInt, width: Int): SInt = apply(value, Width(width))
-
- /** Create an SInt type with specified width. */
- def apply(width: Width): SInt = new SInt(NO_DIR, width)
- /** Create an SInt port with specified width. */
- def apply(dir: Direction, width: Width): SInt = new SInt(dir, width)
- /** Create an SInt literal with specified width. */
- def apply(value: BigInt, width: Width): SInt = {
- val lit = SLit(value, width)
- new SInt(NO_DIR, lit.width, Some(lit))
- }
-}
-
-// 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(dir: Direction, lit: Option[ULit] = None) extends UInt(dir, Width(1), lit) {
- private[Chisel] override def cloneTypeWidth(w: Width): this.type = {
- require(!w.known || w.get == 1)
- new Bool(dir).asInstanceOf[this.type]
- }
-
- override private[Chisel] def fromInt(value: BigInt, width: Int): this.type = {
- require((value == 0 || value == 1) && width == 1)
- Bool(value == 1).asInstanceOf[this.type]
- }
-
- // REVIEW TODO: Why does this need to exist and have different conventions
- // than Bits?
- final def & (that: Bool): Bool = macro SourceInfoTransform.thatArg
- final def | (that: Bool): Bool = macro SourceInfoTransform.thatArg
- final def ^ (that: Bool): Bool = macro SourceInfoTransform.thatArg
-
- def do_& (that: Bool)(implicit sourceInfo: SourceInfo): Bool =
- binop(sourceInfo, Bool(), BitAndOp, that)
- def do_| (that: Bool)(implicit sourceInfo: SourceInfo): Bool =
- binop(sourceInfo, Bool(), BitOrOp, that)
- def do_^ (that: Bool)(implicit sourceInfo: SourceInfo): Bool =
- binop(sourceInfo, Bool(), BitXorOp, that)
-
- /** Returns this wire bitwise-inverted. */
- override def do_unary_~ (implicit sourceInfo: SourceInfo): Bool =
- unop(sourceInfo, Bool(), BitNotOp)
-
- /** Outputs the logical OR of two Bools.
- */
- def || (that: Bool): Bool = macro SourceInfoTransform.thatArg
-
- def do_|| (that: Bool)(implicit sourceInfo: SourceInfo): Bool = this | that
-
- /** Outputs the logical AND of two Bools.
- */
- def && (that: Bool): Bool = macro SourceInfoTransform.thatArg
-
- def do_&& (that: Bool)(implicit sourceInfo: SourceInfo): Bool = this & that
-}
-
-object Bool {
- /** Creates an empty Bool.
- */
- def apply(dir: Direction = NO_DIR): Bool = new Bool(dir)
-
- /** Creates Bool literal.
- */
- def apply(x: Boolean): Bool = new Bool(NO_DIR, Some(ULit(if (x) 1 else 0, Width(1))))
-}
-
-object Mux {
- /** Creates a mux, whose output is one of the inputs depending on the
- * value of the condition.
- *
- * @param cond condition determining the input to choose
- * @param con the value chosen when `cond` is true
- * @param alt the value chosen when `cond` is false
- * @example
- * {{{
- * val muxOut = Mux(data_in === UInt(3), UInt(3, 4), UInt(0, 4))
- * }}}
- */
- def apply[T <: Data](cond: Bool, con: T, alt: T): T = macro MuxTransform.apply[T]
-
- def do_apply[T <: Data](cond: Bool, con: T, alt: T)(implicit sourceInfo: SourceInfo): T =
- (con, alt) match {
- // Handle Mux(cond, UInt, Bool) carefully so that the concrete type is UInt
- case (c: Bool, a: Bool) => doMux(cond, c, a).asInstanceOf[T]
- case (c: UInt, a: Bool) => doMux(cond, c, a << 0).asInstanceOf[T]
- case (c: Bool, a: UInt) => doMux(cond, c << 0, a).asInstanceOf[T]
- case (c: Bits, a: Bits) => doMux(cond, c, a).asInstanceOf[T]
- case _ => doAggregateMux(cond, con, alt)
- }
-
- private def doMux[T <: Data](cond: Bool, con: T, alt: T)(implicit sourceInfo: SourceInfo): T = {
- require(con.getClass == alt.getClass, s"can't Mux between ${con.getClass} and ${alt.getClass}")
- val d = alt.cloneTypeWidth(con.width max alt.width)
- pushOp(DefPrim(sourceInfo, d, MultiplexOp, cond.ref, con.ref, alt.ref))
- }
-
- private def doAggregateMux[T <: Data](cond: Bool, con: T, alt: T)(implicit sourceInfo: SourceInfo): T = {
- require(con.getClass == alt.getClass, s"can't Mux between ${con.getClass} and ${alt.getClass}")
- for ((c, a) <- con.flatten zip alt.flatten)
- require(c.width == a.width, "can't Mux between aggregates of different width")
- doMux(cond, con, alt)
- }
-}
-
diff --git a/chiselFrontend/src/main/scala/Chisel/BlackBox.scala b/chiselFrontend/src/main/scala/Chisel/BlackBox.scala
deleted file mode 100644
index b634f021..00000000
--- a/chiselFrontend/src/main/scala/Chisel/BlackBox.scala
+++ /dev/null
@@ -1,55 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-import internal.Builder.pushCommand
-import internal.firrtl.{ModuleIO, DefInvalid}
-import internal.sourceinfo.SourceInfo
-
-/** Defines a black box, which is a module that can be referenced from within
- * Chisel, but is not defined in the emitted Verilog. Useful for connecting
- * to RTL modules defined outside Chisel.
- *
- * @example
- * {{{
- * ... to be written once a spec is finalized ...
- * }}}
- */
-// REVIEW TODO: make Verilog parameters part of the constructor interface?
-abstract class BlackBox extends Module {
- // Don't bother taking override_clock|reset, clock/reset locked out anyway
- // TODO: actually implement this.
- def setVerilogParameters(s: String): Unit = {}
-
- // The body of a BlackBox is empty, the real logic happens in firrtl/Emitter.scala
- // Bypass standard clock, reset, io port declaration by flattening io
- // TODO(twigg): ? Really, overrides are bad, should extend BaseModule....
- override private[Chisel] def ports = io.elements.toSeq
-
- // Do not do reflective naming of internal signals, just name io
- override private[Chisel] def setRefs(): this.type = {
- for ((name, port) <- ports) {
- port.setRef(ModuleIO(this, _namespace.name(name)))
- }
- // setRef is not called on the actual io.
- // There is a risk of user improperly attempting to connect directly with io
- // Long term solution will be to define BlackBox IO differently as part of
- // it not descending from the (current) Module
- this
- }
-
- // Don't setup clock, reset
- // Cann't invalide io in one bunch, must invalidate each part separately
- override private[Chisel] def setupInParent(implicit sourceInfo: SourceInfo): this.type = _parent match {
- case Some(p) => {
- // Just init instance inputs
- for((_,port) <- ports) pushCommand(DefInvalid(sourceInfo, port.ref))
- this
- }
- case None => this
- }
-
- // Using null is horrible but these signals SHOULD NEVER be used:
- override val clock = null
- override val reset = null
-}
diff --git a/chiselFrontend/src/main/scala/Chisel/Data.scala b/chiselFrontend/src/main/scala/Chisel/Data.scala
deleted file mode 100644
index d16843f7..00000000
--- a/chiselFrontend/src/main/scala/Chisel/Data.scala
+++ /dev/null
@@ -1,161 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-import scala.language.experimental.macros
-
-import internal._
-import internal.Builder.pushCommand
-import internal.firrtl._
-import internal.sourceinfo.{SourceInfo, DeprecatedSourceInfo, UnlocatableSourceInfo, WireTransform, SourceInfoTransform}
-
-sealed abstract class Direction(name: String) {
- override def toString: String = name
- def flip: Direction
-}
-object INPUT extends Direction("input") { override def flip: Direction = OUTPUT }
-object OUTPUT extends Direction("output") { override def flip: Direction = INPUT }
-object NO_DIR extends Direction("?") { override def flip: Direction = NO_DIR }
-
-@deprecated("debug doesn't do anything in Chisel3 as no pruning happens in the frontend", "chisel3")
-object debug { // scalastyle:ignore object.name
- def apply (arg: Data): Data = arg
-}
-
-/** Mixing in this trait flips the direction of an Aggregate. */
-trait Flipped extends Data {
- this.overrideDirection(_.flip, !_)
-}
-
-/** This forms the root of the type system for wire data types. The data value
- * must be representable as some number (need not be known at Chisel compile
- * time) of bits, and must have methods to pack / unpack structured data to /
- * from bits.
- */
-abstract class Data(dirArg: Direction) extends HasId {
- def dir: Direction = dirVar
-
- // Sucks this is mutable state, but cloneType doesn't take a Direction arg
- private var isFlipVar = dirArg == INPUT
- private var dirVar = dirArg
- private[Chisel] def isFlip = isFlipVar
-
- private[Chisel] def overrideDirection(newDir: Direction => Direction,
- newFlip: Boolean => Boolean): this.type = {
- this.isFlipVar = newFlip(this.isFlipVar)
- for (field <- this.flatten)
- (field: Data).dirVar = newDir((field: Data).dirVar)
- this
- }
- def asInput: this.type = cloneType.overrideDirection(_ => INPUT, _ => true)
- def asOutput: this.type = cloneType.overrideDirection(_ => OUTPUT, _ => false)
- def flip(): this.type = cloneType.overrideDirection(_.flip, !_)
-
- private[Chisel] def badConnect(that: Data)(implicit sourceInfo: SourceInfo): Unit =
- throwException(s"cannot connect ${this} and ${that}")
- private[Chisel] def connect(that: Data)(implicit sourceInfo: SourceInfo): Unit =
- pushCommand(Connect(sourceInfo, this.lref, that.ref))
- private[Chisel] def bulkConnect(that: Data)(implicit sourceInfo: SourceInfo): Unit =
- pushCommand(BulkConnect(sourceInfo, this.lref, that.lref))
- private[Chisel] def lref: Node = Node(this)
- private[Chisel] def ref: Arg = if (isLit) litArg.get else lref
- private[Chisel] def cloneTypeWidth(width: Width): this.type
- private[Chisel] def toType: String
-
- def := (that: Data)(implicit sourceInfo: SourceInfo): Unit = this badConnect that
-
- def <> (that: Data)(implicit sourceInfo: SourceInfo): Unit = this badConnect that
-
- def cloneType: this.type
- def litArg(): Option[LitArg] = None
- def litValue(): BigInt = litArg.get.num
- def isLit(): Boolean = litArg.isDefined
-
- def width: Width
- final def getWidth: Int = width.get
-
- // While this being in the Data API doesn't really make sense (should be in
- // Aggregate, right?) this is because of an implementation limitation:
- // cloneWithDirection, which is private and defined here, needs flatten to
- // set element directionality.
- // Related: directionality is mutable state. A possible solution for both is
- // to define directionality relative to the container, but these parent links
- // currently don't exist (while this information may be available during
- // FIRRTL emission, it would break directionality querying from Chisel, which
- // does get used).
- private[Chisel] def flatten: IndexedSeq[Bits]
-
- /** Creates an new instance of this type, unpacking the input Bits into
- * structured data.
- *
- * This performs the inverse operation of toBits.
- *
- * @note does NOT assign to the object this is called on, instead creates
- * and returns a NEW object (useful in a clone-and-assign scenario)
- * @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 do_fromBits(that: Bits)(implicit sourceInfo: SourceInfo): this.type = {
- var i = 0
- val wire = Wire(this.cloneType)
- val bits =
- if (that.width.known && that.width.get >= wire.width.get) {
- that
- } else {
- Wire(that.cloneTypeWidth(wire.width), init = that)
- }
- for (x <- wire.flatten) {
- x := bits(i + x.getWidth-1, i)
- i += x.getWidth
- }
- wire.asInstanceOf[this.type]
- }
-
- /** Packs the value of this object as plain Bits.
- *
- * This performs the inverse operation of fromBits(Bits).
- */
- @deprecated("Use asBits, which makes the reinterpret cast more explicit and actually returns Bits", "chisel3")
- def toBits(): UInt = SeqUtils.do_asUInt(this.flatten)(DeprecatedSourceInfo)
-}
-
-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)
-
- // 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 do_apply[T <: Data](t: T, init: T)(implicit sourceInfo: SourceInfo): T = {
- val x = Reg.makeType(t, null.asInstanceOf[T], init)
- pushCommand(DefWire(sourceInfo, x))
- pushCommand(DefInvalid(sourceInfo, x.ref))
- if (init != null) {
- x := init
- }
- x
- }
-}
-
-object Clock {
- def apply(dir: Direction = NO_DIR): Clock = new Clock(dir)
-}
-
-// TODO: Document this.
-sealed class Clock(dirArg: Direction) extends Element(dirArg, Width(1)) {
- def cloneType: this.type = Clock(dirArg).asInstanceOf[this.type]
- private[Chisel] override def flatten: IndexedSeq[Bits] = IndexedSeq()
- private[Chisel] def cloneTypeWidth(width: Width): this.type = cloneType
- private[Chisel] def toType = "Clock"
-
- override def := (that: Data)(implicit sourceInfo: SourceInfo): Unit = that match {
- case _: Clock => this connect that
- case _ => this badConnect that
- }
-}
diff --git a/chiselFrontend/src/main/scala/Chisel/Mem.scala b/chiselFrontend/src/main/scala/Chisel/Mem.scala
deleted file mode 100644
index e34d5499..00000000
--- a/chiselFrontend/src/main/scala/Chisel/Mem.scala
+++ /dev/null
@@ -1,134 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-import scala.language.experimental.macros
-
-import internal._
-import internal.Builder.pushCommand
-import internal.firrtl._
-import internal.sourceinfo.{SourceInfo, DeprecatedSourceInfo, UnlocatableSourceInfo, MemTransform}
-
-object Mem {
- @deprecated("Mem argument order should be size, t; this will be removed by the official release", "chisel3")
- def apply[T <: Data](t: T, size: Int): Mem[T] = do_apply(size, t)(UnlocatableSourceInfo)
-
- /** Creates a combinational-read, sequential-write [[Mem]].
- *
- * @param size number of elements in the memory
- * @param t data type of memory element
- */
- 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): Mem[T] = {
- val mt = t.cloneType
- val mem = new Mem(mt, size)
- pushCommand(DefMemory(sourceInfo, mem, mt, size)) // TODO multi-clock
- mem
- }
-}
-
-sealed abstract class MemBase[T <: Data](t: T, val length: Int) extends HasId with VecLike[T] {
- // REVIEW TODO: make accessors (static/dynamic, read/write) combinations consistent.
-
- /** Creates a read accessor into the memory with static addressing. See the
- * class documentation of the memory for more detailed information.
- */
- def apply(idx: Int): T = apply(UInt(idx))
-
- /** Creates a read/write accessor into the memory with dynamic addressing.
- * See the class documentation of the memory for more detailed information.
- */
- def apply(idx: UInt): T = makePort(UnlocatableSourceInfo, idx, MemPortDirection.INFER)
-
- /** Creates a read accessor into the memory with dynamic addressing. See the
- * class documentation of the memory for more detailed information.
- */
- def read(idx: UInt): T = makePort(UnlocatableSourceInfo, idx, MemPortDirection.READ)
-
- /** Creates a write accessor into the memory.
- *
- * @param idx memory element index to write into
- * @param data new data to write
- */
- def write(idx: UInt, data: T): Unit = {
- implicit val sourceInfo = UnlocatableSourceInfo
- makePort(UnlocatableSourceInfo, idx, MemPortDirection.WRITE) := data
- }
-
- /** Creates a masked write accessor into the memory.
- *
- * @param idx memory element index to write into
- * @param data new data to write
- * @param mask write mask as a Vec of Bool: a write to the Vec element in
- * memory is only performed if the corresponding mask index is true.
- *
- * @note this is only allowed if the memory's element data type is a Vec
- */
- def write(idx: UInt, data: T, mask: Seq[Bool]) (implicit evidence: T <:< Vec[_]): Unit = {
- implicit val sourceInfo = UnlocatableSourceInfo
- val accessor = makePort(sourceInfo, idx, MemPortDirection.WRITE).asInstanceOf[Vec[Data]]
- val dataVec = data.asInstanceOf[Vec[Data]]
- if (accessor.length != dataVec.length) {
- Builder.error(s"Mem write data must contain ${accessor.length} elements (found ${dataVec.length})")
- }
- if (accessor.length != mask.length) {
- Builder.error(s"Mem write mask must contain ${accessor.length} elements (found ${mask.length})")
- }
- for (((cond, port), datum) <- mask zip accessor zip dataVec)
- when (cond) { port := datum }
- }
-
- private def makePort(sourceInfo: SourceInfo, idx: UInt, dir: MemPortDirection): T =
- pushCommand(DefMemPort(sourceInfo,
- t.cloneType, Node(this), dir, idx.ref, Node(idx._parent.get.clock))).id
-}
-
-/** A combinational-read, sequential-write memory.
- *
- * Writes take effect on the rising clock edge after the request. Reads are
- * combinational (requests will return data on the same cycle).
- * Read-after-write hazards are not an issue.
- *
- * @note when multiple conflicting writes are performed on a Mem element, the
- * result is undefined (unlike Vec, where the last assignment wins)
- */
-sealed class Mem[T <: Data](t: T, length: Int) extends MemBase(t, length)
-
-object SeqMem {
- @deprecated("SeqMem argument order should be size, t; this will be removed by the official release", "chisel3")
- def apply[T <: Data](t: T, size: Int): SeqMem[T] = do_apply(size, t)(DeprecatedSourceInfo)
-
- /** Creates a sequential-read, sequential-write [[SeqMem]].
- *
- * @param size number of elements in the memory
- * @param t data type of memory element
- */
- def apply[T <: Data](size: Int, t: T): SeqMem[T] = macro MemTransform.apply[T]
-
- def do_apply[T <: Data](size: Int, t: T)(implicit sourceInfo: SourceInfo): SeqMem[T] = {
- val mt = t.cloneType
- val mem = new SeqMem(mt, size)
- pushCommand(DefSeqMemory(sourceInfo, mem, mt, size)) // TODO multi-clock
- mem
- }
-}
-
-/** A sequential-read, sequential-write memory.
- *
- * Writes take effect on the rising clock edge after the request. Reads return
- * data on the rising edge after the request. Read-after-write behavior (when
- * a read and write to the same address are requested on the same cycle) is
- * undefined.
- *
- * @note when multiple conflicting writes are performed on a Mem element, the
- * result is undefined (unlike Vec, where the last assignment wins)
- */
-sealed class SeqMem[T <: Data](t: T, n: Int) extends MemBase[T](t, n) {
- def read(addr: UInt, enable: Bool): T = {
- implicit val sourceInfo = UnlocatableSourceInfo
- val a = Wire(UInt())
- when (enable) { a := addr }
- read(a)
- }
-}
diff --git a/chiselFrontend/src/main/scala/Chisel/Module.scala b/chiselFrontend/src/main/scala/Chisel/Module.scala
deleted file mode 100644
index e2101538..00000000
--- a/chiselFrontend/src/main/scala/Chisel/Module.scala
+++ /dev/null
@@ -1,119 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-import scala.collection.mutable.{ArrayBuffer, HashSet}
-import scala.language.experimental.macros
-
-import internal._
-import internal.Builder.pushCommand
-import internal.Builder.dynamicContext
-import internal.firrtl._
-import internal.sourceinfo.{SourceInfo, InstTransform, UnlocatableSourceInfo}
-
-object Module {
- /** A wrapper method that all Module instantiations must be wrapped in
- * (necessary to help Chisel track internal state).
- *
- * @param m the Module being created
- *
- * @return the input module `m` with Chisel metadata properly set
- */
- def apply[T <: Module](bc: => T): T = macro InstTransform.apply[T]
-
- def do_apply[T <: Module](bc: => T)(implicit sourceInfo: SourceInfo): T = {
- // Don't generate source info referencing parents inside a module, sincce this interferes with
- // module de-duplication in FIRRTL emission.
- val childSourceInfo = UnlocatableSourceInfo
-
- val parent = dynamicContext.currentModule
- val m = bc.setRefs()
- m._commands.prepend(DefInvalid(childSourceInfo, m.io.ref)) // init module outputs
- dynamicContext.currentModule = parent
- val ports = m.computePorts
- Builder.components += Component(m, m.name, ports, m._commands)
- pushCommand(DefInstance(sourceInfo, m, ports))
- m.setupInParent(childSourceInfo)
- }
-}
-
-/** Abstract base class for Modules, which behave much like Verilog modules.
- * These may contain both logic and state which are written in the Module
- * body (constructor).
- *
- * @note Module instantiations must be wrapped in a Module() call.
- */
-abstract class Module(
- override_clock: Option[Clock]=None, override_reset: Option[Bool]=None)
-extends HasId {
- // _clock and _reset can be clock and reset in these 2ary constructors
- // once chisel2 compatibility issues are resolved
- def this(_clock: Clock) = this(Option(_clock), None)
- def this(_reset: Bool) = this(None, Option(_reset))
- def this(_clock: Clock, _reset: Bool) = this(Option(_clock), Option(_reset))
-
- private[Chisel] val _namespace = Builder.globalNamespace.child
- private[Chisel] val _commands = ArrayBuffer[Command]()
- private[Chisel] val _ids = ArrayBuffer[HasId]()
- dynamicContext.currentModule = Some(this)
-
- /** Name of the instance. */
- val name = Builder.globalNamespace.name(getClass.getName.split('.').last)
-
- /** IO for this Module. At the Scala level (pre-FIRRTL transformations),
- * connections in and out of a Module may only go through `io` elements.
- */
- def io: Bundle
- val clock = Clock(INPUT)
- val reset = Bool(INPUT)
-
- private[Chisel] def addId(d: HasId) { _ids += d }
-
- private[Chisel] def ports: Seq[(String,Data)] = Vector(
- ("clk", clock), ("reset", reset), ("io", io)
- )
-
- private[Chisel] def computePorts = for((name, port) <- ports) yield {
- val bundleDir = if (port.isFlip) INPUT else OUTPUT
- Port(port, if (port.dir == NO_DIR) bundleDir else port.dir)
- }
-
- private[Chisel] def setupInParent(implicit sourceInfo: SourceInfo): this.type = {
- _parent match {
- case Some(p) => {
- pushCommand(DefInvalid(sourceInfo, io.ref)) // init instance inputs
- clock := override_clock.getOrElse(p.clock)
- reset := override_reset.getOrElse(p.reset)
- this
- }
- case None => this
- }
- }
-
- private[Chisel] def setRefs(): this.type = {
- for ((name, port) <- ports) {
- port.setRef(ModuleIO(this, _namespace.name(name)))
- }
-
- // Suggest names to nodes using runtime reflection
- val valNames = HashSet[String](getClass.getDeclaredFields.map(_.getName):_*)
- def isPublicVal(m: java.lang.reflect.Method) =
- m.getParameterTypes.isEmpty && valNames.contains(m.getName)
- val methods = getClass.getMethods.sortWith(_.getName > _.getName)
- for (m <- methods; if isPublicVal(m)) m.invoke(this) match {
- case (id: HasId) => id.suggestName(m.getName)
- case _ =>
- }
-
- // For Module instances we haven't named, suggest the name of the Module
- _ids foreach {
- case m: Module => m.suggestName(m.name)
- case _ =>
- }
-
- // All suggestions are in, force names to every node.
- _ids.foreach(_.forceName(default="T", _namespace))
- _ids.foreach(_._onModuleClose)
- this
- }
-}
diff --git a/chiselFrontend/src/main/scala/Chisel/Printf.scala b/chiselFrontend/src/main/scala/Chisel/Printf.scala
deleted file mode 100644
index f068f637..00000000
--- a/chiselFrontend/src/main/scala/Chisel/Printf.scala
+++ /dev/null
@@ -1,36 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-import scala.language.experimental.macros
-
-import internal._
-import internal.Builder.pushCommand
-import internal.firrtl._
-import internal.sourceinfo.SourceInfo
-
-object printf { // scalastyle:ignore object.name
- /** Prints a message in simulation.
- *
- * Does not fire when in reset (defined as the encapsulating Module's
- * reset). If your definition of reset is not the encapsulating Module's
- * reset, you will need to gate this externally.
- *
- * May be called outside of a Module (like defined in a function), so
- * functions using printf make the standard Module assumptions (single clock
- * and single reset).
- *
- * @param fmt printf format string
- * @param data format string varargs containing data to print
- */
- def apply(fmt: String, data: Bits*)(implicit sourceInfo: SourceInfo) {
- when (!(Builder.dynamicContext.currentModule.get.reset)) {
- printfWithoutReset(fmt, data:_*)
- }
- }
-
- private[Chisel] def printfWithoutReset(fmt: String, data: Bits*)(implicit sourceInfo: SourceInfo) {
- val clock = Builder.dynamicContext.currentModule.get.clock
- pushCommand(Printf(sourceInfo, Node(clock), fmt, data.map((d: Bits) => d.ref)))
- }
-}
diff --git a/chiselFrontend/src/main/scala/Chisel/Reg.scala b/chiselFrontend/src/main/scala/Chisel/Reg.scala
deleted file mode 100644
index c8faa5c9..00000000
--- a/chiselFrontend/src/main/scala/Chisel/Reg.scala
+++ /dev/null
@@ -1,71 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-import internal._
-import internal.Builder.pushCommand
-import internal.firrtl._
-import internal.sourceinfo.{SourceInfo, UnlocatableSourceInfo}
-
-object Reg {
- private[Chisel] def makeType[T <: Data](t: T = null, next: T = null, init: T = null): T = {
- if (t ne null) {
- t.cloneType
- } else if (next ne null) {
- next.cloneTypeWidth(Width())
- } 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.cloneType
- case _ => init.cloneTypeWidth(Width())
- }
- } else {
- throwException("cannot infer type")
- }
- }
-
- /** Creates a register with optional next and initialization values.
- *
- * @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]`.
- */
- def apply[T <: Data](t: T = null, next: T = null, init: T = null): T =
- // Scala macros can't (yet) handle named or default arguments.
- do_apply(t, next, init)(UnlocatableSourceInfo)
-
- /** Creates a register without initialization (reset is ignored). Value does
- * not change unless assigned to (using the := operator).
- *
- * @param outType: data type for the register
- */
- def apply[T <: Data](outType: T): T = Reg[T](outType, null.asInstanceOf[T], null.asInstanceOf[T])
-
- def do_apply[T <: Data](t: T, next: T, init: T)(implicit sourceInfo: SourceInfo): 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(t, next, init)
- val clock = Node(x._parent.get.clock) // TODO multi-clock
- if (init == null) {
- pushCommand(DefReg(sourceInfo, x, clock))
- } else {
- pushCommand(DefRegInit(sourceInfo, x, clock, Node(x._parent.get.reset), init.ref))
- }
- if (next != null) {
- x := next
- }
- x
- }
-}
diff --git a/chiselFrontend/src/main/scala/Chisel/SeqUtils.scala b/chiselFrontend/src/main/scala/Chisel/SeqUtils.scala
deleted file mode 100644
index 9a15fd5f..00000000
--- a/chiselFrontend/src/main/scala/Chisel/SeqUtils.scala
+++ /dev/null
@@ -1,59 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-import scala.language.experimental.macros
-
-import internal.sourceinfo.{SourceInfo, SourceInfoTransform}
-
-private[Chisel] object SeqUtils {
- /** Equivalent to Cat(r(n-1), ..., r(0)) */
- def asUInt[T <: Bits](in: Seq[T]): UInt = macro SourceInfoTransform.inArg
-
- def do_asUInt[T <: Bits](in: Seq[T])(implicit sourceInfo: SourceInfo): UInt = {
- if (in.tail.isEmpty) {
- in.head.asUInt
- } else {
- val left = asUInt(in.slice(0, in.length/2))
- val right = asUInt(in.slice(in.length/2, in.length))
- right ## left
- }
- }
-
- /** Counts the number of true Bools in a Seq */
- def count(in: Seq[Bool]): UInt = macro SourceInfoTransform.inArg
-
- def do_count(in: Seq[Bool])(implicit sourceInfo: SourceInfo): UInt = {
- if (in.size == 0) {
- UInt(0)
- } else if (in.size == 1) {
- in.head
- } else {
- count(in.slice(0, in.size/2)) + (UInt(0) ## count(in.slice(in.size/2, in.size)))
- }
- }
-
- /** Returns data value corresponding to first true predicate */
- def priorityMux[T <: Data](in: Seq[(Bool, T)]): T = macro SourceInfoTransform.inArg
-
- def do_priorityMux[T <: Data](in: Seq[(Bool, T)])(implicit sourceInfo: SourceInfo): T = {
- if (in.size == 1) {
- in.head._2
- } else {
- Mux(in.head._1, in.head._2, priorityMux(in.tail))
- }
- }
-
- /** Returns data value corresponding to lone true predicate */
- def oneHotMux[T <: Data](in: Iterable[(Bool, T)]): T = macro SourceInfoTransform.inArg
-
- def do_oneHotMux[T <: Data](in: Iterable[(Bool, T)])(implicit sourceInfo: SourceInfo): T = {
- if (in.tail.isEmpty) {
- in.head._2
- } else {
- val masked = for ((s, i) <- in) yield Mux(s, i.toBits, Bits(0))
- val width = in.map(_._2.width).reduce(_ max _)
- in.head._2.cloneTypeWidth(width).fromBits(masked.reduceLeft(_|_))
- }
- }
-}
diff --git a/chiselFrontend/src/main/scala/Chisel/When.scala b/chiselFrontend/src/main/scala/Chisel/When.scala
deleted file mode 100644
index 90b3d1a5..00000000
--- a/chiselFrontend/src/main/scala/Chisel/When.scala
+++ /dev/null
@@ -1,59 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-import scala.language.experimental.macros
-
-import internal._
-import internal.Builder.pushCommand
-import internal.firrtl._
-import internal.sourceinfo.{SourceInfo}
-
-object when { // scalastyle:ignore object.name
- /** Create a `when` condition block, where whether a block of logic is
- * executed or not depends on the conditional.
- *
- * @param cond condition to execute upon
- * @param block logic that runs only if `cond` is true
- *
- * @example
- * {{{
- * when ( myData === UInt(3) ) {
- * // Some logic to run when myData equals 3.
- * } .elsewhen ( myData === UInt(1) ) {
- * // Some logic to run when myData equals 1.
- * } .otherwise {
- * // Some logic to run when myData is neither 3 nor 1.
- * }
- * }}}
- */
- def apply(cond: Bool)(block: => Unit)(implicit sourceInfo: SourceInfo): WhenContext = {
- new WhenContext(sourceInfo, cond, !cond, block)
- }
-}
-
-/** Internal mechanism for generating a when. Because of the way FIRRTL
- * commands are emitted, generating a FIRRTL elsewhen or nested whens inside
- * elses would be difficult. Instead, this keeps track of the negative of the
- * previous conditions, so when an elsewhen or otherwise is used, it checks
- * that both the condition is true and all the previous conditions have been
- * false.
- */
-final class WhenContext(sourceInfo: SourceInfo, cond: Bool, prevCond: => Bool, block: => Unit) {
- /** This block of logic gets executed if above conditions have been false
- * and this condition is true.
- */
- def elsewhen (elseCond: Bool)(block: => Unit)(implicit sourceInfo: SourceInfo): WhenContext = {
- new WhenContext(sourceInfo, prevCond && elseCond, prevCond && !elseCond, block)
- }
-
- /** This block of logic gets executed only if the above conditions were all
- * false. No additional logic blocks may be appended past the `otherwise`.
- */
- def otherwise(block: => Unit)(implicit sourceInfo: SourceInfo): Unit =
- new WhenContext(sourceInfo, prevCond, null, block)
-
- pushCommand(WhenBegin(sourceInfo, cond.ref))
- block
- pushCommand(WhenEnd(sourceInfo))
-}
diff --git a/chiselFrontend/src/main/scala/Chisel/internal/Builder.scala b/chiselFrontend/src/main/scala/Chisel/internal/Builder.scala
deleted file mode 100644
index d0e28b7c..00000000
--- a/chiselFrontend/src/main/scala/Chisel/internal/Builder.scala
+++ /dev/null
@@ -1,123 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel.internal
-
-import scala.util.DynamicVariable
-import scala.collection.mutable.{ArrayBuffer, HashMap}
-
-import Chisel._
-import Chisel.internal.firrtl._
-
-private[Chisel] class Namespace(parent: Option[Namespace], keywords: Set[String]) {
- private var i = 0L
- private val names = collection.mutable.HashSet[String]()
-
- private def rename(n: String) = { i += 1; s"${n}_${i}" }
-
- def contains(elem: String): Boolean = {
- keywords.contains(elem) || names.contains(elem) ||
- parent.map(_ contains elem).getOrElse(false)
- }
-
- def name(elem: String): String = {
- if (this contains elem) {
- name(rename(elem))
- } else {
- names += elem
- elem
- }
- }
-
- def child(kws: Set[String]): Namespace = new Namespace(Some(this), kws)
- def child: Namespace = child(Set())
-}
-
-private[Chisel] class IdGen {
- private var counter = -1L
- def next: Long = {
- counter += 1
- counter
- }
-}
-
-private[Chisel] trait HasId {
- private[Chisel] def _onModuleClose {} // scalastyle:ignore method.name
- private[Chisel] val _parent = Builder.dynamicContext.currentModule
- _parent.foreach(_.addId(this))
-
- private[Chisel] val _id = Builder.idGen.next
- override def hashCode: Int = _id.toInt
- override def equals(that: Any): Boolean = that match {
- case x: HasId => _id == x._id
- case _ => false
- }
-
- // Facilities for 'suggesting' a name to this.
- // Post-name hooks called to carry the suggestion to other candidates as needed
- private var suggested_name: Option[String] = None
- private val postname_hooks = scala.collection.mutable.ListBuffer.empty[String=>Unit]
- // Only takes the first suggestion!
- def suggestName(name: =>String): this.type = {
- if(suggested_name.isEmpty) suggested_name = Some(name)
- for(hook <- postname_hooks) { hook(name) }
- this
- }
- private[Chisel] def addPostnameHook(hook: String=>Unit): Unit = postname_hooks += hook
-
- // Uses a namespace to convert suggestion into a true name
- // Will not do any naming if the reference already assigned.
- // (e.g. tried to suggest a name to part of a Bundle)
- private[Chisel] def forceName(default: =>String, namespace: Namespace): Unit =
- if(_ref.isEmpty) {
- val candidate_name = suggested_name.getOrElse(default)
- val available_name = namespace.name(candidate_name)
- setRef(Ref(available_name))
- }
-
- private var _ref: Option[Arg] = None
- private[Chisel] def setRef(imm: Arg): Unit = _ref = Some(imm)
- private[Chisel] def setRef(parent: HasId, name: String): Unit = setRef(Slot(Node(parent), name))
- private[Chisel] def setRef(parent: HasId, index: Int): Unit = setRef(Index(Node(parent), ILit(index)))
- private[Chisel] def setRef(parent: HasId, index: UInt): Unit = setRef(Index(Node(parent), index.ref))
- private[Chisel] def getRef: Arg = _ref.get
-}
-
-private[Chisel] class DynamicContext {
- val idGen = new IdGen
- val globalNamespace = new Namespace(None, Set())
- val components = ArrayBuffer[Component]()
- var currentModule: Option[Module] = None
- val errors = new ErrorLog
-}
-
-private[Chisel] object Builder {
- // All global mutable state must be referenced via dynamicContextVar!!
- private val dynamicContextVar = new DynamicVariable[Option[DynamicContext]](None)
-
- def dynamicContext: DynamicContext =
- dynamicContextVar.value getOrElse (new DynamicContext)
- def idGen: IdGen = dynamicContext.idGen
- def globalNamespace: Namespace = dynamicContext.globalNamespace
- def components: ArrayBuffer[Component] = dynamicContext.components
-
- def pushCommand[T <: Command](c: T): T = {
- dynamicContext.currentModule.foreach(_._commands += c)
- c
- }
- def pushOp[T <: Data](cmd: DefPrim[T]): T = pushCommand(cmd).id
-
- def errors: ErrorLog = dynamicContext.errors
- def error(m: => String): Unit = errors.error(m)
-
- def build[T <: Module](f: => T): Circuit = {
- dynamicContextVar.withValue(Some(new DynamicContext)) {
- errors.info("Elaborating design...")
- val mod = f
- mod.forceName(mod.name, globalNamespace)
- errors.checkpoint()
- errors.info("Done elaborating.")
-
- Circuit(components.last.name, components)
- }
- }
-}
diff --git a/chiselFrontend/src/main/scala/Chisel/internal/Error.scala b/chiselFrontend/src/main/scala/Chisel/internal/Error.scala
deleted file mode 100644
index 6c4c0880..00000000
--- a/chiselFrontend/src/main/scala/Chisel/internal/Error.scala
+++ /dev/null
@@ -1,91 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel.internal
-
-import scala.collection.mutable.ArrayBuffer
-
-import Chisel._
-
-class ChiselException(message: String, cause: Throwable) extends Exception(message, cause)
-
-private[Chisel] object throwException {
- def apply(s: String, t: Throwable = null): Nothing =
- throw new ChiselException(s, t)
-}
-
-/** Records and reports runtime errors and warnings. */
-private[Chisel] class ErrorLog {
- def hasErrors: Boolean = errors.exists(_.isFatal)
-
- /** Log an error message */
- def error(m: => String): Unit =
- errors += new Error(m, getUserLineNumber)
-
- /** Log a warning message */
- def warning(m: => String): Unit =
- errors += new Warning(m, getUserLineNumber)
-
- /** Emit an informational message */
- def info(m: String): Unit =
- println(new Info("[%2.3f] %s".format(elapsedTime/1e3, m), None)) // scalastyle:ignore regex
-
- /** Prints error messages generated by Chisel at runtime. */
- def report(): Unit = errors foreach println // scalastyle:ignore regex
-
- /** Throw an exception if any errors have yet occurred. */
- def checkpoint(): Unit = if(hasErrors) {
- import Console._
- throwException(errors.map(_ + "\n").reduce(_ + _) +
- UNDERLINED + "CODE HAS " + errors.filter(_.isFatal).length + RESET +
- UNDERLINED + " " + RED + "ERRORS" + RESET +
- UNDERLINED + " and " + errors.filterNot(_.isFatal).length + RESET +
- UNDERLINED + " " + YELLOW + "WARNINGS" + RESET)
- }
-
- private def findFirstUserFrame(stack: Array[StackTraceElement]): Option[StackTraceElement] = {
- def isUserCode(ste: StackTraceElement): Boolean = {
- def isUserModule(c: Class[_]): Boolean =
- c != null && (c == classOf[Module] || isUserModule(c.getSuperclass))
- isUserModule(Class.forName(ste.getClassName))
- }
-
- stack.indexWhere(isUserCode) match {
- case x if x < 0 => None
- case x => Some(stack(x))
- }
- }
-
- private def getUserLineNumber =
- findFirstUserFrame(Thread.currentThread().getStackTrace)
-
- private val errors = ArrayBuffer[LogEntry]()
-
- private val startTime = System.currentTimeMillis
- private def elapsedTime: Long = System.currentTimeMillis - startTime
-}
-
-private abstract class LogEntry(msg: => String, line: Option[StackTraceElement]) {
- def isFatal: Boolean = false
- def format: String
-
- override def toString: String = line match {
- case Some(l) => s"${format} ${l.getFileName}:${l.getLineNumber}: ${msg} in class ${l.getClassName}"
- case None => s"${format} ${msg}"
- }
-
- protected def tag(name: String, color: String): String =
- s"[${color}${name}${Console.RESET}]"
-}
-
-private class Error(msg: => String, line: Option[StackTraceElement]) extends LogEntry(msg, line) {
- override def isFatal: Boolean = true
- def format: String = tag("error", Console.RED)
-}
-
-private class Warning(msg: => String, line: Option[StackTraceElement]) extends LogEntry(msg, line) {
- def format: String = tag("warn", Console.YELLOW)
-}
-
-private class Info(msg: => String, line: Option[StackTraceElement]) extends LogEntry(msg, line) {
- def format: String = tag("info", Console.MAGENTA)
-}
diff --git a/chiselFrontend/src/main/scala/Chisel/internal/SourceInfo.scala b/chiselFrontend/src/main/scala/Chisel/internal/SourceInfo.scala
deleted file mode 100644
index 66bfc7a4..00000000
--- a/chiselFrontend/src/main/scala/Chisel/internal/SourceInfo.scala
+++ /dev/null
@@ -1,51 +0,0 @@
-// See LICENSE for license details.
-
-// This file contains macros for adding source locators at the point of invocation.
-//
-// This is not part of coreMacros to disallow this macro from being implicitly invoked in Chisel
-// frontend (and generating source locators in Chisel core), which is almost certainly a bug.
-//
-// Note: While these functions and definitions are not private (macros can't be
-// private), these are NOT meant to be part of the public API (yet) and no
-// forward compatibility guarantees are made.
-// A future revision may stabilize the source locator API to allow library
-// writers to append source locator information at the point of a library
-// function invocation.
-
-package Chisel.internal.sourceinfo
-
-import scala.language.experimental.macros
-import scala.reflect.macros.blackbox.Context
-
-/** Abstract base class for generalized source information.
- */
-sealed trait SourceInfo
-
-sealed trait NoSourceInfo extends SourceInfo
-
-/** For when source info can't be generated because of a technical limitation, like for Reg because
- * Scala macros don't support named or default arguments.
- */
-case object UnlocatableSourceInfo extends NoSourceInfo
-
-/** For when source info isn't generated because the function is deprecated and we're lazy.
- */
-case object DeprecatedSourceInfo extends NoSourceInfo
-
-/** For FIRRTL lines from a Scala source line.
- */
-case class SourceLine(filename: String, line: Int, col: Int) extends SourceInfo
-
-/** Provides a macro that returns the source information at the invocation point.
- */
-object SourceInfoMacro {
- def generate_source_info(c: Context): c.Tree = {
- import c.universe._
- val p = c.enclosingPosition
- q"_root_.Chisel.internal.sourceinfo.SourceLine(${p.source.file.name}, ${p.line}, ${p.column})"
- }
-}
-
-object SourceInfo {
- implicit def materialize: SourceInfo = macro SourceInfoMacro.generate_source_info
-}
diff --git a/chiselFrontend/src/main/scala/Chisel/internal/firrtl/IR.scala b/chiselFrontend/src/main/scala/Chisel/internal/firrtl/IR.scala
deleted file mode 100644
index 62784cee..00000000
--- a/chiselFrontend/src/main/scala/Chisel/internal/firrtl/IR.scala
+++ /dev/null
@@ -1,188 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel.internal.firrtl
-import Chisel._
-import Chisel.internal._
-import Chisel.internal.sourceinfo.{SourceInfo, NoSourceInfo}
-
-case class PrimOp(val name: String) {
- override def toString: String = name
-}
-
-object PrimOp {
- val AddOp = PrimOp("add")
- val SubOp = PrimOp("sub")
- val TailOp = PrimOp("tail")
- val HeadOp = PrimOp("head")
- val TimesOp = PrimOp("mul")
- val DivideOp = PrimOp("div")
- val RemOp = PrimOp("rem")
- val ShiftLeftOp = PrimOp("shl")
- val ShiftRightOp = PrimOp("shr")
- val DynamicShiftLeftOp = PrimOp("dshl")
- val DynamicShiftRightOp = PrimOp("dshr")
- val BitAndOp = PrimOp("and")
- val BitOrOp = PrimOp("or")
- val BitXorOp = PrimOp("xor")
- val BitNotOp = PrimOp("not")
- val ConcatOp = PrimOp("cat")
- val BitsExtractOp = PrimOp("bits")
- val LessOp = PrimOp("lt")
- val LessEqOp = PrimOp("leq")
- val GreaterOp = PrimOp("gt")
- val GreaterEqOp = PrimOp("geq")
- val EqualOp = PrimOp("eq")
- val PadOp = PrimOp("pad")
- val NotEqualOp = PrimOp("neq")
- val NegOp = PrimOp("neg")
- val MultiplexOp = PrimOp("mux")
- val XorReduceOp = PrimOp("xorr")
- val ConvertOp = PrimOp("cvt")
- val AsUIntOp = PrimOp("asUInt")
- val AsSIntOp = PrimOp("asSInt")
-}
-
-abstract class Arg {
- def fullName(ctx: Component): String = name
- def name: String
-}
-
-case class Node(id: HasId) extends Arg {
- override def fullName(ctx: Component): String = id.getRef.fullName(ctx)
- def name: String = id.getRef.name
-}
-
-abstract class LitArg(val num: BigInt, widthArg: Width) extends Arg {
- private[Chisel] def forcedWidth = widthArg.known
- private[Chisel] def width: Width = if (forcedWidth) widthArg else Width(minWidth)
-
- protected def minWidth: Int
- if (forcedWidth) {
- require(widthArg.get >= minWidth,
- s"The literal value ${num} was elaborated with a specificed width of ${widthArg.get} bits, but at least ${minWidth} bits are required.")
- }
-}
-
-case class ILit(n: BigInt) extends Arg {
- def name: String = n.toString
-}
-
-case class ULit(n: BigInt, w: Width) extends LitArg(n, w) {
- def name: String = "UInt" + width + "(\"h0" + num.toString(16) + "\")"
- def minWidth: Int = 1 max n.bitLength
-
- require(n >= 0, s"UInt literal ${n} is negative")
-}
-
-case class SLit(n: BigInt, w: Width) extends LitArg(n, w) {
- def name: String = {
- val unsigned = if (n < 0) (BigInt(1) << width.get) + n else n
- s"asSInt(${ULit(unsigned, width).name})"
- }
- def minWidth: Int = 1 + n.bitLength
-}
-
-case class Ref(name: String) extends Arg
-case class ModuleIO(mod: Module, name: String) extends Arg {
- override def fullName(ctx: Component): String =
- if (mod eq ctx.id) name else s"${mod.getRef.name}.$name"
-}
-case class Slot(imm: Node, name: String) extends Arg {
- override def fullName(ctx: Component): String =
- if (imm.fullName(ctx).isEmpty) name else s"${imm.fullName(ctx)}.${name}"
-}
-case class Index(imm: Arg, value: Arg) extends Arg {
- def name: String = s"[$value]"
- override def fullName(ctx: Component): String = s"${imm.fullName(ctx)}[${value.fullName(ctx)}]"
-}
-
-object Width {
- def apply(x: Int): Width = KnownWidth(x)
- def apply(): Width = UnknownWidth()
-}
-
-sealed abstract class Width {
- type W = Int
- def max(that: Width): Width = this.op(that, _ max _)
- def + (that: Width): Width = this.op(that, _ + _)
- def + (that: Int): Width = this.op(this, (a, b) => a + that)
- def shiftRight(that: Int): Width = this.op(this, (a, b) => 0 max (a - that))
- def dynamicShiftLeft(that: Width): Width =
- this.op(that, (a, b) => a + (1 << b) - 1)
-
- def known: Boolean
- def get: W
- protected def op(that: Width, f: (W, W) => W): Width
-}
-
-sealed case class UnknownWidth() extends Width {
- def known: Boolean = false
- def get: Int = None.get
- def op(that: Width, f: (W, W) => W): Width = this
- override def toString: String = ""
-}
-
-sealed case class KnownWidth(value: Int) extends Width {
- require(value >= 0)
- def known: Boolean = true
- def get: Int = value
- def op(that: Width, f: (W, W) => W): Width = that match {
- case KnownWidth(x) => KnownWidth(f(value, x))
- case _ => that
- }
- override def toString: String = s"<${value.toString}>"
-}
-
-sealed abstract class MemPortDirection(name: String) {
- override def toString: String = name
-}
-object MemPortDirection {
- object READ extends MemPortDirection("read")
- object WRITE extends MemPortDirection("write")
- object RDWR extends MemPortDirection("rdwr")
- object INFER extends MemPortDirection("infer")
-}
-
-abstract class Command {
- def sourceInfo: SourceInfo
-}
-abstract class Definition extends Command {
- def id: HasId
- def name: String = id.getRef.name
-}
-case class DefPrim[T <: Data](sourceInfo: SourceInfo, id: T, op: PrimOp, args: Arg*) extends Definition
-case class DefInvalid(sourceInfo: SourceInfo, arg: Arg) extends Command
-case class DefWire(sourceInfo: SourceInfo, id: Data) extends Definition
-case class DefReg(sourceInfo: SourceInfo, id: Data, clock: Arg) extends Definition
-case class DefRegInit(sourceInfo: SourceInfo, id: Data, clock: Arg, reset: Arg, init: Arg) extends Definition
-case class DefMemory(sourceInfo: SourceInfo, id: HasId, t: Data, size: Int) extends Definition
-case class DefSeqMemory(sourceInfo: SourceInfo, id: HasId, t: Data, size: Int) extends Definition
-case class DefMemPort[T <: Data](sourceInfo: SourceInfo, id: T, source: Node, dir: MemPortDirection, index: Arg, clock: Arg) extends Definition
-case class DefInstance(sourceInfo: SourceInfo, id: Module, ports: Seq[Port]) extends Definition
-case class WhenBegin(sourceInfo: SourceInfo, pred: Arg) extends Command
-case class WhenEnd(sourceInfo: SourceInfo) extends Command
-case class Connect(sourceInfo: SourceInfo, loc: Node, exp: Arg) extends Command
-case class BulkConnect(sourceInfo: SourceInfo, loc1: Node, loc2: Node) extends Command
-case class ConnectInit(sourceInfo: SourceInfo, loc: Node, exp: Arg) extends Command
-case class Stop(sourceInfo: SourceInfo, clk: Arg, ret: Int) extends Command
-case class Component(id: Module, name: String, ports: Seq[Port], commands: Seq[Command]) extends Arg
-case class Port(id: Data, dir: Direction)
-case class Printf(sourceInfo: SourceInfo, clk: Arg, formatIn: String, ids: Seq[Arg]) extends Command {
- require(formatIn.forall(c => c.toInt > 0 && c.toInt < 128), "format strings must comprise non-null ASCII values")
- def format: String = {
- def escaped(x: Char) = {
- require(x.toInt >= 0)
- if (x == '"' || x == '\\') {
- s"\\${x}"
- } else if (x == '\n') {
- "\\n"
- } else {
- require(x.toInt >= 32) // TODO \xNN once FIRRTL issue #59 is resolved
- x
- }
- }
- formatIn.map(escaped _).mkString
- }
-}
-
-case class Circuit(name: String, components: Seq[Component])