summaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorducky2016-05-05 11:50:39 -0700
committerducky2016-05-05 11:50:39 -0700
commit9036d96bb032c19de31131f2296120e708cbc3dc (patch)
treecf17173fab309b09670ca7529680e09d61341451 /src/main
parent623a301df1f5a1954f8e4a64ef97c99c3900da28 (diff)
Move Chisel API into separate chiselFrontend compilation unit in preparation for source locator macros
Diffstat (limited to 'src/main')
-rw-r--r--src/main/scala/Chisel/Aggregate.scala342
-rw-r--r--src/main/scala/Chisel/BitPat.scala80
-rw-r--r--src/main/scala/Chisel/Bits.scala571
-rw-r--r--src/main/scala/Chisel/BlackBox.scala54
-rw-r--r--src/main/scala/Chisel/CoreUtil.scala97
-rw-r--r--src/main/scala/Chisel/Data.scala152
-rw-r--r--src/main/scala/Chisel/Mem.scala123
-rw-r--r--src/main/scala/Chisel/Module.scala103
-rw-r--r--src/main/scala/Chisel/Reg.scala66
-rw-r--r--src/main/scala/Chisel/SeqUtils.scala47
-rw-r--r--src/main/scala/Chisel/When.scala56
-rw-r--r--src/main/scala/Chisel/internal/Builder.scala122
-rw-r--r--src/main/scala/Chisel/internal/Error.scala91
-rw-r--r--src/main/scala/Chisel/internal/firrtl/Emitter.scala101
-rw-r--r--src/main/scala/Chisel/internal/firrtl/IR.scala187
15 files changed, 0 insertions, 2192 deletions
diff --git a/src/main/scala/Chisel/Aggregate.scala b/src/main/scala/Chisel/Aggregate.scala
deleted file mode 100644
index 4d35e2f0..00000000
--- a/src/main/scala/Chisel/Aggregate.scala
+++ /dev/null
@@ -1,342 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-import scala.collection.immutable.ListMap
-import scala.collection.mutable.{ArrayBuffer, HashSet, LinkedHashMap}
-
-import internal._
-import internal.Builder.pushCommand
-import internal.firrtl._
-
-/** 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] = {
- // 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] =
- 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] =
- 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] = 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): 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]): Unit = this := that
-
- // TODO: eliminate once assign(Seq) isn't ambiguous with assign(Data) since Vec extends Seq and Data
- def <> (that: Vec[T]): Unit = this := that.asInstanceOf[Data]
-
- override def := (that: Data): 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]): 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]): 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
-
- 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] {
- def apply(idx: UInt): T
-
- @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 = (this map p).fold(Bool(true))(_ && _)
-
- /** Outputs true if p outputs true for at least one element.
- */
- def exists(p: T => Bool): 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 evidence: T <:< UInt): Bool = this.exists(_ === x)
-
- /** Outputs the number of elements for which p is true.
- */
- def count(p: T => Bool): 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 = SeqUtils.priorityMux(indexWhereHelper(p))
-
- /** Outputs the index of the last element for which p outputs true.
- */
- def lastIndexWhere(p: T => Bool): 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 = 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): 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): 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/src/main/scala/Chisel/BitPat.scala b/src/main/scala/Chisel/BitPat.scala
deleted file mode 100644
index a1bf1985..00000000
--- a/src/main/scala/Chisel/BitPat.scala
+++ /dev/null
@@ -1,80 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-object BitPat {
- /** Parses a bit pattern string into (bits, mask, width).
- *
- * @return bits the literal value, with don't cares being 0
- * @return mask the mask bits, with don't cares being 0 and cares being 1
- * @return width the number of bits in the literal, including values and
- * don't cares.
- */
- private def parse(x: String): (BigInt, BigInt, Int) = {
- // Notes:
- // While Verilog Xs also handle octal and hex cases, there isn't a
- // compelling argument and no one has asked for it.
- // If ? parsing is to be exposed, the return API needs further scrutiny
- // (especially with things like mask polarity).
- require(x.head == 'b', "BitPats must be in binary and be prefixed with 'b'")
- var bits = BigInt(0)
- var mask = BigInt(0)
- for (d <- x.tail) {
- if (d != '_') {
- require("01?".contains(d), "Literal: " + x + " contains illegal character: " + d)
- mask = (mask << 1) + (if (d == '?') 0 else 1)
- bits = (bits << 1) + (if (d == '1') 1 else 0)
- }
- }
- (bits, mask, x.length - 1)
- }
-
- /** Creates a [[BitPat]] literal from a string.
- *
- * @param n the literal value as a string, in binary, prefixed with 'b'
- * @note legal characters are '0', '1', and '?', as well as '_' as white
- * space (which are ignored)
- */
- def apply(n: String): BitPat = {
- val (bits, mask, width) = parse(n)
- new BitPat(bits, mask, width)
- }
-
- /** Creates a [[BitPat]] of all don't cares of the specified bitwidth. */
- def dontCare(width: Int): BitPat = BitPat("b" + ("?" * width))
-
- @deprecated("Use BitPat.dontCare", "chisel3")
- def DC(width: Int): BitPat = dontCare(width) // scalastyle:ignore method.name
-
- /** Allows BitPats to be used where a UInt is expected.
- *
- * @note the BitPat must not have don't care bits (will error out otherwise)
- */
- implicit def bitPatToUInt(x: BitPat): UInt = {
- require(x.mask == (BigInt(1) << x.getWidth) - 1)
- UInt(x.value, x.getWidth)
- }
-
- /** Allows UInts to be used where a BitPat is expected, useful for when an
- * interface is defined with BitPats but not all cases need the partial
- * matching capability.
- *
- * @note the UInt must be a literal
- */
- implicit def apply(x: UInt): BitPat = {
- require(x.isLit)
- BitPat("b" + x.litValue.toString(2))
- }
-}
-
-// TODO: Break out of Core? (this doesn't involve FIRRTL generation)
-/** Bit patterns are literals with masks, used to represent values with don't
- * cares. Equality comparisons will ignore don't care bits (for example,
- * BitPat(0b10?1) === UInt(0b1001) and UInt(0b1011)).
- */
-sealed class BitPat(val value: BigInt, val mask: BigInt, width: Int) {
- def getWidth: Int = width
- def === (other: UInt): Bool = UInt(value) === (other & UInt(mask))
- def =/= (other: UInt): Bool = !(this === other)
- def != (other: UInt): Bool = this =/= other
-}
diff --git a/src/main/scala/Chisel/Bits.scala b/src/main/scala/Chisel/Bits.scala
deleted file mode 100644
index 44d9b660..00000000
--- a/src/main/scala/Chisel/Bits.scala
+++ /dev/null
@@ -1,571 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-import internal._
-import internal.Builder.pushOp
-import internal.firrtl._
-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): this.type
-
- private[Chisel] def flatten: IndexedSeq[Bits] = IndexedSeq(this)
-
- def cloneType: this.type = cloneTypeWidth(width)
-
- override def <> (that: Data): Unit = this := that
-
- def tail(n: Int): 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(UInt(width = w), TailOp, n)
- }
-
- def head(n: Int): UInt = {
- width match {
- case KnownWidth(x) => require(x >= n, s"Can't head($n) for width $x < $n")
- case UnknownWidth() =>
- }
- binop(UInt(width = n), HeadOp, n)
- }
-
- /** Returns the specified bit on this wire as a [[Bool]], statically
- * addressed.
- */
- final def apply(x: BigInt): 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(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 =
- apply(BigInt(x))
-
- /** Returns the specified bit on this wire as a [[Bool]], dynamically
- * addressed.
- */
- final def apply(x: UInt): 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 = {
- 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(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 = apply(x.toInt, y.toInt)
-
- private[Chisel] def unop[T <: Data](dest: T, op: PrimOp): T =
- pushOp(DefPrim(dest, op, this.ref))
- private[Chisel] def binop[T <: Data](dest: T, op: PrimOp, other: BigInt): T =
- pushOp(DefPrim(dest, op, this.ref, ILit(other)))
- private[Chisel] def binop[T <: Data](dest: T, op: PrimOp, other: Bits): T =
- pushOp(DefPrim(dest, op, this.ref, other.ref))
- private[Chisel] def compop(op: PrimOp, other: Bits): Bool =
- pushOp(DefPrim(Bool(), op, this.ref, other.ref))
- private[Chisel] def redop(op: PrimOp): Bool =
- pushOp(DefPrim(Bool(), op, this.ref))
-
- /** Returns this wire zero padded up to the specified width.
- *
- * @note for SInts only, this does sign extension
- */
- def pad (other: Int): this.type = binop(cloneTypeWidth(this.width max Width(other)), PadOp, other)
-
- /** Shift left operation */
- // REVIEW TODO: redundant
- // REVIEW TODO: should these return this.type or Bits?
- def << (other: BigInt): 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.
- */
- def << (other: Int): 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.
- */
- def << (other: UInt): Bits
-
- /** Shift right operation */
- // REVIEW TODO: redundant
- def >> (other: BigInt): 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.
- */
- def >> (other: Int): 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.
- */
- def >> (other: UInt): Bits
-
- /** Returns the contents of this wire as a [[Vec]] of [[Bool]]s.
- */
- def toBools: Vec[Bool] = Vec.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
- */
- def asSInt(): 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
- */
- def asUInt(): UInt
-
- /** Reinterpret cast to Bits. */
- def asBits(): Bits = asUInt
-
- @deprecated("Use asSInt, which makes the reinterpret cast more explicit", "chisel3")
- final def toSInt(): SInt = asSInt
- @deprecated("Use asUInt, which makes the reinterpret cast more explicit", "chisel3")
- final def toUInt(): UInt = asUInt
-
- def toBool(): 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.
- */
- def ## (other: Bits): UInt = {
- val w = this.width + other.width
- pushOp(DefPrim(UInt(w), ConcatOp, this.ref, other.ref))
- }
-
- @deprecated("Use asBits, which makes the reinterpret cast more explicit and actually returns Bits", "chisel3")
- override def toBits: UInt = asUInt
-
- override def fromBits(n: Bits): this.type = {
- val res = Wire(this).asInstanceOf[this.type]
- res := n
- 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).
- */
- def + (b: T): 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
- */
- def * (b: T): T
-
- /** Outputs the quotient of `this` and `b`.
- *
- * TODO: full rules
- */
- def / (b: T): T
-
- def % (b: T): T
-
- /** Outputs the difference of `this` and `b`. The resulting width is the max
- * of the operands plus 1 (should not overflow).
- */
- def - (b: T): T
-
- /** Outputs true if `this` < `b`.
- */
- def < (b: T): Bool
-
- /** Outputs true if `this` <= `b`.
- */
- def <= (b: T): Bool
-
- /** Outputs true if `this` > `b`.
- */
- def > (b: T): Bool
-
- /** Outputs true if `this` >= `b`.
- */
- def >= (b: T): Bool
-
- /** Outputs the minimum of `this` and `b`. The resulting width is the max of
- * the operands.
- */
- def min(b: T): T = Mux(this < b, this.asInstanceOf[T], b)
-
- /** Outputs the maximum of `this` and `b`. The resulting width is the max of
- * the operands.
- */
- def max(b: T): T = Mux(this < b, b, 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): this.type = UInt(value).asInstanceOf[this.type]
-
- override def := (that: Data): Unit = that match {
- case _: UInt => this connect that
- case _ => this badConnect that
- }
-
- // TODO: refactor to share documentation with Num or add independent scaladoc
- def unary_- : UInt = UInt(0) - this
- def unary_-% : UInt = UInt(0) -% this
- def +& (other: UInt): UInt = binop(UInt((this.width max other.width) + 1), AddOp, other)
- def + (other: UInt): UInt = this +% other
- def +% (other: UInt): UInt = (this +& other) tail 1
- def -& (other: UInt): UInt = binop(UInt((this.width max other.width) + 1), SubOp, other)
- def - (other: UInt): UInt = this -% other
- def -% (other: UInt): UInt = (this -& other) tail 1
- def * (other: UInt): UInt = binop(UInt(this.width + other.width), TimesOp, other)
- def * (other: SInt): SInt = other * this
- def / (other: UInt): UInt = binop(UInt(this.width), DivideOp, other)
- def % (other: UInt): UInt = binop(UInt(this.width), RemOp, other)
-
- def & (other: UInt): UInt = binop(UInt(this.width max other.width), BitAndOp, other)
- def | (other: UInt): UInt = binop(UInt(this.width max other.width), BitOrOp, other)
- def ^ (other: UInt): UInt = binop(UInt(this.width max other.width), BitXorOp, other)
-
- /** Returns this wire bitwise-inverted. */
- def unary_~ : UInt = unop(UInt(width = width), BitNotOp)
-
- // REVIEW TODO: Can this be defined on Bits?
- def orR: Bool = this != UInt(0)
- def andR: Bool = ~this === UInt(0)
- def xorR: Bool = redop(XorReduceOp)
-
- def < (other: UInt): Bool = compop(LessOp, other)
- def > (other: UInt): Bool = compop(GreaterOp, other)
- def <= (other: UInt): Bool = compop(LessEqOp, other)
- def >= (other: UInt): Bool = compop(GreaterEqOp, other)
- def != (other: UInt): Bool = compop(NotEqualOp, other)
- def =/= (other: UInt): Bool = compop(NotEqualOp, other)
- def === (other: UInt): Bool = compop(EqualOp, other)
- def unary_! : Bool = this === Bits(0)
-
- // REVIEW TODO: Can these also not be defined on Bits?
- def << (other: Int): UInt = binop(UInt(this.width + other), ShiftLeftOp, other)
- def << (other: BigInt): UInt = this << other.toInt
- def << (other: UInt): UInt = binop(UInt(this.width.dynamicShiftLeft(other.width)), DynamicShiftLeftOp, other)
- def >> (other: Int): UInt = binop(UInt(this.width.shiftRight(other)), ShiftRightOp, other)
- def >> (other: BigInt): UInt = this >> other.toInt
- def >> (other: UInt): UInt = binop(UInt(this.width), DynamicShiftRightOp, other)
-
- def bitSet(off: UInt, dat: Bool): UInt = {
- val bit = UInt(1, 1) << off
- Mux(dat, this | bit, ~(~this | bit))
- }
-
- def === (that: BitPat): Bool = that === this
- def != (that: BitPat): Bool = that != this
- def =/= (that: BitPat): Bool = that =/= this
-
- /** 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.
- def zext(): SInt = pushOp(DefPrim(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).
- */
- def asSInt(): SInt = pushOp(DefPrim(SInt(width), AsSIntOp, ref))
-
- def asUInt(): 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): Unit = that match {
- case _: SInt => this connect that
- case _ => this badConnect that
- }
-
- override private[Chisel] def fromInt(value: BigInt): this.type = SInt(value).asInstanceOf[this.type]
-
- def unary_- : SInt = SInt(0) - this
- def unary_-% : SInt = SInt(0) -% this
- /** add (width +1) operator */
- def +& (other: SInt): SInt = binop(SInt((this.width max other.width) + 1), AddOp, other)
- /** add (default - no growth) operator */
- def + (other: SInt): SInt = this +% other
- /** add (no growth) operator */
- def +% (other: SInt): SInt = (this +& other).tail(1).asSInt
- /** subtract (width +1) operator */
- def -& (other: SInt): SInt = binop(SInt((this.width max other.width) + 1), SubOp, other)
- /** subtract (default - no growth) operator */
- def - (other: SInt): SInt = this -% other
- /** subtract (no growth) operator */
- def -% (other: SInt): SInt = (this -& other).tail(1).asSInt
- def * (other: SInt): SInt = binop(SInt(this.width + other.width), TimesOp, other)
- def * (other: UInt): SInt = binop(SInt(this.width + other.width), TimesOp, other)
- def / (other: SInt): SInt = binop(SInt(this.width), DivideOp, other)
- def % (other: SInt): SInt = binop(SInt(this.width), RemOp, other)
-
- def & (other: SInt): SInt = binop(UInt(this.width max other.width), BitAndOp, other).asSInt
- def | (other: SInt): SInt = binop(UInt(this.width max other.width), BitOrOp, other).asSInt
- def ^ (other: SInt): SInt = binop(UInt(this.width max other.width), BitXorOp, other).asSInt
-
- /** Returns this wire bitwise-inverted. */
- def unary_~ : SInt = unop(UInt(width = width), BitNotOp).asSInt
-
- def < (other: SInt): Bool = compop(LessOp, other)
- def > (other: SInt): Bool = compop(GreaterOp, other)
- def <= (other: SInt): Bool = compop(LessEqOp, other)
- def >= (other: SInt): Bool = compop(GreaterEqOp, other)
- def != (other: SInt): Bool = compop(NotEqualOp, other)
- def =/= (other: SInt): Bool = compop(NotEqualOp, other)
- def === (other: SInt): Bool = compop(EqualOp, other)
- def abs(): UInt = Mux(this < SInt(0), (-this).asUInt, this.asUInt)
-
- def << (other: Int): SInt = binop(SInt(this.width + other), ShiftLeftOp, other)
- def << (other: BigInt): SInt = this << other.toInt
- def << (other: UInt): SInt = binop(SInt(this.width.dynamicShiftLeft(other.width)), DynamicShiftLeftOp, other)
- def >> (other: Int): SInt = binop(SInt(this.width.shiftRight(other)), ShiftRightOp, other)
- def >> (other: BigInt): SInt = this >> other.toInt
- def >> (other: UInt): SInt = binop(SInt(this.width), DynamicShiftRightOp, other)
-
- def asUInt(): UInt = pushOp(DefPrim(UInt(this.width), AsUIntOp, ref))
- def asSInt(): 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): this.type = {
- require(value == 0 || value == 1)
- Bool(value == 1).asInstanceOf[this.type]
- }
-
- // REVIEW TODO: Why does this need to exist and have different conventions
- // than Bits?
- def & (other: Bool): Bool = binop(Bool(), BitAndOp, other)
- def | (other: Bool): Bool = binop(Bool(), BitOrOp, other)
- def ^ (other: Bool): Bool = binop(Bool(), BitXorOp, other)
-
- /** Returns this wire bitwise-inverted. */
- override def unary_~ : Bool = unop(Bool(), BitNotOp)
-
- /** Outputs the logical OR of two Bools.
- */
- def || (that: Bool): Bool = this | that
-
- /** Outputs the logical AND of two Bools.
- */
- def && (that: Bool): 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 = (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): 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(d, MultiplexOp, cond.ref, con.ref, alt.ref))
- }
-
- private def doAggregateMux[T <: Data](cond: Bool, con: T, alt: T): 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/src/main/scala/Chisel/BlackBox.scala b/src/main/scala/Chisel/BlackBox.scala
deleted file mode 100644
index be72934d..00000000
--- a/src/main/scala/Chisel/BlackBox.scala
+++ /dev/null
@@ -1,54 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-import internal.Builder.pushCommand
-import internal.firrtl.{ModuleIO, DefInvalid}
-
-/** 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(): this.type = _parent match {
- case Some(p) => {
- // Just init instance inputs
- for((_,port) <- ports) pushCommand(DefInvalid(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/src/main/scala/Chisel/CoreUtil.scala b/src/main/scala/Chisel/CoreUtil.scala
deleted file mode 100644
index 708b516e..00000000
--- a/src/main/scala/Chisel/CoreUtil.scala
+++ /dev/null
@@ -1,97 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-import internal._
-import internal.Builder.pushCommand
-import internal.firrtl._
-
-import scala.language.experimental.macros
-import scala.reflect.macros.blackbox.Context
-
-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
- */
- def apply(cond: Bool, message: String): Unit = macro apply_impl_msg
- def apply(cond: Bool): Unit = macro apply_impl // macros currently can't take default arguments
-
- def apply_impl_msg(c: Context)(cond: c.Tree, message: 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))"
- }
-
- def apply_impl(c: Context)(cond: 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)"
- }
-
- def apply_impl_do(cond: Bool, line: String, message: Option[String]) {
- 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(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, "")
- }
-}
-
-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*) {
- when (!Builder.dynamicContext.currentModule.get.reset) {
- printfWithoutReset(fmt, data:_*)
- }
- }
-
- private[Chisel] def printfWithoutReset(fmt: String, data: Bits*) {
- val clock = Builder.dynamicContext.currentModule.get.clock
- pushCommand(Printf(Node(clock), fmt, data.map((d: Bits) => d.ref)))
- }
-}
diff --git a/src/main/scala/Chisel/Data.scala b/src/main/scala/Chisel/Data.scala
deleted file mode 100644
index 8879491c..00000000
--- a/src/main/scala/Chisel/Data.scala
+++ /dev/null
@@ -1,152 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-import internal._
-import internal.Builder.pushCommand
-import internal.firrtl._
-
-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): Unit =
- throwException(s"cannot connect ${this} and ${that}")
- private[Chisel] def connect(that: Data): Unit =
- pushCommand(Connect(this.lref, that.ref))
- private[Chisel] def bulkConnect(that: Data): Unit =
- pushCommand(BulkConnect(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): Unit = this badConnect that
- def <> (that: Data): 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(n: Bits): this.type = {
- var i = 0
- val wire = Wire(this.cloneType)
- val bits =
- if (n.width.known && n.width.get >= wire.width.get) {
- n
- } else {
- Wire(n.cloneTypeWidth(wire.width), init = n)
- }
- 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).
- */
- def toBits(): UInt = SeqUtils.asUInt(this.flatten)
-}
-
-object Wire {
- def apply[T <: Data](t: T): T =
- makeWire(t, null.asInstanceOf[T])
-
- def apply[T <: Data](dummy: Int = 0, init: T): T =
- makeWire(null.asInstanceOf[T], init)
-
- def apply[T <: Data](t: T, init: T): T =
- makeWire(t, init)
-
- private def makeWire[T <: Data](t: T, init: T): T = {
- val x = Reg.makeType(t, null.asInstanceOf[T], init)
- pushCommand(DefWire(x))
- pushCommand(DefInvalid(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): Unit = that match {
- case _: Clock => this connect that
- case _ => this badConnect that
- }
-}
diff --git a/src/main/scala/Chisel/Mem.scala b/src/main/scala/Chisel/Mem.scala
deleted file mode 100644
index 17ac9ca5..00000000
--- a/src/main/scala/Chisel/Mem.scala
+++ /dev/null
@@ -1,123 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-import internal._
-import internal.Builder.pushCommand
-import internal.firrtl._
-
-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] = apply(size, t)
-
- /** 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] = {
- val mt = t.cloneType
- val mem = new Mem(mt, size)
- pushCommand(DefMemory(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(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(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 = {
- makePort(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: Vec[Bool]) (implicit evidence: T <:< Vec[_]): Unit = {
- val accessor = makePort(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(idx: UInt, dir: MemPortDirection): T =
- pushCommand(DefMemPort(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] = apply(size, t)
-
- /** 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] = {
- val mt = t.cloneType
- val mem = new SeqMem(mt, size)
- pushCommand(DefSeqMemory(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 = {
- val a = Wire(UInt())
- when (enable) { a := addr }
- read(a)
- }
-}
diff --git a/src/main/scala/Chisel/Module.scala b/src/main/scala/Chisel/Module.scala
deleted file mode 100644
index 3e839cac..00000000
--- a/src/main/scala/Chisel/Module.scala
+++ /dev/null
@@ -1,103 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-import scala.collection.mutable.{ArrayBuffer, HashSet}
-
-import internal._
-import internal.Builder.pushCommand
-import internal.Builder.dynamicContext
-import internal.firrtl._
-
-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 = {
- val parent = dynamicContext.currentModule
- val m = bc.setRefs()
- m._commands.prepend(DefInvalid(m.io.ref)) // init module outputs
- dynamicContext.currentModule = parent
- val ports = m.computePorts
- Builder.components += Component(m, m.name, ports, m._commands)
- pushCommand(DefInstance(m, ports))
- m.setupInParent()
- }
-}
-
-/** 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(Some(_clock), None)
- def this(_reset: Bool) = this(None, Some(_reset))
- def this(_clock: Clock, _reset: Bool) = this(Some(_clock), Some(_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(): this.type = _parent match {
- case Some(p) => {
- pushCommand(DefInvalid(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 _ =>
- }
-
- // All suggestions are in, force names to every node.
- _ids.foreach(_.forceName(default="T", _namespace))
- _ids.foreach(_._onModuleClose)
- this
- }
-}
diff --git a/src/main/scala/Chisel/Reg.scala b/src/main/scala/Chisel/Reg.scala
deleted file mode 100644
index e69061c5..00000000
--- a/src/main/scala/Chisel/Reg.scala
+++ /dev/null
@@ -1,66 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-import internal._
-import internal.Builder.pushCommand
-import internal.firrtl._
-
-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 = {
- // 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(x, clock))
- } else {
- pushCommand(DefRegInit(x, clock, Node(x._parent.get.reset), init.ref))
- }
- if (next != null) {
- x := next
- }
- x
- }
-
- /** 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])
-}
diff --git a/src/main/scala/Chisel/SeqUtils.scala b/src/main/scala/Chisel/SeqUtils.scala
deleted file mode 100644
index c63f5735..00000000
--- a/src/main/scala/Chisel/SeqUtils.scala
+++ /dev/null
@@ -1,47 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-private[Chisel] object SeqUtils {
- /** Equivalent to Cat(r(n-1), ..., r(0)) */
- def asUInt[T <: Bits](in: Seq[T]): 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 = {
- 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 <: Bits](in: Seq[(Bool, T)]): 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 = {
- 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/src/main/scala/Chisel/When.scala b/src/main/scala/Chisel/When.scala
deleted file mode 100644
index 5f6b02c5..00000000
--- a/src/main/scala/Chisel/When.scala
+++ /dev/null
@@ -1,56 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel
-
-import internal._
-import internal.Builder.pushCommand
-import internal.firrtl._
-
-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): WhenContext = {
- new WhenContext(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.
- */
-class WhenContext(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): WhenContext = {
- new WhenContext(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): Unit =
- new WhenContext(prevCond, null)(block)
-
- pushCommand(WhenBegin(cond.ref))
- block
- pushCommand(WhenEnd())
-}
diff --git a/src/main/scala/Chisel/internal/Builder.scala b/src/main/scala/Chisel/internal/Builder.scala
deleted file mode 100644
index c7ecdaa0..00000000
--- a/src/main/scala/Chisel/internal/Builder.scala
+++ /dev/null
@@ -1,122 +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.get
- 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/src/main/scala/Chisel/internal/Error.scala b/src/main/scala/Chisel/internal/Error.scala
deleted file mode 100644
index 6c4c0880..00000000
--- a/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/src/main/scala/Chisel/internal/firrtl/Emitter.scala b/src/main/scala/Chisel/internal/firrtl/Emitter.scala
deleted file mode 100644
index b690d974..00000000
--- a/src/main/scala/Chisel/internal/firrtl/Emitter.scala
+++ /dev/null
@@ -1,101 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel.internal.firrtl
-import Chisel._
-
-private class Emitter(circuit: Circuit) {
- override def toString: String = res.toString
-
- private def emitPort(e: Port): String =
- s"${e.dir} ${e.id.getRef.name} : ${e.id.toType}"
- private def emit(e: Command, ctx: Component): String = e match {
- case e: DefPrim[_] => s"node ${e.name} = ${e.op.name}(${e.args.map(_.fullName(ctx)).mkString(", ")})"
- case e: DefWire => s"wire ${e.name} : ${e.id.toType}"
- case e: DefReg => s"reg ${e.name} : ${e.id.toType}, ${e.clock.fullName(ctx)}"
- case e: DefRegInit => s"reg ${e.name} : ${e.id.toType}, ${e.clock.fullName(ctx)} with : (reset => (${e.reset.fullName(ctx)}, ${e.init.fullName(ctx)}))"
- case e: DefMemory => s"cmem ${e.name} : ${e.t.toType}[${e.size}]"
- case e: DefSeqMemory => s"smem ${e.name} : ${e.t.toType}[${e.size}]"
- case e: DefMemPort[_] => s"${e.dir} mport ${e.name} = ${e.source.fullName(ctx)}[${e.index.fullName(ctx)}], ${e.clock.fullName(ctx)}"
- case e: Connect => s"${e.loc.fullName(ctx)} <= ${e.exp.fullName(ctx)}"
- case e: BulkConnect => s"${e.loc1.fullName(ctx)} <- ${e.loc2.fullName(ctx)}"
- case e: Stop => s"stop(${e.clk.fullName(ctx)}, UInt<1>(1), ${e.ret})"
- case e: Printf => s"""printf(${e.clk.fullName(ctx)}, UInt<1>(1), "${e.format}"${e.ids.map(_.fullName(ctx)).fold(""){_ + ", " + _}})"""
- case e: DefInvalid => s"${e.arg.fullName(ctx)} is invalid"
- case e: DefInstance => {
- val modName = moduleMap.get(e.id.name).get
- s"inst ${e.name} of $modName"
- }
-
- case w: WhenBegin =>
- indent()
- s"when ${w.pred.fullName(ctx)} :"
- case _: WhenEnd =>
- unindent()
- "skip"
- }
-
- // Map of Module FIRRTL definition to FIRRTL name, if it has been emitted already.
- private val defnMap = collection.mutable.HashMap[String, String]()
- // Map of Component name to FIRRTL id.
- private val moduleMap = collection.mutable.HashMap[String, String]()
-
- /** Generates the FIRRTL module definition with a specified name.
- */
- private def moduleDefn(m: Component, name: String): String = {
- val body = new StringBuilder
- m.id match {
- case _: BlackBox => body ++= newline + s"extmodule $name : "
- case _: Module => body ++= newline + s"module $name : "
- }
- withIndent {
- for (p <- m.ports)
- body ++= newline + emitPort(p)
- body ++= newline
-
- m.id match {
- case _: BlackBox =>
- // TODO: BlackBoxes should be empty, but funkiness in Module() means
- // it's not for now. Eventually, this should assert out.
- case _: Module => for (cmd <- m.commands) {
- body ++= newline + emit(cmd, m)
- }
- }
- body ++= newline
- }
- body.toString()
- }
-
- /** Returns the FIRRTL declaration and body of a module, or nothing if it's a
- * duplicate of something already emitted (on the basis of simple string
- * matching).
- */
- private def emit(m: Component): String = {
- // Generate the body.
- val moduleName = m.id.getClass.getName.split('.').last
- val defn = moduleDefn(m, moduleName)
-
- defnMap get defn match {
- case Some(deduplicatedName) =>
- moduleMap(m.name) = deduplicatedName
- ""
- case None =>
- require(!(moduleMap contains m.name),
- "emitting module with same name but different contents")
-
- moduleMap(m.name) = m.name
- defnMap(defn) = m.name
-
- moduleDefn(m, m.name)
- }
- }
-
- private var indentLevel = 0
- private def newline = "\n" + (" " * indentLevel)
- private def indent(): Unit = indentLevel += 1
- private def unindent() { require(indentLevel > 0); indentLevel -= 1 }
- private def withIndent(f: => Unit) { indent(); f; unindent() }
-
- private val res = new StringBuilder(s"circuit ${circuit.name} : ")
- withIndent { circuit.components.foreach(c => res ++= emit(c)) }
- res ++= newline
-}
diff --git a/src/main/scala/Chisel/internal/firrtl/IR.scala b/src/main/scala/Chisel/internal/firrtl/IR.scala
deleted file mode 100644
index 1e06a663..00000000
--- a/src/main/scala/Chisel/internal/firrtl/IR.scala
+++ /dev/null
@@ -1,187 +0,0 @@
-// See LICENSE for license details.
-
-package Chisel.internal.firrtl
-import Chisel._
-import Chisel.internal._
-
-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
-abstract class Definition extends Command {
- def id: HasId
- def name: String = id.getRef.name
-}
-case class DefPrim[T <: Data](id: T, op: PrimOp, args: Arg*) extends Definition
-case class DefInvalid(arg: Arg) extends Command
-case class DefWire(id: Data) extends Definition
-case class DefReg(id: Data, clock: Arg) extends Definition
-case class DefRegInit(id: Data, clock: Arg, reset: Arg, init: Arg) extends Definition
-case class DefMemory(id: HasId, t: Data, size: Int) extends Definition
-case class DefSeqMemory(id: HasId, t: Data, size: Int) extends Definition
-case class DefMemPort[T <: Data](id: T, source: Node, dir: MemPortDirection, index: Arg, clock: Arg) extends Definition
-case class DefInstance(id: Module, ports: Seq[Port]) extends Definition
-case class WhenBegin(pred: Arg) extends Command
-case class WhenEnd() extends Command
-case class Connect(loc: Node, exp: Arg) extends Command
-case class BulkConnect(loc1: Node, loc2: Node) extends Command
-case class ConnectInit(loc: Node, exp: Arg) extends Command
-case class Stop(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(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]) {
- def emit: String = new Emitter(this).toString
-}