diff options
| -rw-r--r-- | build.sbt | 2 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala | 19 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Bits.scala | 775 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Data.scala | 25 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Mem.scala | 10 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Module.scala | 4 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Mux.scala | 4 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala | 4 | ||||
| -rw-r--r-- | coreMacros/src/main/scala/chisel3/SourceInfoDoc.scala | 42 | ||||
| -rw-r--r-- | src/main/scala/chisel3/compatibility.scala | 3 | ||||
| -rw-r--r-- | src/main/scala/chisel3/package.scala | 18 | ||||
| -rw-r--r-- | src/main/scala/chisel3/util/BitPat.scala | 4 |
12 files changed, 787 insertions, 123 deletions
@@ -140,6 +140,8 @@ lazy val chisel = (project in file(".")). scalacOptions in Test ++= Seq("-language:reflectiveCalls"), scalacOptions in Compile in doc ++= Seq( "-diagrams", + "-groups", + "-skip-packages", "chisel3.internal", "-diagrams-max-classes", "25", "-doc-version", version.value, "-doc-title", name.value, diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 235b1d5a..f47b33d9 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -10,6 +10,7 @@ import chisel3.internal._ import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl._ import chisel3.internal.sourceinfo._ +import chisel3.SourceInfoDoc /** An abstract class for data types that solely consist of (are an aggregate * of) other Data objects. @@ -97,7 +98,7 @@ sealed abstract class Aggregate extends Data { } } -trait VecFactory { +trait VecFactory extends SourceInfoDoc { /** Creates a new [[Vec]] with `n` entries of the specified data type. * * @note elements are NOT assigned by default and have no value @@ -209,6 +210,7 @@ sealed class Vec[T <: Data] private[core] (gen: => T, val length: Int) */ override def apply(p: UInt): T = macro CompileOptionsTransform.pArg + /** @group SourceInfoTransformMacro */ def do_apply(p: UInt)(implicit compileOptions: CompileOptions): T = { requireIsHardware(p, "vec index") val port = gen @@ -259,7 +261,7 @@ sealed class Vec[T <: Data] private[core] (gen: => T, val length: Int) } } -object VecInit { +object VecInit extends SourceInfoDoc { /** Creates a new [[Vec]] composed of elements of the input Seq of [[Data]] * nodes. * @@ -271,6 +273,7 @@ object VecInit { */ def apply[T <: Data](elts: Seq[T]): Vec[T] = macro VecTransform.apply_elts + /** @group SourceInfoTransformMacro */ def do_apply[T <: Data](elts: Seq[T])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = { // REVIEW TODO: this should be removed in favor of the apply(elts: T*) // varargs constructor, which is more in line with the style of the Scala @@ -310,6 +313,7 @@ object VecInit { */ def apply[T <: Data](elt0: T, elts: T*): Vec[T] = macro VecTransform.apply_elt0 + /** @group SourceInfoTransformMacro */ def do_apply[T <: Data](elt0: T, elts: T*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = apply(elt0 +: elts.toSeq) @@ -323,6 +327,7 @@ object VecInit { */ def tabulate[T <: Data](n: Int)(gen: (Int) => T): Vec[T] = macro VecTransform.tabulate + /** @group SourceInfoTransformMacro */ def do_tabulate[T <: Data](n: Int)(gen: (Int) => T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = apply((0 until n).map(i => gen(i))) } @@ -330,9 +335,10 @@ object VecInit { /** A trait for [[Vec]]s containing common hardware generators for collection * operations. */ -trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId { +trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId with SourceInfoDoc { def apply(p: UInt): T = macro CompileOptionsTransform.pArg + /** @group SourceInfoTransformMacro */ def do_apply(p: UInt)(implicit compileOptions: CompileOptions): T // IndexedSeq has its own hashCode/equals that we must not use @@ -353,6 +359,7 @@ trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId { */ def forall(p: T => Bool): Bool = macro SourceInfoTransform.pArg + /** @group SourceInfoTransformMacro */ def do_forall(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = (this map p).fold(true.B)(_ && _) @@ -360,6 +367,7 @@ trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId { */ def exists(p: T => Bool): Bool = macro SourceInfoTransform.pArg + /** @group SourceInfoTransformMacro */ def do_exists(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = (this map p).fold(false.B)(_ || _) @@ -368,6 +376,7 @@ trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId { */ def contains(x: T)(implicit ev: T <:< UInt): Bool = macro VecTransform.contains + /** @group SourceInfoTransformMacro */ def do_contains(x: T)(implicit sourceInfo: SourceInfo, ev: T <:< UInt, compileOptions: CompileOptions): Bool = this.exists(_ === x) @@ -375,6 +384,7 @@ trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId { */ def count(p: T => Bool): UInt = macro SourceInfoTransform.pArg + /** @group SourceInfoTransformMacro */ def do_count(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = SeqUtils.count(this map p) @@ -387,6 +397,7 @@ trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId { */ def indexWhere(p: T => Bool): UInt = macro SourceInfoTransform.pArg + /** @group SourceInfoTransformMacro */ def do_indexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = SeqUtils.priorityMux(indexWhereHelper(p)) @@ -394,6 +405,7 @@ trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId { */ def lastIndexWhere(p: T => Bool): UInt = macro SourceInfoTransform.pArg + /** @group SourceInfoTransformMacro */ def do_lastIndexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = SeqUtils.priorityMux(indexWhereHelper(p).reverse) @@ -409,6 +421,7 @@ trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId { */ def onlyIndexWhere(p: T => Bool): UInt = macro SourceInfoTransform.pArg + /** @group SourceInfoTransformMacro */ def do_onlyIndexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = SeqUtils.oneHotMux(indexWhereHelper(p)) } diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala index 10b6ec8e..e9458446 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala @@ -14,8 +14,10 @@ import chisel3.internal.firrtl.PrimOp._ //scalastyle:off method.name -/** Element is a leaf data type: it cannot contain other Data objects. Example - * uses are for representing primitive data types, like integers and bits. +/** Element is a leaf data type: it cannot contain other [[Data]] objects. Example uses are for representing primitive + * data types, like integers and bits. + * + * @define coll element */ abstract class Element(private[chisel3] val width: Width) extends Data { private[chisel3] override def bind(target: Binding, parentDirection: SpecifiedDirection) { @@ -43,26 +45,31 @@ abstract class Element(private[chisel3] val width: Width) extends Data { } } -/** Exists to unify common interfaces of [[Bits]] and [[Reset]] - * Workaround because macros cannot override abstract methods +/** Exists to unify common interfaces of [[Bits]] and [[Reset]]. + * + * @note This is a workaround because macros cannot override abstract methods. */ private[chisel3] sealed trait ToBoolable extends Element { - /** Casts this object to a [[Bool]] + /** Casts this $coll to a [[Bool]] * - * @note Width must be known and equal to 1 + * @note The width must be known and equal to 1 */ final def toBool(): Bool = macro SourceInfoWhiteboxTransform.noArg + /** @group SourceInfoTransformMacro */ def do_toBool(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool } -/** A data type for values represented by a single bitvector. Provides basic - * bitwise operations. +/** A data type for values represented by a single bitvector. This provides basic bitwise operations. + * + * @groupdesc Bitwise Bitwise hardware operators + * @define coll [[Bits]] + * @define sumWidthInt @note The width of the returned $coll is `width of this` + `that`. + * @define sumWidth @note The width of the returned $coll is `width of this` + `width of that`. + * @define unchangedWidth @note The width of the returned $coll is unchanged, i.e., the `width of this`. */ -//scalastyle:off number.of.methods -sealed abstract class Bits(width: Width) - extends Element(width) with ToBoolable { +sealed abstract class Bits(width: Width) extends Element(width) with ToBoolable { //scalastyle:off number.of.methods // 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 @@ -99,9 +106,23 @@ sealed abstract class Bits(width: Width) case _ => super.ref } + /** Tail operator + * + * @param n the number of bits to remove + * @return This $coll with the `n` most significant bits removed. + * @group Bitwise + */ final def tail(n: Int): UInt = macro SourceInfoTransform.nArg + + /** Head operator + * + * @param n the number of bits to take + * @return The `n` most significant bits of this $coll + * @group Bitwise + */ final def head(n: Int): UInt = macro SourceInfoTransform.nArg + /** @group SourceInfoTransformMacro */ def do_tail(n: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = { val w = width match { case KnownWidth(x) => @@ -112,7 +133,7 @@ sealed abstract class Bits(width: Width) binop(sourceInfo, UInt(width = w), TailOp, n) } - + /** @group SourceInfoTransformMacro */ def do_head(n: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = { width match { case KnownWidth(x) => require(x >= n, s"Can't head($n) for width $x < $n") @@ -121,11 +142,14 @@ sealed abstract class Bits(width: Width) binop(sourceInfo, UInt(Width(n)), HeadOp, n) } - /** Returns the specified bit on this wire as a [[Bool]], statically - * addressed. + /** Returns the specified bit on this $coll as a [[Bool]], statically addressed. + * + * @param x an index + * @return the specified bit */ final def apply(x: BigInt): Bool = macro SourceInfoTransform.xArg + /** @group SourceInfoTransformMacro */ final def do_apply(x: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = { if (x < 0) { Builder.error(s"Negative bit indices are illegal (got $x)") @@ -140,36 +164,44 @@ sealed abstract class Bits(width: Width) } } - /** Returns the specified bit on this wire as a [[Bool]], statically - * addressed. + /** Returns the specified bit on this $coll as a [[Bool]], statically addressed. * - * @note convenience method allowing direct use of Ints without implicits + * @param x an index + * @return the specified bit + * @note convenience method allowing direct use of [[scala.Int]] without implicits */ final def apply(x: Int): Bool = macro SourceInfoTransform.xArg + /** @group SourceInfoTransformMacro */ final def do_apply(x: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = apply(BigInt(x)) - /** Returns the specified bit on this wire as a [[Bool]], dynamically - * addressed. + /** Returns the specified bit on this wire as a [[Bool]], dynamically addressed. + * + * @param x a hardware component whose value will be used for dynamic addressing + * @return the specified bit */ final def apply(x: UInt): Bool = macro SourceInfoTransform.xArg + /** @group SourceInfoTransformMacro */ final def do_apply(x: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = { val theBits = this >> x theBits(0) } - /** Returns a subset of bits on this wire from `hi` to `lo` (inclusive), - * statically addressed. + /** Returns a subset of bits on this $coll from `hi` to `lo` (inclusive), statically addressed. * * @example * {{{ * myBits = 0x5 = 0b101 * myBits(1,0) => 0b01 // extracts the two least significant bits * }}} + * @param x the high bit + * @param y the low bit + * @return a hardware component contain the requested bits */ final def apply(x: Int, y: Int): UInt = macro SourceInfoTransform.xyArg + /** @group SourceInfoTransformMacro */ final def do_apply(x: Int, y: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = { if (x < y || y < 0) { Builder.error(s"Invalid bit range ($x,$y)") @@ -186,8 +218,20 @@ sealed abstract class Bits(width: Width) } // REVIEW TODO: again, is this necessary? Or just have this and use implicits? + /** Returns a subset of bits on this $coll from `hi` to `lo` (inclusive), statically addressed. + * + * @example + * {{{ + * myBits = 0x5 = 0b101 + * myBits(1,0) => 0b01 // extracts the two least significant bits + * }}} + * @param x the high bit + * @param y the low bit + * @return a hardware component contain the requested bits + */ final def apply(x: BigInt, y: BigInt): UInt = macro SourceInfoTransform.xyArg + /** @group SourceInfoTransformMacro */ final def do_apply(x: BigInt, y: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = apply(x.toInt, y.toInt) @@ -214,96 +258,134 @@ sealed abstract class Bits(width: Width) pushOp(DefPrim(sourceInfo, Bool(), op, this.ref)) } - /** Returns this wire zero padded up to the specified width. + /** Pad operator * - * @note for SInts only, this does sign extension + * @param that the width to pad to + * @return this @coll zero padded up to width `that`. If `that` is less than the width of the original component, + * this method returns the original component. + * @note For [[SInt]]s only, this will do sign extension. + * @group Bitwise */ final def pad(that: Int): this.type = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_pad(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): this.type = this.width match { case KnownWidth(w) if w >= that => this case _ => binop(sourceInfo, cloneTypeWidth(this.width max Width(that)), PadOp, that) } - /** Returns this wire bitwise-inverted. */ + /** Bitwise inversion operator + * + * @return this $coll with each bit inverted + * @group Bitwise + */ final def unary_~ (): Bits = macro SourceInfoWhiteboxTransform.noArg + /** @group SourceInfoTransformMacro */ def do_unary_~ (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits - - /** Shift left operation */ + /** Static left shift operator + * + * @param that an amount to shift by + * @return this $coll with `that` many zeros concatenated to its least significant end + * $sumWidthInt + * @group Bitwise + */ // REVIEW TODO: redundant // REVIEW TODO: should these return this.type or Bits? final def << (that: BigInt): Bits = macro SourceInfoWhiteboxTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_<< (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits - /** Returns this wire statically left shifted by the specified amount, - * inserting zeros into the least significant bits. + /** Static left shift operator * - * The width of the output is `other` larger than the input. + * @param that an amount to shift by + * @return this $coll with `that` many zeros concatenated to its least significant end + * $sumWidthInt + * @group Bitwise */ final def << (that: Int): Bits = macro SourceInfoWhiteboxTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_<< (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits - /** Returns this wire dynamically left shifted by the specified amount, - * inserting zeros into the least significant bits. + /** Dynamic left shift operator * - * The width of the output is `pow(2, width(other))` larger than the input. + * @param that a hardware component + * @return this $coll dynamically shifted left by `that` many places, shifting in zeros from the right + * @note The width of the returned $coll is `width of this + pow(2, width of that)`. + * @group Bitwise */ final def << (that: UInt): Bits = macro SourceInfoWhiteboxTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_<< (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits - /** Shift right operation */ + /** Static right shift operator + * + * @param that an amount to shift by + * @return this $coll with `that` many least significant bits truncated + * $unchangedWidth + * @group Bitwise + */ // REVIEW TODO: redundant final def >> (that: BigInt): Bits = macro SourceInfoWhiteboxTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_>> (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits - /** Returns this wire statically right shifted by the specified amount, - * inserting zeros into the most significant bits. + /** Static right shift operator * - * The width of the output is the same as the input. + * @param that an amount to shift by + * @return this $coll with `that` many least significant bits truncated + * $unchangedWidth + * @group Bitwise */ final def >> (that: Int): Bits = macro SourceInfoWhiteboxTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_>> (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits - /** Returns this wire dynamically right shifted by the specified amount, - * inserting zeros into the most significant bits. + /** Dynamic right shift operator * - * The width of the output is the same as the input. + * @param that a hardware component + * @return this $coll dynamically shifted right by the value of `that` component, inserting zeros into the most + * significant bits. + * $unchangedWidth + * @group Bitwise */ final def >> (that: UInt): Bits = macro SourceInfoWhiteboxTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_>> (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits - /** Returns the contents of this wire as a [[Vec]] of [[Bool]]s. - */ + /** Returns the contents of this wire as a [[scala.collection.Seq]] of [[Bool]]. */ final def toBools(): Seq[Bool] = macro SourceInfoTransform.noArg + /** @group SourceInfoTransformMacro */ def toBools(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Seq[Bool] = Seq.tabulate(this.getWidth)(i => this(i)) - /** Reinterpret cast to a SInt. + /** Reinterpret this $coll as 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 + * @note The value is not guaranteed to be preserved. For example, a [[UInt]] of width 3 and value 7 (0b111) would + * become a [[SInt]] with value -1. */ final def asSInt(): SInt = macro SourceInfoTransform.noArg + /** @group SourceInfoTransformMacro */ def do_asSInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt - /** Reinterpret cast as a FixedPoint. + /** Reinterpret this $coll as a [[FixedPoint]]. * - * @note value not guaranteed to be preserved: for example, an UInt of width - * 3 and value 7 (0b111) would become a FixedInt with value -1, the interpretation - * of the number is also affected by the specified binary point. Caution advised + * @note The value is not guaranteed to be preserved. For example, a [[UInt]] of width 3 and value 7 (0b111) would + * become a [[FixedPoint]] with value -1. The interpretation of the number is also affected by the specified binary + * point. '''Caution is advised!''' */ final def asFixedPoint(that: BinaryPoint): FixedPoint = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_asFixedPoint(that: BinaryPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = { throwException(s"Cannot call .asFixedPoint on $this") } @@ -337,13 +419,16 @@ sealed abstract class Bits(width: Width) } } - /** Returns this wire concatenated with `other`, where this wire forms the - * most significant part and `other` forms the least significant part. + /** Concatenation operator * - * The width of the output is sum of the inputs. + * @param that a hardware component + * @return this $coll concatenated to the most significant end of `that` + * $sumWidth + * @group Bitwise */ final def ## (that: Bits): UInt = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_## (that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = { val w = this.width + that.width pushOp(DefPrim(sourceInfo, UInt(w), ConcatOp, this.ref, that.ref)) @@ -360,8 +445,22 @@ sealed abstract class Bits(width: Width) } // REVIEW TODO: Further discussion needed on what Num actually is. -/** Abstract trait defining operations available on numeric-like wire data - * types. +/** Abstract trait defining operations available on numeric-like hardware data types. + * + * @tparam T the underlying type of the number + * @groupdesc Arithmetic Arithmetic hardware operators + * @groupdesc Comparison Comparison hardware operators + * @groupdesc Logical Logical hardware operators + * @define coll numeric-like type + * @define numType hardware type + * @define canHaveHighCost can result in significant cycle time and area costs + * @define canGenerateA This method can generate a + * @define singleCycleMul @note $canGenerateA single-cycle multiplier which $canHaveHighCost. + * @define singleCycleDiv @note $canGenerateA single-cycle divider which $canHaveHighCost. + * @define maxWidth @note The width of the returned $numType is `max(width of this, width of that)`. + * @define maxWidthPlusOne @note The width of the returned $numType is `max(width of this, width of that) + 1`. + * @define sumWidth @note The width of the returned $numType is `width of this` + `width of that`. + * @define unchangedWidth @note The width of the returned $numType is unchanged, i.e., the `width of this`. */ abstract trait Num[T <: Data] { self: Num[T] => @@ -371,89 +470,157 @@ abstract trait Num[T <: Data] { // 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). + /** Addition operator + * + * @param that a $numType + * @return the sum of this $coll and `that` + * $maxWidthPlusOne + * @group Arithmetic */ final def + (that: T): T = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_+ (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T - /** Outputs the product of `this` and `b`. The resulting width is the sum of - * the operands. + /** Multiplication operator * - * @note can generate a single-cycle multiplier, which can result in - * significant cycle time and area costs + * @param that a $numType + * @return the product of this $coll and `that` + * $sumWidth + * $singleCycleMul + * @group Arithmetic */ final def * (that: T): T = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_* (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T - /** Outputs the quotient of `this` and `b`. + /** Division operator * - * TODO: full rules + * @param that a $numType + * @return the quotient of this $coll divided by `that` + * $singleCycleDiv + * @todo full rules + * @group Arithmetic */ final def / (that: T): T = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_/ (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T + /** Modulo operator + * + * @param that a $numType + * @return the remainder of this $coll divided by `that` + * $singleCycleDiv + * @group Arithmetic + */ final def % (that: T): T = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_% (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T - /** Outputs the difference of `this` and `b`. The resulting width is the max - * of the operands plus 1 (should not overflow). + /** Subtraction operator + * + * @param that a $numType + * @return the difference of this $coll less `that` + * $maxWidthPlusOne + * @group Arithmetic */ final def - (that: T): T = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_- (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T - /** Outputs true if `this` < `b`. + /** Less than operator + * + * @param that a $numType + * @return a hardware [[Bool]] asserted if this $coll is less than `that` + * @group Comparison */ final def < (that: T): Bool = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_< (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool - /** Outputs true if `this` <= `b`. + /** Less than or equal to operator + * + * @param that a $numType + * @return a hardware [[Bool]] asserted if this $coll is less than or equal to `that` + * @group Comparison */ final def <= (that: T): Bool = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_<= (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool - /** Outputs true if `this` > `b`. + /** Greater than operator + * + * @param that a hardware component + * @return a hardware [[Bool]] asserted if this $coll is greater than `that` + * @group Comparison */ final def > (that: T): Bool = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_> (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool - /** Outputs true if `this` >= `b`. + /** Greater than or equal to operator + * + * @param that a hardware component + * @return a hardware [[Bool]] asserted if this $coll is greather than or equal to `that` + * @group Comparison */ final def >= (that: T): Bool = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_>= (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool - /** Outputs the absolute value of `this`. The resulting width is the unchanged */ + /** Absolute value operator + * + * @return a $numType with a value equal to the absolute value of this $coll + * $unchangedWidth + * @group Arithmetic + */ final def abs(): T = macro SourceInfoTransform.noArg + + /** @group SourceInfoTransformMacro */ def do_abs(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T - /** Outputs the minimum of `this` and `b`. The resulting width is the max of - * the operands. + /** Minimum operator + * + * @param that a hardware $coll + * @return a $numType with a value equal to the mimimum value of this $coll and `that` + * $maxWidth + * @group Arithmetic */ final def min(that: T): T = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_min(that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = Mux(this < that, this.asInstanceOf[T], that) - /** Outputs the maximum of `this` and `b`. The resulting width is the max of - * the operands. + /** Maximum operator + * + * @param that a $numType + * @return a $numType with a value equal to the mimimum value of this $coll and `that` + * $maxWidth + * @group Arithmetic */ final def max(that: T): T = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_max(that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): 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. +/** A data type for unsigned integers, represented as a binary bitvector. Defines arithmetic operations between other + * integer types. + * + * @define coll [[UInt]] + * @define numType $coll + * @define expandingWidth @note The width of the returned $coll is `width of this` + `1`. + * @define constantWidth @note The width of the returned $coll is unchanged, i.e., `width of this`. */ sealed class UInt private[core] (width: Width) extends Bits(width) with Num[UInt] { @@ -464,10 +631,25 @@ sealed class UInt private[core] (width: Width) extends Bits(width) with Num[UInt new UInt(w).asInstanceOf[this.type] // TODO: refactor to share documentation with Num or add independent scaladoc + /** Unary negation (expanding width) + * + * @return a $coll equal to zero minus this $coll + * $expandingWidth + * @group Arithmetic + */ final def unary_- (): UInt = macro SourceInfoTransform.noArg + + /** Unary negation (constant width) + * + * @return a $coll equal to zero minus this $coll shifted right by one. + * $constantWidth + * @group Arithmetic + */ final def unary_-% (): UInt = macro SourceInfoTransform.noArg + /** @group SourceInfoTransformMacro */ def do_unary_- (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) : UInt = 0.U - this + /** @group SourceInfoTransformMacro */ def do_unary_-% (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = 0.U -% this override def do_+ (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = this +% that @@ -479,48 +661,138 @@ sealed class UInt private[core] (width: Width) extends Bits(width) with Num[UInt override def do_* (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = binop(sourceInfo, UInt(this.width + that.width), TimesOp, that) + /** Multiplication operator + * + * @param that a hardware [[SInt]] + * @return the product of this $coll and `that` + * $sumWidth + * $singleCycleMul + * @group Arithmetic + */ final def * (that: SInt): SInt = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_* (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = that * this + /** Addition operator (expanding width) + * + * @param that a hardware $coll + * @return the sum of this $coll and `that` + * $maxWidthPlusOne + * @group Arithmetic + */ final def +& (that: UInt): UInt = macro SourceInfoTransform.thatArg + + /** Addition operator (constant width) + * + * @param that a hardware $coll + * @return the sum of this $coll and `that` + * $maxWidth + * @group Arithmetic + */ final def +% (that: UInt): UInt = macro SourceInfoTransform.thatArg + + /** Subtraction operator (increasing width) + * + * @param that a hardware $coll + * @return the difference of this $coll less `that` + * $maxWidthPlusOne + * @group Arithmetic + */ final def -& (that: UInt): UInt = macro SourceInfoTransform.thatArg + + /** Subtraction operator (constant width) + * + * @param that a hardware $coll + * @return the difference of this $coll less `that` + * $maxWidth + * @group Arithmetic + */ final def -% (that: UInt): UInt = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_+& (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = binop(sourceInfo, UInt((this.width max that.width) + 1), AddOp, that) + /** @group SourceInfoTransformMacro */ def do_+% (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = (this +& that).tail(1) + /** @group SourceInfoTransformMacro */ def do_-& (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = binop(sourceInfo, SInt((this.width max that.width) + 1), SubOp, that).asUInt + /** @group SourceInfoTransformMacro */ def do_-% (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = (this -& that).tail(1) + /** Bitwise and operator + * + * @param that a hardware $coll + * @return the bitwise and of this $coll and `that` + * $maxWidth + * @group Bitwise + */ final def & (that: UInt): UInt = macro SourceInfoTransform.thatArg + + /** Bitwise or operator + * + * @param that a hardware $coll + * @return the bitwise or of this $coll and `that` + * $maxWidth + * @group Bitwise + */ final def | (that: UInt): UInt = macro SourceInfoTransform.thatArg + + /** Bitwise exclusive or (xor) operator + * + * @param that a hardware $coll + * @return the bitwise xor of this $coll and `that` + * $maxWidth + * @group Bitwise + */ final def ^ (that: UInt): UInt = macro SourceInfoTransform.thatArg -// override def abs: UInt = macro SourceInfoTransform.noArg + // override def abs: UInt = macro SourceInfoTransform.noArg def do_abs(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = this + /** @group SourceInfoTransformMacro */ def do_& (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = binop(sourceInfo, UInt(this.width max that.width), BitAndOp, that) + /** @group SourceInfoTransformMacro */ def do_| (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = binop(sourceInfo, UInt(this.width max that.width), BitOrOp, that) + /** @group SourceInfoTransformMacro */ def do_^ (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = binop(sourceInfo, UInt(this.width max that.width), BitXorOp, that) - /** Returns this wire bitwise-inverted. */ + /** @group SourceInfoTransformMacro */ def do_unary_~ (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = unop(sourceInfo, UInt(width = width), BitNotOp) - // REVIEW TODO: Can this be defined on Bits? + // REVIEW TODO: Can these be defined on Bits? + /** Or reduction operator + * + * @return a hardware [[Bool]] resulting from every bit of this $coll or'd together + * @group Bitwise + */ final def orR(): Bool = macro SourceInfoTransform.noArg + + /** And reduction operator + * + * @return a hardware [[Bool]] resulting from every bit of this $coll and'd together + * @group Bitwise + */ final def andR(): Bool = macro SourceInfoTransform.noArg + + /** Exclusive or (xor) reduction operator + * + * @return a hardware [[Bool]] resulting from every bit of this $coll xor'd together + * @group Bitwise + */ final def xorR(): Bool = macro SourceInfoTransform.noArg + /** @group SourceInfoTransformMacro */ def do_orR(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = this =/= 0.U + /** @group SourceInfoTransformMacro */ def do_andR(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = ~this === 0.U + /** @group SourceInfoTransformMacro */ def do_xorR(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = redop(sourceInfo, XorReduceOp) override def do_< (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, LessOp, that) @@ -531,14 +803,36 @@ sealed class UInt private[core] (width: Width) extends Bits(width) with Num[UInt @chiselRuntimeDeprecated @deprecated("Use '=/=', which avoids potential precedence problems", "chisel3") final def != (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = this =/= that + + /** Dynamic not equals operator + * + * @param that a hardware $coll + * @return a hardware [[Bool]] asserted if this $coll is not equal to `that` + * @group Comparison + */ final def =/= (that: UInt): Bool = macro SourceInfoTransform.thatArg + + /** Dynamic equals operator + * + * @param that a hardware $coll + * @return a hardware [[Bool]] asserted if this $coll is equal to `that` + * @group Comparison + */ final def === (that: UInt): Bool = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_=/= (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, NotEqualOp, that) + /** @group SourceInfoTransformMacro */ def do_=== (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, EqualOp, that) + /** Unary not + * + * @return a hardware [[Bool]] asserted if the least significant bit of this $coll is zero + * @group Bitwise + */ final def unary_! () : Bool = macro SourceInfoTransform.noArg + /** @group SourceInfoTransformMacro */ def do_unary_! (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) : Bool = this === 0.U(1.W) override def do_<< (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = @@ -554,25 +848,33 @@ sealed class UInt private[core] (width: Width) extends Bits(width) with Num[UInt override def do_>> (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = binop(sourceInfo, UInt(this.width), DynamicShiftRightOp, that) + /** Conditionally set or clear a bit + * + * @param off a dynamic offset + * @param dat set if true, clear if false + * @return a hrdware $coll with bit `off` set or cleared based on the value of `dat` + * $unchangedWidth + */ final def bitSet(off: UInt, dat: Bool): UInt = macro UIntTransform.bitset + /** @group SourceInfoTransformMacro */ def do_bitSet(off: UInt, dat: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = { val bit = 1.U(1.W) << 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. + /** Zero extend as [[SInt]] + * + * @return an [[SInt]] equal to this $coll with an additional zero in its most significant bit + * @note The width of the returned [[SInt]] is `width of this` + `1`. + */ final def zext(): SInt = macro SourceInfoTransform.noArg + /** @group SourceInfoTransformMacro */ def do_zext(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): 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, compileOptions: CompileOptions): SInt = pushOp(DefPrim(sourceInfo, SInt(width), AsSIntOp, ref)) override def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = this @@ -620,6 +922,14 @@ trait UIntFactory { object UInt extends UIntFactory object Bits extends UIntFactory +/** A data type for signed integers, represented as a binary bitvector. Defines arithmetic operations between other + * integer types. + * + * @define coll [[SInt]] + * @define numType $coll + * @define expandingWidth @note The width of the returned $coll is `width of this` + `1`. + * @define constantWidth @note The width of the returned $coll is unchanged, i.e., `width of this`. + */ sealed class SInt private[core] (width: Width) extends Bits(width) with Num[SInt] { private[core] override def typeEquivalent(that: Data): Boolean = @@ -628,10 +938,25 @@ sealed class SInt private[core] (width: Width) extends Bits(width) with Num[SInt private[core] override def cloneTypeWidth(w: Width): this.type = new SInt(w).asInstanceOf[this.type] + /** Unary negation (expanding width) + * + * @return a hardware $coll equal to zero minus this $coll + * $expandingWidth + * @group Arithmetic + */ final def unary_- (): SInt = macro SourceInfoTransform.noArg + + /** Unary negation (constant width) + * + * @return a hardware $coll equal to zero minus `this` shifted right by one + * $constantWidth + * @group Arithmetic + */ final def unary_-% (): SInt = macro SourceInfoTransform.noArg + /** @group SourceInfoTransformMacro */ def unary_- (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = 0.S - this + /** @group SourceInfoTransformMacro */ def unary_-% (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = 0.S -% this /** add (default - no growth) operator */ @@ -647,43 +972,109 @@ sealed class SInt private[core] (width: Width) extends Bits(width) with Num[SInt override def do_% (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = binop(sourceInfo, SInt(this.width), RemOp, that) + /** Multiplication operator + * + * @param that a hardware $coll + * @return the product of this $coll and `that` + * $sumWidth + * $singleCycleMul + * @group Arithmetic + */ final def * (that: UInt): SInt = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_* (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = { val thatToSInt = that.zext() val result = binop(sourceInfo, SInt(this.width + thatToSInt.width), TimesOp, thatToSInt) result.tail(1).asSInt } - /** add (width +1) operator */ + /** Addition operator (expanding width) + * + * @param that a hardware $coll + * @return the sum of this $coll and `that` + * $maxWidthPlusOne + * @group Arithmetic + */ final def +& (that: SInt): SInt = macro SourceInfoTransform.thatArg - /** add (no growth) operator */ + + /** Addition operator (constant width) + * + * @param that a hardware $coll + * @return the sum of this $coll and `that` shifted right by one + * $maxWidth + * @group Arithmetic + */ final def +% (that: SInt): SInt = macro SourceInfoTransform.thatArg - /** subtract (width +1) operator */ + + /** Subtraction operator (increasing width) + * + * @param that a hardware $coll + * @return the difference of this $coll less `that` + * $maxWidthPlusOne + * @group Arithmetic + */ final def -& (that: SInt): SInt = macro SourceInfoTransform.thatArg - /** subtract (no growth) operator */ + + /** Subtraction operator (constant width) + * + * @param that a hardware $coll + * @return the difference of this $coll less `that` shifted right by one + * $maxWidth + * @group Arithmetic + */ final def -% (that: SInt): SInt = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_+& (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = binop(sourceInfo, SInt((this.width max that.width) + 1), AddOp, that) + /** @group SourceInfoTransformMacro */ def do_+% (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = (this +& that).tail(1).asSInt + /** @group SourceInfoTransformMacro */ def do_-& (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = binop(sourceInfo, SInt((this.width max that.width) + 1), SubOp, that) + /** @group SourceInfoTransformMacro */ def do_-% (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = (this -& that).tail(1).asSInt + /** Bitwise and operator + * + * @param that a hardware $coll + * @return the bitwise and of this $coll and `that` + * $maxWidth + * @group Bitwise + */ final def & (that: SInt): SInt = macro SourceInfoTransform.thatArg + + /** Bitwise or operator + * + * @param that a hardware $coll + * @return the bitwise or of this $coll and `that` + * $maxWidth + * @group Bitwise + */ final def | (that: SInt): SInt = macro SourceInfoTransform.thatArg + + /** Bitwise exclusive or (xor) operator + * + * @param that a hardware $coll + * @return the bitwise xor of this $coll and `that` + * $maxWidth + * @group Bitwise + */ final def ^ (that: SInt): SInt = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_& (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = binop(sourceInfo, UInt(this.width max that.width), BitAndOp, that).asSInt + /** @group SourceInfoTransformMacro */ def do_| (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = binop(sourceInfo, UInt(this.width max that.width), BitOrOp, that).asSInt + /** @group SourceInfoTransformMacro */ def do_^ (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = binop(sourceInfo, UInt(this.width max that.width), BitXorOp, that).asSInt - /** Returns this wire bitwise-inverted. */ + /** @group SourceInfoTransformMacro */ def do_unary_~ (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = unop(sourceInfo, UInt(width = width), BitNotOp).asSInt @@ -695,10 +1086,26 @@ sealed class SInt private[core] (width: Width) extends Bits(width) with Num[SInt @chiselRuntimeDeprecated @deprecated("Use '=/=', which avoids potential precedence problems", "chisel3") final def != (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = this =/= that + + /** Dynamic not equals operator + * + * @param that a hardware $coll + * @return a hardware [[Bool]] asserted if this $coll is not equal to `that` + * @group Comparison + */ final def =/= (that: SInt): Bool = macro SourceInfoTransform.thatArg + + /** Dynamic equals operator + * + * @param that a hardware $coll + * @return a hardware [[Bool]] asserted if this $coll is equal to `that` + * @group Comparison + */ final def === (that: SInt): Bool = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_=/= (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, NotEqualOp, that) + /** @group SourceInfoTransformMacro */ def do_=== (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, EqualOp, that) // final def abs(): UInt = macro SourceInfoTransform.noArg @@ -767,6 +1174,9 @@ sealed trait Reset extends Element with ToBoolable // 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. + * + * @define coll [[Bool]] + * @define numType $coll */ sealed class Bool() extends UInt(1.W) with Reset { private[core] override def cloneTypeWidth(w: Width): this.type = { @@ -774,46 +1184,85 @@ sealed class Bool() extends UInt(1.W) with Reset { new Bool().asInstanceOf[this.type] } + /** Convert to a [[scala.Option]] of [[scala.Boolean]] */ def litToBooleanOption: Option[Boolean] = litOption.map { case intVal if intVal == 1 => true case intVal if intVal == 0 => false case intVal => throwException(s"Boolean with unexpected literal value $intVal") } + /** Convert to a [[scala.Boolean]] */ def litToBoolean: Boolean = litToBooleanOption.get // REVIEW TODO: Why does this need to exist and have different conventions // than Bits? + + /** Bitwise and operator + * + * @param that a hardware $coll + * @return the bitwise and of this $coll and `that` + * @group Bitwise + */ final def & (that: Bool): Bool = macro SourceInfoTransform.thatArg + + /** Bitwise or operator + * + * @param that a hardware $coll + * @return the bitwise or of this $coll and `that` + * @group Bitwise + */ final def | (that: Bool): Bool = macro SourceInfoTransform.thatArg + + /** Bitwise exclusive or (xor) operator + * + * @param that a hardware $coll + * @return the bitwise xor of this $coll and `that` + * @group Bitwise + */ final def ^ (that: Bool): Bool = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_& (that: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = binop(sourceInfo, Bool(), BitAndOp, that) + /** @group SourceInfoTransformMacro */ def do_| (that: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = binop(sourceInfo, Bool(), BitOrOp, that) + /** @group SourceInfoTransformMacro */ def do_^ (that: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = binop(sourceInfo, Bool(), BitXorOp, that) - /** Returns this wire bitwise-inverted. */ + /** @group SourceInfoTransformMacro */ override def do_unary_~ (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = unop(sourceInfo, Bool(), BitNotOp) - /** Outputs the logical OR of two Bools. - */ + /** Logical or operator + * + * @param that a hardware $coll + * @return the lgocial or of this $coll and `that` + * @note this is equivalent to [[Bool.|]] + * @group Logical + */ def || (that: Bool): Bool = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_|| (that: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = this | that - /** Outputs the logical AND of two Bools. - */ + /** Logical and operator + * + * @param that a hardware $coll + * @return the lgocial and of this $coll and `that` + * @note this is equivalent to [[Bool.&]] + * @group Logical + */ def && (that: Bool): Bool = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_&& (that: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = this & that - /** Reinterprets this Bool as a Clock. */ + /** Reinterprets this $coll as a clock */ def asClock(): Clock = macro SourceInfoTransform.noArg + /** @group SourceInfoTransformMacro */ def do_asClock(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Clock = pushOp(DefPrim(sourceInfo, Clock(), AsClockOp, ref)) } @@ -835,17 +1284,19 @@ trait BoolFactory { object Bool extends BoolFactory //scalastyle:off number.of.methods -/** - * A sealed class representing a fixed point number that has a bit width and a binary point - * The width and binary point may be inferred. +/** A sealed class representing a fixed point number that has a bit width and a binary point The width and binary point + * may be inferred. * * IMPORTANT: The API provided here is experimental and may change in the future. * * @param width bit width of the fixed point number - * @param binaryPoint the position of the binary point with respect to the right most bit of the width - * currently this should be positive but it is hoped to soon support negative points - * and thus use this field as a simple exponent - * @param lit + * @param binaryPoint the position of the binary point with respect to the right most bit of the width currently this + * should be positive but it is hoped to soon support negative points and thus use this field as a + * simple exponent + * @define coll [[FixedPoint]] + * @define numType $coll + * @define expandingWidth @note The width of the returned $coll is `width of this` + `1`. + * @define constantWidth @note The width of the returned $coll is unchanged, i.e., `width of this`. */ sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint) extends Bits(width) with Num[FixedPoint] { @@ -862,17 +1313,35 @@ sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint) case _ => this badConnect that } + /** Convert to a [[scala.Option]] of [[scala.Boolean]] */ def litToDoubleOption: Option[Double] = litOption.map { intVal => val multiplier = math.pow(2, binaryPoint.get) intVal.toDouble / multiplier } + /** Convert to a [[scala.Option]] */ def litToDouble: Double = litToDoubleOption.get + + /** Unary negation (expanding width) + * + * @return a hardware $coll equal to zero minus this $coll + * $expandingWidth + * @group Arithmetic + */ final def unary_- (): FixedPoint = macro SourceInfoTransform.noArg + + /** Unary negation (constant width) + * + * @return a hardware $coll equal to zero minus `this` shifted right by one + * $constantWidth + * @group Arithmetic + */ final def unary_-% (): FixedPoint = macro SourceInfoTransform.noArg + /** @group SourceInfoTransformMacro */ def unary_- (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = FixedPoint.fromBigInt(0) - this + /** @group SourceInfoTransformMacro */ def unary_-% (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = FixedPoint.fromBigInt(0) -% this /** add (default - no growth) operator */ @@ -888,23 +1357,70 @@ sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint) override def do_% (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = throwException(s"mod is illegal on FixedPoint types") + + /** Multiplication operator + * + * @param that a hardware [[UInt]] + * @return the product of this $coll and `that` + * $sumWidth + * $singleCycleMul + * @group Arithmetic + */ final def * (that: UInt): FixedPoint = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_* (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = binop(sourceInfo, FixedPoint(this.width + that.width, binaryPoint), TimesOp, that) + /** Multiplication operator + * + * @param that a hardware [[SInt]] + * @return the product of this $coll and `that` + * $sumWidth + * $singleCycleMul + * @group Arithmetic + */ final def * (that: SInt): FixedPoint = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_* (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = binop(sourceInfo, FixedPoint(this.width + that.width, binaryPoint), TimesOp, that) - /** add (width +1) operator */ + /** Addition operator (expanding width) + * + * @param that a hardware $coll + * @return the sum of this $coll and `that` + * $maxWidthPlusOne + * @group Arithmetic + */ final def +& (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg - /** add (no growth) operator */ + + /** Addition operator (constant width) + * + * @param that a hardware $coll + * @return the sum of this $coll and `that` shifted right by one + * $maxWidth + * @group Arithmetic + */ final def +% (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg - /** subtract (width +1) operator */ + + /** Subtraction operator (increasing width) + * + * @param that a hardware $coll + * @return the difference of this $coll less `that` + * $maxWidthPlusOne + * @group Arithmetic + */ final def -& (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg - /** subtract (no growth) operator */ + + /** Subtraction operator (constant width) + * + * @param that a hardware $coll + * @return the difference of this $coll less `that` shifted right by one + * $maxWidth + * @group Arithmetic + */ final def -% (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_+& (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = { (this.width, that.width, this.binaryPoint, that.binaryPoint) match { case (KnownWidth(thisWidth), KnownWidth(thatWidth), KnownBinaryPoint(thisBP), KnownBinaryPoint(thatBP)) => @@ -919,8 +1435,10 @@ sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint) } } + /** @group SourceInfoTransformMacro */ def do_+% (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = (this +& that).tail(1).asFixedPoint(this.binaryPoint max that.binaryPoint) + /** @group SourceInfoTransformMacro */ def do_-& (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = { (this.width, that.width, this.binaryPoint, that.binaryPoint) match { case (KnownWidth(thisWidth), KnownWidth(thatWidth), KnownBinaryPoint(thisBP), KnownBinaryPoint(thatBP)) => @@ -935,22 +1453,50 @@ sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint) } } + /** @group SourceInfoTransformMacro */ def do_-% (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = (this -& that).tail(1).asFixedPoint(this.binaryPoint max that.binaryPoint) + /** Bitwise and operator + * + * @param that a hardware $coll + * @return the bitwise and of this $coll and `that` + * $maxWidth + * @group Bitwise + */ final def & (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg + + /** Bitwise or operator + * + * @param that a hardware $coll + * @return the bitwise or of this $coll and `that` + * $maxWidth + * @group Bitwise + */ final def | (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg + + /** Bitwise exclusive or (xor) operator + * + * @param that a hardware $coll + * @return the bitwise xor of this $coll and `that` + * $maxWidth + * @group Bitwise + */ final def ^ (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_& (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = throwException(s"And is illegal between $this and $that") + /** @group SourceInfoTransformMacro */ def do_| (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = throwException(s"Or is illegal between $this and $that") + /** @group SourceInfoTransformMacro */ def do_^ (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = throwException(s"Xor is illegal between $this and $that") final def setBinaryPoint(that: Int): FixedPoint = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_setBinaryPoint(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = this.binaryPoint match { case KnownBinaryPoint(value) => binop(sourceInfo, FixedPoint(this.width + (that - value), KnownBinaryPoint(that)), SetBinaryPoint, that) @@ -958,7 +1504,7 @@ sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint) binop(sourceInfo, FixedPoint(UnknownWidth(), KnownBinaryPoint(that)), SetBinaryPoint, that) } - /** Returns this wire bitwise-inverted. */ + /** @group SourceInfoTransformMacro */ def do_unary_~ (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = throwException(s"Not is illegal on $this") @@ -969,11 +1515,28 @@ sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint) override def do_>= (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, GreaterEqOp, that) final def != (that: FixedPoint): Bool = macro SourceInfoTransform.thatArg + + /** Dynamic not equals operator + * + * @param that a hardware $coll + * @return a hardware [[Bool]] asserted if this $coll is not equal to `that` + * @group Comparison + */ final def =/= (that: FixedPoint): Bool = macro SourceInfoTransform.thatArg + + /** Dynamic equals operator + * + * @param that a hardware $coll + * @return a hardware [[Bool]] asserted if this $coll is equal to `that` + * @group Comparison + */ final def === (that: FixedPoint): Bool = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_!= (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, NotEqualOp, that) + /** @group SourceInfoTransformMacro */ def do_=/= (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, NotEqualOp, that) + /** @group SourceInfoTransformMacro */ def do_=== (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, EqualOp, that) def do_abs(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = { diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala index 171a2bff..cab6075e 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala @@ -7,7 +7,8 @@ import scala.language.experimental.macros import chisel3.internal._ import chisel3.internal.Builder.{pushCommand, pushOp} import chisel3.internal.firrtl._ -import chisel3.internal.sourceinfo._ +import chisel3.internal.sourceinfo.{SourceInfo, SourceInfoTransform, UnlocatableSourceInfo, DeprecatedSourceInfo} +import chisel3.SourceInfoDoc import chisel3.core.BiConnect.DontCareCantBeSink /** User-specified directions. @@ -197,8 +198,11 @@ object Flipped { * 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. + * + * @groupdesc Connect Utilities for connecting hardware components + * @define coll data */ -abstract class Data extends HasId with NamedComponent { +abstract class Data extends HasId with NamedComponent with SourceInfoDoc { // This is a bad API that punches through object boundaries. @deprecated("pending removal once all instances replaced", "chisel3") private[chisel3] def flatten: IndexedSeq[Element] = { @@ -381,7 +385,22 @@ abstract class Data extends HasId with NamedComponent { clone } + /** Connect this $coll to that $coll mono-directionally and element-wise. + * + * This uses the [[MonoConnect]] algorithm. + * + * @param that the $coll to connect to + * @group Connect + */ final def := (that: Data)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Unit = this.connect(that)(sourceInfo, connectionCompileOptions) + + /** Connect this $coll to that $coll bi-directionally and element-wise. + * + * This uses the [[BiConnect]] algorithm. + * + * @param that the $coll to connect to + * @group Connect + */ final def <> (that: Data)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Unit = this.bulkConnect(that)(sourceInfo, connectionCompileOptions) @chiselRuntimeDeprecated @@ -432,6 +451,7 @@ abstract class Data extends HasId with NamedComponent { */ def asTypeOf[T <: Data](that: T): T = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_asTypeOf[T <: Data](that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { val thatCloned = Wire(that.cloneTypeFull) thatCloned.connectFromBits(this.asUInt()) @@ -452,6 +472,7 @@ abstract class Data extends HasId with NamedComponent { */ final def asUInt(): UInt = macro SourceInfoTransform.noArg + /** @group SourceInfoTransformMacro */ def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt /** Default pretty printing */ diff --git a/chiselFrontend/src/main/scala/chisel3/core/Mem.scala b/chiselFrontend/src/main/scala/chisel3/core/Mem.scala index 73bf3708..09e30fec 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Mem.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Mem.scala @@ -8,6 +8,7 @@ import chisel3.internal._ import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl._ import chisel3.internal.sourceinfo.{SourceInfo, SourceInfoTransform, UnlocatableSourceInfo, MemTransform} +import chisel3.SourceInfoDoc object Mem { @chiselRuntimeDeprecated @@ -20,6 +21,8 @@ object Mem { * @param t data type of memory element */ def apply[T <: Data](size: Int, t: T): Mem[T] = macro MemTransform.apply[T] + + /** @group SourceInfoTransformMacro */ def do_apply[T <: Data](size: Int, t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Mem[T] = { if (compileOptions.declaredTypeMustBeUnbound) { requireIsChiselType(t, "memory type") @@ -31,7 +34,7 @@ object Mem { } } -sealed abstract class MemBase[T <: Data](t: T, val length: Int) extends HasId with NamedComponent { +sealed abstract class MemBase[T <: Data](t: T, val length: Int) extends HasId with NamedComponent with SourceInfoDoc { // REVIEW TODO: make accessors (static/dynamic, read/write) combinations consistent. /** Creates a read accessor into the memory with static addressing. See the @@ -39,6 +42,7 @@ sealed abstract class MemBase[T <: Data](t: T, val length: Int) extends HasId wi */ def apply(x: Int): T = macro SourceInfoTransform.xArg + /** @group SourceInfoTransformMacro */ def do_apply(idx: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { require(idx >= 0 && idx < length) apply(idx.asUInt) @@ -49,6 +53,7 @@ sealed abstract class MemBase[T <: Data](t: T, val length: Int) extends HasId wi */ def apply(x: UInt): T = macro SourceInfoTransform.xArg + /** @group SourceInfoTransformMacro */ def do_apply(idx: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = makePort(sourceInfo, idx, MemPortDirection.INFER) @@ -57,6 +62,7 @@ sealed abstract class MemBase[T <: Data](t: T, val length: Int) extends HasId wi */ def read(x: UInt): T = macro SourceInfoTransform.xArg + /** @group SourceInfoTransformMacro */ def do_read(idx: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = makePort(sourceInfo, idx, MemPortDirection.READ) @@ -130,6 +136,7 @@ object SyncReadMem { */ def apply[T <: Data](size: Int, t: T): SyncReadMem[T] = macro MemTransform.apply[T] + /** @group SourceInfoTransformMacro */ def do_apply[T <: Data](size: Int, t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SyncReadMem[T] = { if (compileOptions.declaredTypeMustBeUnbound) { requireIsChiselType(t, "memory type") @@ -154,6 +161,7 @@ object SyncReadMem { sealed class SyncReadMem[T <: Data] private (t: T, n: Int) extends MemBase[T](t, n) { def read(x: UInt, en: Bool): T = macro SourceInfoTransform.xEnArg + /** @group SourceInfoTransformMacro */ def do_read(addr: UInt, enable: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { val a = Wire(UInt()) a := DontCare diff --git a/chiselFrontend/src/main/scala/chisel3/core/Module.scala b/chiselFrontend/src/main/scala/chisel3/core/Module.scala index 0cf05496..399f0462 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Module.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Module.scala @@ -12,10 +12,11 @@ import chisel3.internal._ import chisel3.internal.Builder._ import chisel3.internal.firrtl._ import chisel3.internal.sourceinfo.{InstTransform, SourceInfo} +import chisel3.SourceInfoDoc import _root_.firrtl.annotations.{CircuitName, ModuleName} -object Module { +object Module extends SourceInfoDoc { /** A wrapper method that all Module instantiations must be wrapped in * (necessary to help Chisel track internal state). * @@ -25,6 +26,7 @@ object Module { */ def apply[T <: BaseModule](bc: => T): T = macro InstTransform.apply[T] + /** @group SourceInfoTransformMacro */ def do_apply[T <: BaseModule](bc: => T) (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { diff --git a/chiselFrontend/src/main/scala/chisel3/core/Mux.scala b/chiselFrontend/src/main/scala/chisel3/core/Mux.scala index e4ef001f..56c145b5 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Mux.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Mux.scala @@ -9,8 +9,9 @@ import chisel3.internal.Builder.{pushOp} import chisel3.internal.sourceinfo.{SourceInfo, MuxTransform} import chisel3.internal.firrtl._ import chisel3.internal.firrtl.PrimOp._ +import chisel3.SourceInfoDoc -object Mux { +object Mux extends SourceInfoDoc { /** Creates a mux, whose output is one of the inputs depending on the * value of the condition. * @@ -24,6 +25,7 @@ object Mux { */ def apply[T <: Data](cond: Bool, con: T, alt: T): T = macro MuxTransform.apply[T] + /** @group SourceInfoTransformMacro */ def do_apply[T <: Data](cond: Bool, con: T, alt: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { requireIsHardware(cond, "mux condition") diff --git a/chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala b/chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala index 69f54102..e87fb045 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala @@ -18,6 +18,7 @@ private[chisel3] object SeqUtils { */ def asUInt[T <: Bits](in: Seq[T]): UInt = macro SourceInfoTransform.inArg + /** @group SourceInfoTransformMacros */ def do_asUInt[T <: Bits](in: Seq[T])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = { if (in.tail.isEmpty) { in.head.asUInt @@ -32,6 +33,7 @@ private[chisel3] object SeqUtils { */ def count(in: Seq[Bool]): UInt = macro SourceInfoTransform.inArg + /** @group SourceInfoTransformMacros */ def do_count(in: Seq[Bool])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = in.size match { case 0 => 0.U case 1 => in.head @@ -42,6 +44,7 @@ private[chisel3] object SeqUtils { */ def priorityMux[T <: Data](in: Seq[(Bool, T)]): T = macro SourceInfoTransform.inArg + /** @group SourceInfoTransformMacros */ def do_priorityMux[T <: Data](in: Seq[(Bool, T)]) (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { if (in.size == 1) { @@ -60,6 +63,7 @@ private[chisel3] object SeqUtils { def oneHotMux[T <: Data](in: Iterable[(Bool, T)]): T = macro SourceInfoTransform.inArg //scalastyle:off method.length cyclomatic.complexity + /** @group SourceInfoTransformMacros */ def do_oneHotMux[T <: Data](in: Iterable[(Bool, T)]) (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { if (in.tail.isEmpty) { diff --git a/coreMacros/src/main/scala/chisel3/SourceInfoDoc.scala b/coreMacros/src/main/scala/chisel3/SourceInfoDoc.scala new file mode 100644 index 00000000..ad320d5d --- /dev/null +++ b/coreMacros/src/main/scala/chisel3/SourceInfoDoc.scala @@ -0,0 +1,42 @@ +// See LICENSE for license details + +package chisel3 + +/** Provides ScalaDoc information for "hidden" `do_*` methods + * + * Mix this into classes/objects that have `do_*` methods to get access to the shared `SourceInfoTransformMacro` + * ScalaDoc group and the lengthy `groupdesc` below. + * + * @groupdesc SourceInfoTransformMacro + * + * <p> + * '''These internal methods are not part of the public-facing API!''' + * <br> + * <br> + * + * The equivalent public-facing methods do not have the `do_` prefix or have the same name. Use and look at the + * documentation for those. If you want left shift, use `<<`, not `do_<<`. If you want comversion to a [[Seq]] of + * [[Bool]]s look at the `toBools` above, not the one below. Users can safely ignore every method in this group! + * <br> + * <br> + * + * 🐉🐉🐉 '''Here be dragons...''' 🐉🐉🐉 + * <br> + * <br> + * + * These `do_X` methods are used to enable both implicit passing of [[SourceInfo]] and + * [[chisel3.core.CompileOptions]] while also supporting chained apply methods. In effect all "normal" methods that + * you, as a user, will use in your designs, are converted to their "hidden", `do_*`, via macro transformations. + * Without using macros here, only one of the above wanted behaviors is allowed (implicit passing and chained + * applies)---the compiler interprets a chained apply as an explicit 'implicit' argument and will throw type errors. + * <br> + * <br> + * + * The "normal", public-facing methods then take no [[SourceInfo]]. However, a macro transforms this public-facing + * method into a call to an internal, hidden `do_*` that takes an explicit [[SourceInfo]] by inserting an + * `implicitly[SourceInfo]` as the explicit argument. + * </p> + * + * @groupprio SourceInfoTransformMacro 1001 + */ +trait SourceInfoDoc diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala index 0212aca9..1d0c0ff7 100644 --- a/src/main/scala/chisel3/compatibility.scala +++ b/src/main/scala/chisel3/compatibility.scala @@ -120,15 +120,18 @@ package object Chisel { // scalastyle:ignore package.object.name apply(Seq.fill(n)(gen)) def apply[T <: Data](elts: Seq[T]): Vec[T] = macro VecTransform.apply_elts + /** @group SourceInfoTransformMacro */ def do_apply[T <: Data](elts: Seq[T])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = chisel3.core.VecInit(elts) def apply[T <: Data](elt0: T, elts: T*): Vec[T] = macro VecTransform.apply_elt0 + /** @group SourceInfoTransformMacro */ def do_apply[T <: Data](elt0: T, elts: T*) (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = chisel3.core.VecInit(elt0 +: elts.toSeq) def tabulate[T <: Data](n: Int)(gen: (Int) => T): Vec[T] = macro VecTransform.tabulate + /** @group SourceInfoTransformMacro */ def do_tabulate[T <: Data](n: Int)(gen: (Int) => T) (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = chisel3.core.VecInit.tabulate(n)(gen) diff --git a/src/main/scala/chisel3/package.scala b/src/main/scala/chisel3/package.scala index 7f1ad040..b7c39bad 100644 --- a/src/main/scala/chisel3/package.scala +++ b/src/main/scala/chisel3/package.scala @@ -50,11 +50,11 @@ package object chisel3 { // scalastyle:ignore package.object.name @chiselRuntimeDeprecated @deprecated("Input(Data) should be used over Data.asInput", "chisel3") def asInput: T = Input(target) - + @chiselRuntimeDeprecated @deprecated("Output(Data) should be used over Data.asOutput", "chisel3") def asOutput: T = Output(target) - + @chiselRuntimeDeprecated @deprecated("Flipped(Data) should be used over Data.flip", "chisel3") def flip(): T = Flipped(target) @@ -152,7 +152,7 @@ package object chisel3 { // scalastyle:ignore package.object.name @chiselRuntimeDeprecated @deprecated("use n.U", "chisel3, will be removed by end of 2017") def apply(n: String): UInt = n.asUInt - + /** Create a UInt literal with fixed width. */ @chiselRuntimeDeprecated @deprecated("use n.U(width.W)", "chisel3, will be removed by end of 2017") @@ -192,7 +192,7 @@ package object chisel3 { // scalastyle:ignore package.object.name @chiselRuntimeDeprecated @deprecated("use SInt(width.W)", "chisel3, will be removed by end of 2017") def width(width: Int): SInt = apply(width.W) - + /** Create an SInt type with specified width. */ @chiselRuntimeDeprecated @deprecated("use SInt(width)", "chisel3, will be removed by end of 2017") @@ -202,7 +202,7 @@ package object chisel3 { // scalastyle:ignore package.object.name @chiselRuntimeDeprecated @deprecated("use value.S", "chisel3, will be removed by end of 2017") def apply(value: BigInt): SInt = value.asSInt - + /** Create an SInt literal with fixed width. */ @chiselRuntimeDeprecated @deprecated("use value.S(width.W)", "chisel3, will be removed by end of 2017") @@ -257,7 +257,7 @@ package object chisel3 { // scalastyle:ignore package.object.name val SeqMem = chisel3.core.SyncReadMem @deprecated("Use 'SyncReadMem'", "chisel3") type SeqMem[T <: Data] = chisel3.core.SyncReadMem[T] - + val Module = chisel3.core.Module type Module = chisel3.core.LegacyModule @@ -367,18 +367,20 @@ package object chisel3 { // scalastyle:ignore package.object.name implicit class fromIntToWidth(x: Int) extends chisel3.core.fromIntToWidth(x) implicit class fromIntToBinaryPoint(x: Int) extends chisel3.core.fromIntToBinaryPoint(x) - implicit class fromUIntToBitPatComparable(x: UInt) { + implicit class fromUIntToBitPatComparable(x: UInt) extends chisel3.SourceInfoDoc { import scala.language.experimental.macros import internal.sourceinfo.{SourceInfo, SourceInfoTransform} final def === (that: BitPat): Bool = macro SourceInfoTransform.thatArg final def =/= (that: BitPat): Bool = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_=== (that: BitPat) // scalastyle:ignore method.name (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = that === x + /** @group SourceInfoTransformMacro */ def do_=/= (that: BitPat) // scalastyle:ignore method.name (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = that =/= x - + final def != (that: BitPat): Bool = macro SourceInfoTransform.thatArg @chiselRuntimeDeprecated @deprecated("Use '=/=', which avoids potential precedence problems", "chisel3") diff --git a/src/main/scala/chisel3/util/BitPat.scala b/src/main/scala/chisel3/util/BitPat.scala index 6ff08bea..6cba497e 100644 --- a/src/main/scala/chisel3/util/BitPat.scala +++ b/src/main/scala/chisel3/util/BitPat.scala @@ -88,15 +88,17 @@ object BitPat { * "b10001".U === BitPat("b101??") // evaluates to false.B * }}} */ -sealed class BitPat(val value: BigInt, val mask: BigInt, width: Int) { +sealed class BitPat(val value: BigInt, val mask: BigInt, width: Int) extends SourceInfoDoc { def getWidth: Int = width def === (that: UInt): Bool = macro SourceInfoTransform.thatArg def =/= (that: UInt): Bool = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ def do_=== (that: UInt) // scalastyle:ignore method.name (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = { value.asUInt === (that & mask.asUInt) } + /** @group SourceInfoTransformMacro */ def do_=/= (that: UInt) // scalastyle:ignore method.name (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = { !(this === that) |
