From f4b01bc40d16a6cee1b6848e9e5ea0616df4bada Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Wed, 20 Nov 2024 12:00:29 -0800 Subject: [PATCH 01/30] Add Scala3 sources --- core/src/main/scala-3/chisel3/Aggregate.scala | 270 ++++++++ core/src/main/scala-3/chisel3/Bits.scala | 648 ++++++++++++++++++ .../src/main/scala-3/chisel3/ChiselEnum.scala | 18 + core/src/main/scala-3/chisel3/Clock.scala | 16 + core/src/main/scala-3/chisel3/Data.scala | 37 + core/src/main/scala-3/chisel3/Disable.scala | 29 + core/src/main/scala-3/chisel3/Mem.scala | 313 +++++++++ core/src/main/scala-3/chisel3/Module.scala | 27 + core/src/main/scala-3/chisel3/Mux.scala | 27 + core/src/main/scala-3/chisel3/Num.scala | 144 ++++ core/src/main/scala-3/chisel3/Printf.scala | 59 ++ .../main/scala-3/chisel3/PrintfMacros.scala | 35 + .../main/scala-3/chisel3/SourceInfoDoc.scala | 6 + .../chisel3/VerificationStatement.scala | 58 ++ .../chisel3/VerificationStatementMacros.scala | 36 + .../chisel3/experimental/SourceInfo.scala | 55 ++ .../dataview/ChiselSubtypeOf.scala | 5 + .../dataview/InvertibleDataView.scala | 7 + .../hierarchy/HierarchyMarker.scala | 3 + .../hierarchy/core/Hierarchy.scala | 62 ++ .../main/scala-3/chisel3/probe/Probe.scala | 24 + .../scala-3/chisel3/probe/ProbeValue.scala | 18 + .../main/scala-3/chisel3/probe/package.scala | 15 + .../scala-3/chisel3/properties/Object.scala | 31 + firrtl/src/main/scala-3/Macros.scala | 13 + src/main/scala-3/chisel3/FixedIOModule.scala | 36 + .../scala-3/chisel3/choice/ModuleChoice.scala | 35 + src/main/scala-3/chisel3/util/BitPat.scala | 26 + src/main/scala-3/chisel3/util/Bitwise.scala | 83 +++ src/main/scala-3/chisel3/util/Cat.scala | 32 + src/main/scala-3/chisel3/util/Mux.scala | 40 ++ src/main/scala-3/chisel3/util/Reg.scala | 148 ++++ src/main/scala-3/chisel3/util/Switch.scala | 12 + 33 files changed, 2368 insertions(+) create mode 100644 core/src/main/scala-3/chisel3/Aggregate.scala create mode 100644 core/src/main/scala-3/chisel3/Bits.scala create mode 100644 core/src/main/scala-3/chisel3/ChiselEnum.scala create mode 100644 core/src/main/scala-3/chisel3/Clock.scala create mode 100644 core/src/main/scala-3/chisel3/Data.scala create mode 100644 core/src/main/scala-3/chisel3/Disable.scala create mode 100644 core/src/main/scala-3/chisel3/Mem.scala create mode 100644 core/src/main/scala-3/chisel3/Module.scala create mode 100644 core/src/main/scala-3/chisel3/Mux.scala create mode 100644 core/src/main/scala-3/chisel3/Num.scala create mode 100644 core/src/main/scala-3/chisel3/Printf.scala create mode 100644 core/src/main/scala-3/chisel3/PrintfMacros.scala create mode 100644 core/src/main/scala-3/chisel3/SourceInfoDoc.scala create mode 100644 core/src/main/scala-3/chisel3/VerificationStatement.scala create mode 100644 core/src/main/scala-3/chisel3/VerificationStatementMacros.scala create mode 100644 core/src/main/scala-3/chisel3/experimental/SourceInfo.scala create mode 100644 core/src/main/scala-3/chisel3/experimental/dataview/ChiselSubtypeOf.scala create mode 100644 core/src/main/scala-3/chisel3/experimental/dataview/InvertibleDataView.scala create mode 100644 core/src/main/scala-3/chisel3/experimental/hierarchy/HierarchyMarker.scala create mode 100644 core/src/main/scala-3/chisel3/experimental/hierarchy/core/Hierarchy.scala create mode 100644 core/src/main/scala-3/chisel3/probe/Probe.scala create mode 100644 core/src/main/scala-3/chisel3/probe/ProbeValue.scala create mode 100644 core/src/main/scala-3/chisel3/probe/package.scala create mode 100644 core/src/main/scala-3/chisel3/properties/Object.scala create mode 100644 firrtl/src/main/scala-3/Macros.scala create mode 100644 src/main/scala-3/chisel3/FixedIOModule.scala create mode 100644 src/main/scala-3/chisel3/choice/ModuleChoice.scala create mode 100644 src/main/scala-3/chisel3/util/BitPat.scala create mode 100644 src/main/scala-3/chisel3/util/Bitwise.scala create mode 100644 src/main/scala-3/chisel3/util/Cat.scala create mode 100644 src/main/scala-3/chisel3/util/Mux.scala create mode 100644 src/main/scala-3/chisel3/util/Reg.scala create mode 100644 src/main/scala-3/chisel3/util/Switch.scala diff --git a/core/src/main/scala-3/chisel3/Aggregate.scala b/core/src/main/scala-3/chisel3/Aggregate.scala new file mode 100644 index 00000000000..35a6d34b118 --- /dev/null +++ b/core/src/main/scala-3/chisel3/Aggregate.scala @@ -0,0 +1,270 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3 + +import chisel3.experimental.VecLiterals.AddVecLiteralConstructor + +import scala.collection.immutable.{SeqMap, VectorMap} +import scala.collection.mutable.{HashSet, LinkedHashMap} +import chisel3.experimental.{BaseModule, BundleLiteralException, OpaqueType, SourceInfo, VecLiteralException} +import chisel3.internal._ +import chisel3.internal.Builder.pushCommand +import chisel3.internal.firrtl._ + +import java.lang.Math.{floor, log10, pow} +import scala.collection.mutable + +/** An abstract class for data types that solely consist of (are an aggregate + * of) other Data objects. + */ +sealed trait Aggregate extends AggregateImpl + +/** A vector (array) of [[Data]] elements. Provides hardware versions of various + * collection transformation functions found in software array implementations. + * + * Careful consideration should be given over the use of [[Vec]] vs + * [[scala.collection.immutable.Seq Seq]] or some other Scala collection. In general [[Vec]] only + * needs to be used when there is a need to express the hardware collection in a [[Reg]] or IO + * [[Bundle]] or when access to elements of the array is indexed via a hardware signal. + * + * Example of indexing into a [[Vec]] using a hardware address and where the [[Vec]] is defined in + * an IO [[Bundle]] + * + * {{{ + * val io = IO(new Bundle { + * val in = Input(Vec(20, UInt(16.W))) + * val addr = Input(UInt(5.W)) + * val out = Output(UInt(16.W)) + * }) + * io.out := io.in(io.addr) + * }}} + * + * @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) + * - 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[chisel3] (gen: => T, length: Int) + extends VecImpl[T](gen, length) + with VecLike[T] + with Aggregate { + + override def toString: String = super[VecImpl].toString + + def apply(p: UInt)(implicit sourceInfo: SourceInfo): T = do_apply(p) + def do_apply(p: UInt)(implicit sourceInfo: SourceInfo): T = _applyImpl(p) + + /** A reduce operation in a tree like structure instead of sequentially + * @example An adder tree + * {{{ + * val sumOut = inputNums.reduceTree((a: T, b: T) => (a + b)) + * }}} + */ + // def reduceTree(redOp: (T, T) => T): T = macro VecTransform.reduceTreeDefault + + /** A reduce operation in a tree like structure instead of sequentially + * @example A pipelined adder tree + * {{{ + * val sumOut = inputNums.reduceTree( + * (a: T, b: T) => RegNext(a + b), + * (a: T) => RegNext(a) + * ) + * }}} + */ + def reduceTree( + redOp: (T, T) => T, + layerOp: (T) => T = (x: T) => x + )( + implicit sourceInfo: SourceInfo + ): T = _reduceTreeImpl(redOp, layerOp) +} + +object Vec extends VecFactory + +object VecInit extends VecInitImpl with SourceInfoDoc { + + /** 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])(implicit sourceInfo: SourceInfo): Vec[T] = _applyImpl(elts) + + /** 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*)(implicit sourceInfo: SourceInfo): Vec[T] = _applyImpl(elt0, elts: _*) + + /** 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 + )( + implicit sourceInfo: SourceInfo + ): Vec[T] = _tabulateImpl(n)(gen) + + /** Creates a new 2D [[Vec]] of length `n by m` composed of the results of the given + * function applied over a range of integer values starting from 0. + * + * @param n number of 1D vectors inside outer vector + * @param m number of elements in each 1D 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, + m: Int + )(gen: (Int, Int) => T + )( + implicit sourceInfo: SourceInfo + ): Vec[Vec[T]] = _tabulateImpl(n, m)(gen) + + /** Creates a new 3D [[Vec]] of length `n by m by p` composed of the results of the given + * function applied over a range of integer values starting from 0. + * + * @param n number of 2D vectors inside outer vector + * @param m number of 1D vectors in each 2D vector + * @param p number of elements in each 1D vector + * @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, + m: Int, + p: Int + )(gen: (Int, Int, Int) => T + )( + implicit sourceInfo: SourceInfo + ): Vec[Vec[Vec[T]]] = _tabulateImpl(n, m, p)(gen) + + /** Creates a new [[Vec]] of length `n` composed of the result of the given + * function applied to an element of data type T. + * + * @param n number of elements in the vector + * @param gen function that takes in an element T and returns an output + * element of the same type + */ + def fill[T <: Data](n: Int)(gen: => T)(implicit sourceInfo: SourceInfo): Vec[T] = _fillImpl(n)(gen) + + /** Creates a new 2D [[Vec]] of length `n by m` composed of the result of the given + * function applied to an element of data type T. + * + * @param n number of inner vectors (rows) in the outer vector + * @param m number of elements in each inner vector (column) + * @param gen function that takes in an element T and returns an output + * element of the same type + */ + def fill[T <: Data]( + n: Int, + m: Int + )(gen: => T + )( + implicit sourceInfo: SourceInfo + ): Vec[Vec[T]] = _fillImpl(n, m)(gen) + + /** Creates a new 3D [[Vec]] of length `n by m by p` composed of the result of the given + * function applied to an element of data type T. + * + * @param n number of 2D vectors inside outer vector + * @param m number of 1D vectors in each 2D vector + * @param p number of elements in each 1D vector + * @param gen function that takes in an element T and returns an output + * element of the same type + */ + def fill[T <: Data]( + n: Int, + m: Int, + p: Int + )(gen: => T + )( + implicit sourceInfo: SourceInfo + ): Vec[Vec[Vec[T]]] = _fillImpl(n, m, p)(gen) + + /** Creates a new [[Vec]] of length `n` composed of the result of the given + * function applied to an element of data type T. + * + * @param start First element in the Vec + * @param len Lenth of elements in the Vec + * @param f Function that applies the element T from previous index and returns the output + * element to the next index + */ + def iterate[T <: Data]( + start: T, + len: Int + )(f: (T) => T + )( + implicit sourceInfo: SourceInfo + ): Vec[T] = _iterateImpl(start, len)(f) +} + +/** A trait for [[Vec]]s containing common hardware generators for collection + * operations. + */ +trait VecLike[T <: Data] extends VecLikeImpl[T] with SourceInfoDoc { + + /** Creates a dynamically indexed read or write accessor into the array. + */ + def apply(p: UInt)(implicit sourceInfo: SourceInfo): T + + /** Outputs true if p outputs true for every element. + */ + def forall(p: T => Bool)(implicit sourceInfo: SourceInfo): Bool = _forallImpl(p) + + /** Outputs true if p outputs true for at least one element. + */ + def exists(p: T => Bool)(implicit sourceInfo: SourceInfo): Bool = _existsImpl(p) + + /** Outputs true if the vector contains at least one element equal to x (using + * the === operator). + */ + def contains(x: T)(implicit sourceInfo: SourceInfo, ev: T <:< UInt): Bool = _containsImpl(x) + + /** Outputs the number of elements for which p is true. + */ + def count(p: T => Bool)(implicit sourceInfo: SourceInfo): UInt = _countImpl(p) + + /** Outputs the index of the first element for which p outputs true. + */ + def indexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo): UInt = _indexWhereImpl(p) + + /** Outputs the index of the last element for which p outputs true. + */ + def lastIndexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo): UInt = _lastIndexWhereImpl(p) + + /** 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)(implicit sourceInfo: SourceInfo): UInt = _onlyIndexWhereImpl(p) +} + +/** Base class for Aggregates based on key values pairs of String and Data + * + * Record should only be extended by libraries and fairly sophisticated generators. + * RTL writers should use [[Bundle]]. See [[Record#elements]] for an example. + */ +abstract class Record extends Aggregate with RecordImpl diff --git a/core/src/main/scala-3/chisel3/Bits.scala b/core/src/main/scala-3/chisel3/Bits.scala new file mode 100644 index 00000000000..1c94b3a3b3b --- /dev/null +++ b/core/src/main/scala-3/chisel3/Bits.scala @@ -0,0 +1,648 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3 + +import chisel3.internal._ +import chisel3.internal.Builder.pushOp +import chisel3.internal.firrtl.ir._ +import chisel3.internal.firrtl.ir.PrimOp._ +import chisel3.experimental.{requireIsHardware, SourceInfo} + +/** 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 { + def asBool: Bool +} + +/** 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`. + */ +sealed abstract class Bits(private[chisel3] val width: Width) extends BitsImpl with ToBoolable { + + /** Tail operator + * + * @param n the number of bits to remove + * @return This $coll with the `n` most significant bits removed. + * @group Bitwise + */ + def tail(n: Int)(implicit sourceInfo: SourceInfo): UInt = _tailImpl(n) + + /** Head operator + * + * @param n the number of bits to take + * @return The `n` most significant bits of this $coll + * @group Bitwise + */ + def head(n: Int)(implicit sourceInfo: SourceInfo): UInt = _headImpl(n) + + /** Returns the specified bit on this $coll as a [[Bool]], statically addressed. + * + * @param x an index + * @return the specified bit + */ + + final def extract(x: BigInt)(implicit sourceInfo: SourceInfo): Bool = _extractImpl(x) + + /** Returns the specified bit on this $coll as a [[Bool]], statically addressed. + * + * @param x an index + * @return the specified bit + */ + final def apply(x: Int)(implicit sourceInfo: SourceInfo): Bool = _applyImpl(x) + + /** Grab the bottom n bits. Return 0.U(0.W) if n==0. */ + final def take(n: Int)(implicit sourceInfo: SourceInfo): UInt = _takeImpl(n) + + /** 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 extract(x: UInt)(implicit sourceInfo: SourceInfo): Bool = _extractImpl(x) + + /** 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)(implicit sourceInfo: SourceInfo): Bool = _applyImpl(x) + + /** 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)(implicit sourceInfo: SourceInfo): UInt = _applyImpl(x, y) + + // 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)(implicit sourceInfo: SourceInfo): UInt = _applyImpl(x, y) + + /** Pad operator + * + * @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 + */ + def pad(that: Int)(implicit sourceInfo: SourceInfo): Bits = _padImpl(that) + + /** Bitwise inversion operator + * + * @return this $coll with each bit inverted + * @group Bitwise + */ + def unary_~(implicit sourceInfo: SourceInfo): Bits = _impl_unary_~ + + /** 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 + */ + def <<(that: BigInt)(implicit sourceInfo: SourceInfo): Bits = _impl_<<(that) + + /** 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 + */ + def <<(that: Int)(implicit sourceInfo: SourceInfo): Bits = _impl_<<(that) + + /** Dynamic left shift operator + * + * @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) - 1`. + * @group Bitwise + */ + def <<(that: UInt)(implicit sourceInfo: SourceInfo): Bits = _impl_<<(that) + + /** Static right shift operator + * + * @param that an amount to shift by + * @return this $coll with `that` many least significant bits truncated + * $unchangedWidth + * @group Bitwise + */ + def >>(that: BigInt)(implicit sourceInfo: SourceInfo): Bits = _impl_>>(that) + + /** Static right shift operator + * + * @param that an amount to shift by + * @return this $coll with `that` many least significant bits truncated + * $unchangedWidth + * @group Bitwise + */ + def >>(that: Int)(implicit sourceInfo: SourceInfo): Bits = _impl_>>(that) + + /** Dynamic right shift operator + * + * @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 + */ + def >>(that: UInt)(implicit sourceInfo: SourceInfo): Bits = _impl_>>(that) + + /** Returns the contents of this wire as a [[scala.collection.Seq]] of [[Bool]]. */ + def asBools(implicit sourceInfo: SourceInfo): Seq[Bool] = _asBoolsImpl + + /** Reinterpret this $coll as an [[SInt]] + * + * @note The arithmetic value is not preserved if the most-significant bit is set. For example, a [[UInt]] of + * width 3 and value 7 (0b111) would become an [[SInt]] of width 3 and value -1. + */ + def asSInt(implicit sourceInfo: SourceInfo): SInt = _asSIntImpl + + def asBool: Bool = _asBoolImpl + + /** Concatenation operator + * + * @param that a hardware component + * @return this $coll concatenated to the most significant end of `that` + * $sumWidth + * @group Bitwise + */ + def ##(that: Bits)(implicit sourceInfo: SourceInfo): UInt = _impl_##(that) +} + +object Bits extends UIntFactory + +/** 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[chisel3] (width: Width) extends Bits(width) with UIntImpl { + + // TODO: refactor to share documentation with Num or add independent scaladoc + /** Unary negation (expanding width) + * + * @return a $coll equal to zero minus this $coll + * $constantWidth + * @group Arithmetic + */ + def unary_-(implicit sourceInfo: SourceInfo): UInt = _impl_unary_- + + /** Unary negation (constant width) + * + * @return a $coll equal to zero minus this $coll shifted right by one. + * $constantWidth + * @group Arithmetic + */ + def unary_-%(implicit sourceInfo: SourceInfo): UInt = _impl_unary_-% + + override def +(that: UInt): UInt = _impl_+(that) + override def -(that: UInt): UInt = _impl_-(that) + override def /(that: UInt): UInt = _impl_/(that) + override def %(that: UInt): UInt = _impl_%(that) + override def *(that: UInt): UInt = _impl_*(that) + + /** Multiplication operator + * + * @param that a hardware [[SInt]] + * @return the product of this $coll and `that` + * $sumWidth + * $singleCycleMul + * @group Arithmetic + */ + def *(that: SInt): SInt = _impl_*(that) + + /** Addition operator (expanding width) + * + * @param that a hardware $coll + * @return the sum of this $coll and `that` + * $maxWidthPlusOne + * @group Arithmetic + */ + def +&(that: UInt): UInt = _impl_+&(that) + + /** Addition operator (constant width) + * + * @param that a hardware $coll + * @return the sum of this $coll and `that` + * $maxWidth + * @group Arithmetic + */ + def +%(that: UInt): UInt = _impl_+%(that) + + /** Subtraction operator (increasing width) + * + * @param that a hardware $coll + * @return the difference of this $coll less `that` + * $maxWidthPlusOne + * @group Arithmetic + */ + def -&(that: UInt): UInt = _impl_-&(that) + + /** Subtraction operator (constant width) + * + * @param that a hardware $coll + * @return the difference of this $coll less `that` + * $maxWidth + * @group Arithmetic + */ + def -%(that: UInt): UInt = _impl_-%(that) + + /** Bitwise and operator + * + * @param that a hardware $coll + * @return the bitwise and of this $coll and `that` + * $maxWidth + * @group Bitwise + */ + def &(that: UInt): UInt = _impl_&(that) + + /** Bitwise or operator + * + * @param that a hardware $coll + * @return the bitwise or of this $coll and `that` + * $maxWidth + * @group Bitwise + */ + def |(that: UInt): UInt = _impl_|(that) + + /** Bitwise exclusive or (xor) operator + * + * @param that a hardware $coll + * @return the bitwise xor of this $coll and `that` + * $maxWidth + * @group Bitwise + */ + def ^(that: UInt): UInt = _impl_^(that) + + def abs: UInt = _absImpl + + override def unary_~(implicit sourceInfo: SourceInfo) = _impl_unary_~ + + // 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 + */ + def orR: Bool = _orRImpl + + /** And reduction operator + * + * @return a hardware [[Bool]] resulting from every bit of this $coll and'd together + * @group Bitwise + */ + def andR: Bool = _andRImpl + + /** Exclusive or (xor) reduction operator + * + * @return a hardware [[Bool]] resulting from every bit of this $coll xor'd together + * @group Bitwise + */ + final def xorR(implicit sourceInfo: SourceInfo): Bool = _xorRImpl + + override def <(that: UInt): Bool = _impl_<(that) + override def >(that: UInt): Bool = _impl_>(that) + override def <=(that: UInt): Bool = _impl_<=(that) + override def >=(that: UInt): Bool = _impl_>=(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 + */ + def =/=(that: UInt)(implicit sourceInfo: SourceInfo): Bool = _impl_=/=(that) + + /** Dynamic equals operator + * + * @param that a hardware $coll + * @return a hardware [[Bool]] asserted if this $coll is equal to `that` + * @group Comparison + */ + def ===(that: UInt)(implicit sourceInfo: SourceInfo): Bool = _impl_===(that) + + /** Unary not + * + * @return a hardware [[Bool]] asserted if this $coll equals zero + * @group Bitwise + */ + def unary_!(implicit sourceInfo: SourceInfo): Bool = _impl_unary_! + + override def <<(that: Int)(implicit sourceInfo: SourceInfo): UInt = _impl_<<(that) + override def <<(that: BigInt)(implicit sourceInfo: SourceInfo): UInt = _impl_<<(that) + override def <<(that: UInt)(implicit sourceInfo: SourceInfo): UInt = _impl_<<(that) + + override def >>(that: Int)(implicit sourceInfo: SourceInfo): UInt = _impl_>>(that) + override def >>(that: BigInt)(implicit sourceInfo: SourceInfo): UInt = _impl_>>(that) + override def >>(that: UInt)(implicit sourceInfo: SourceInfo): UInt = _impl_>>(that) + + /** + * Circular shift to the left + * @param that number of bits to rotate + * @return UInt of same width rotated left n bits + */ + def rotateLeft(n: Int)(implicit sourceInfo: SourceInfo): UInt = _rotateLeftImpl(n) + + def rotateLeft(n: UInt)(implicit sourceInfo: SourceInfo): UInt = _rotateLeftImpl(n) + + /** + * Circular shift to the right + * @param that number of bits to rotate + * @return UInt of same width rotated right n bits + */ + def rotateRight(n: Int)(implicit sourceInfo: SourceInfo): UInt = _rotateRightImpl(n) + + def rotateRight(n: UInt)(implicit sourceInfo: SourceInfo): UInt = _rotateRightImpl(n) + + /** 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 + */ + def bitSet(off: UInt, dat: Bool)(implicit sourceInfo: SourceInfo): UInt = _bitSetImpl(off, dat) + + // 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`. + */ + def zext(implicit sourceInfo: SourceInfo): SInt = _zextImpl + + override def asSInt(implicit sourceInfo: SourceInfo): SInt = _asSIntImpl +} + +object UInt extends UIntFactory + +sealed class SInt private[chisel3] (width: Width) extends Bits(width) with SIntImpl { + + /** Unary negation (constant width) + * + * @return a hardware $coll equal to zero minus this $coll + * $constantWidth + * @group Arithmetic + */ + final def unary_-(implicit sourceInfo: SourceInfo): SInt = _impl_unary_- + + /** Unary negation (constant width) + * + * @return a hardware $coll equal to zero minus `this` shifted right by one + * $constantWidth + * @group Arithmetic + */ + def unary_-%(implicit sourceInfo: SourceInfo): SInt = _impl_unary_-% + + /** add (default - no growth) operator */ + override def +(that: SInt): SInt = _impl_+(that) + + /** subtract (default - no growth) operator */ + override def -(that: SInt): SInt = _impl_-(that) + override def *(that: SInt): SInt = _impl_*(that) + override def /(that: SInt): SInt = _impl_/(that) + override def %(that: SInt): SInt = _impl_%(that) + + /** Multiplication operator + * + * @param that a hardware $coll + * @return the product of this $coll and `that` + * $sumWidth + * $singleCycleMul + * @group Arithmetic + */ + def *(that: UInt)(implicit sourceInfo: SourceInfo): SInt = _impl_*(that) + + /** Addition operator (expanding width) + * + * @param that a hardware $coll + * @return the sum of this $coll and `that` + * $maxWidthPlusOne + * @group Arithmetic + */ + def +&(that: SInt)(implicit sourceInfo: SourceInfo): SInt = _impl_+&(that) + + /** Addition operator (constant width) + * + * @param that a hardware $coll + * @return the sum of this $coll and `that` shifted right by one + * $maxWidth + * @group Arithmetic + */ + def +%(that: SInt)(implicit sourceInfo: SourceInfo): SInt = _impl_+%(that) + + /** Subtraction operator (increasing width) + * + * @param that a hardware $coll + * @return the difference of this $coll less `that` + * $maxWidthPlusOne + * @group Arithmetic + */ + def -&(that: SInt)(implicit sourceInfo: SourceInfo): SInt = _impl_-&(that) + + /** Subtraction operator (constant width) + * + * @param that a hardware $coll + * @return the difference of this $coll less `that` shifted right by one + * $maxWidth + * @group Arithmetic + */ + def -%(that: SInt)(implicit sourceInfo: SourceInfo): SInt = _impl_-%(that) + + /** Bitwise and operator + * + * @param that a hardware $coll + * @return the bitwise and of this $coll and `that` + * $maxWidth + * @group Bitwise + */ + def &(that: SInt)(implicit sourceInfo: SourceInfo): SInt = _impl_&(that) + + /** Bitwise or operator + * + * @param that a hardware $coll + * @return the bitwise or of this $coll and `that` + * $maxWidth + * @group Bitwise + */ + def |(that: SInt): SInt = _impl_|(that) + + /** Bitwise exclusive or (xor) operator + * + * @param that a hardware $coll + * @return the bitwise xor of this $coll and `that` + * $maxWidth + * @group Bitwise + */ + def ^(that: SInt)(implicit sourceInfo: SourceInfo): SInt = _impl_^(that) + + override def unary_~(implicit sourceInfo: SourceInfo): SInt = _impl_unary_~ + + override def <(that: SInt): Bool = _impl_<(that) + override def >(that: SInt): Bool = _impl_>(that) + override def <=(that: SInt): Bool = _impl_<=(that) + override def >=(that: SInt): Bool = _impl_>=(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 + */ + def =/=(that: SInt): Bool = _impl_=/=(that) + + /** Dynamic equals operator + * + * @param that a hardware $coll + * @return a hardware [[Bool]] asserted if this $coll is equal to `that` + * @group Comparison + */ + def ===(that: SInt): Bool = _impl_===(that) + + def abs: SInt = _absImpl + + override def <<(that: Int)(implicit sourceInfo: SourceInfo): SInt = _impl_<<(that) + override def <<(that: BigInt)(implicit sourceInfo: SourceInfo): SInt = _impl_<<(that) + override def <<(that: UInt)(implicit sourceInfo: SourceInfo): SInt = _impl_<<(that) + + override def >>(that: Int)(implicit sourceInfo: SourceInfo): SInt = _impl_>>(that) + override def >>(that: BigInt)(implicit sourceInfo: SourceInfo): SInt = _impl_>>(that) + override def >>(that: UInt)(implicit sourceInfo: SourceInfo): SInt = _impl_>>(that) + + override def asSInt(implicit sourceInfo: SourceInfo): SInt = _asSIntImpl +} + +object SInt extends SIntFactory + +sealed trait Reset extends ResetImpl with ToBoolable { + def asAsyncReset(implicit sourceInfo: SourceInfo): AsyncReset + def asDisable(implicit sourceInfo: SourceInfo): Disable = _asDisableImpl +} + +object Reset { + def apply(): Reset = new ResetType +} + +/** "Abstract" Reset Type inferred in FIRRTL to either [[AsyncReset]] or [[Bool]] + * + * @note This shares a common interface with [[AsyncReset]] and [[Bool]] but is not their actual + * super type due to Bool inheriting from abstract class UInt + */ +final class ResetType(private[chisel3] val width: Width = Width(1)) extends Reset with ResetTypeImpl with ToBoolable { + def asAsyncReset(implicit sourceInfo: SourceInfo): AsyncReset = _asAsyncResetImpl + def asBool: Bool = _asBoolImpl + def toBool: Bool = asBool +} + +object AsyncReset { + def apply(): AsyncReset = new AsyncReset +} + +/** Data type representing asynchronous reset signals + * + * These signals are similar to [[Clock]]s in that they must be glitch-free for proper circuit + * operation. [[Reg]]s defined with the implicit reset being an [[AsyncReset]] will be + * asychronously reset registers. + */ +sealed class AsyncReset(private[chisel3] val width: Width = Width(1)) extends AsyncResetImpl with Reset { + override def toString: String = stringAccessor("AsyncReset") + def asAsyncReset(implicit sourceInfo: SourceInfo): AsyncReset = _asAsyncResetImpl + def asBool: Bool = _asBoolImpl + def toBool: Bool = _asBoolImpl +} + +// 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 BoolImpl with Reset { + + // 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 + */ + def &(that: Bool)(implicit sourceInfo: SourceInfo): Bool = _impl_&(that) + + /** Bitwise or operator + * + * @param that a hardware $coll + * @return the bitwise or of this $coll and `that` + * @group Bitwise + */ + def |(that: Bool): Bool = _impl_|(that) + + /** Bitwise exclusive or (xor) operator + * + * @param that a hardware $coll + * @return the bitwise xor of this $coll and `that` + * @group Bitwise + */ + def ^(that: Bool)(implicit sourceInfo: SourceInfo): Bool = _impl_^(that) + + override def unary_~(implicit sourceInfo: SourceInfo): Bool = _impl_unary_~ + + /** Logical or operator + * + * @param that a hardware $coll + * @return the logical or of this $coll and `that` + * @note this is equivalent to [[Bool!.|(that:chisel3\.Bool)* Bool.|)]] + * @group Logical + */ + def ||(that: Bool)(implicit sourceInfo: SourceInfo): Bool = _impl_||(that) + + /** Logical and operator + * + * @param that a hardware $coll + * @return the logical and of this $coll and `that` + * @note this is equivalent to [[Bool!.&(that:chisel3\.Bool)* Bool.&]] + * @group Logical + */ + def &&(that: Bool)(implicit sourceInfo: SourceInfo): Bool = _impl_&&(that) + + override def asBool: Bool = _asBoolImpl + + /** Reinterprets this $coll as a clock */ + def asClock(implicit sourceInfo: SourceInfo): Clock = _asClockImpl + + def asAsyncReset(implicit sourceInfo: SourceInfo): AsyncReset = _asAsyncResetImpl +} + +object Bool extends BoolFactory diff --git a/core/src/main/scala-3/chisel3/ChiselEnum.scala b/core/src/main/scala-3/chisel3/ChiselEnum.scala new file mode 100644 index 00000000000..d8032af1e41 --- /dev/null +++ b/core/src/main/scala-3/chisel3/ChiselEnum.scala @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3 + +import chisel3.experimental.SourceInfo + +abstract class EnumType(factory: ChiselEnum, selfAnnotating: Boolean = true) + extends EnumTypeImpl(factory, selfAnnotating) { + + final def ===(that: EnumType)(implicit sourceInfo: SourceInfo): Bool = _impl_===(that) + final def =/=(that: EnumType)(implicit sourceInfo: SourceInfo): Bool = _impl_=/=(that) + final def <(that: EnumType)(implicit sourceInfo: SourceInfo): Bool = _impl_<(that) + final def <=(that: EnumType)(implicit sourceInfo: SourceInfo): Bool = _impl_>(that) + final def >(that: EnumType)(implicit sourceInfo: SourceInfo): Bool = _impl_<=(that) + final def >=(that: EnumType)(implicit sourceInfo: SourceInfo): Bool = _impl_>=(that) +} + +abstract class ChiselEnum extends ChiselEnumImpl diff --git a/core/src/main/scala-3/chisel3/Clock.scala b/core/src/main/scala-3/chisel3/Clock.scala new file mode 100644 index 00000000000..05785b7c483 --- /dev/null +++ b/core/src/main/scala-3/chisel3/Clock.scala @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3 + +import chisel3.experimental.SourceInfo + +object Clock { + def apply(): Clock = new Clock +} + +// TODO: Document this. +sealed class Clock extends ClockImpl { + + /** Returns the contents of the clock wire as a [[Bool]]. */ + def asBool(implicit sourceInfo: SourceInfo): Bool = _asBoolImpl +} diff --git a/core/src/main/scala-3/chisel3/Data.scala b/core/src/main/scala-3/chisel3/Data.scala new file mode 100644 index 00000000000..101797d55c3 --- /dev/null +++ b/core/src/main/scala-3/chisel3/Data.scala @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3 + +import chisel3.experimental.SourceInfo + +/** 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. + * + * @groupdesc Connect Utilities for connecting hardware components + * @define coll data + */ +abstract class Data extends DataImpl with SourceInfoDoc { + + /** Does a reinterpret cast of the bits in this node into the format that provides. + * Returns a new Wire of that type. Does not modify existing nodes. + * + * x.asTypeOf(that) performs the inverse operation of x := that.toBits. + * + * @note bit widths are NOT checked, may pad or drop bits from input + * @note that should have known widths + */ + def asTypeOf[T <: Data](that: T)(implicit sourceInfo: SourceInfo): T = _asTypeOfImpl(that) + + /** Reinterpret cast to 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 + * @note Aggregates are recursively packed with the first element appearing + * in the least-significant bits of the result. + */ + def asUInt: UInt = _asUIntImpl +} + +object Data extends ObjectDataImpl diff --git a/core/src/main/scala-3/chisel3/Disable.scala b/core/src/main/scala-3/chisel3/Disable.scala new file mode 100644 index 00000000000..fd67bb146c7 --- /dev/null +++ b/core/src/main/scala-3/chisel3/Disable.scala @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3 + +import chisel3.internal._ +import chisel3.experimental.{OpaqueType, SourceInfo} +import scala.collection.immutable.ListMap + +/** API for handling disabling of simulation constructs + * + * Disables may be non-synthesizable so they can only be used for disabling simulation constructs + * + * The default disable is the "hasBeenReset" of the currently in scope reset. + * It can be set by the user via the [[withDisable]] API + * + * Users can access the current `Disable` with [[Module.disable]] + */ +// We could just an OpaqueType, but since OpaqueTypes have some API holes, this non-Data type +class Disable private[chisel3] (private[chisel3] val value: Bool) extends DisableImpl { + + /** Logical not + * + * @return invert the logical value of this `Disable` + * @group Bitwise + */ + def unary_!(implicit sourceInfo: SourceInfo): Disable = new Disable(!this.value) +} + +object Disable extends ObectDisableImpl diff --git a/core/src/main/scala-3/chisel3/Mem.scala b/core/src/main/scala-3/chisel3/Mem.scala new file mode 100644 index 00000000000..b71cb108279 --- /dev/null +++ b/core/src/main/scala-3/chisel3/Mem.scala @@ -0,0 +1,313 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3 + +import chisel3.experimental.SourceInfo + +object Mem extends ObjectMemImpl with SourceInfoDoc { + + /** Creates a combinational/asynchronous-read, sequential/synchronous-write [[Mem]]. + * + * @param size number of elements in the memory + * @param t data type of memory element + */ + def apply[T <: Data]( + size: BigInt, + t: T + )( + implicit sourceInfo: SourceInfo + ): Mem[T] = _applyImpl(size, t) + + /** Creates a combinational/asynchronous-read, sequential/synchronous-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)(implicit sourceInfo: SourceInfo): Mem[T] = _applyImpl(size, t) +} + +sealed abstract class MemBase[T <: Data](val t: T, val length: BigInt, protected val sourceInfo: SourceInfo) + extends MemBaseImpl[T] + with SourceInfoDoc { + + // 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: BigInt)(implicit sourceInfo: SourceInfo): T = _applyImpl(idx) + + /** 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)(implicit sourceInfo: SourceInfo): T = _applyImpl(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)(implicit sourceInfo: SourceInfo): T = _applyImpl(idx) + + def apply(idx: UInt, clock: Clock)(implicit sourceInfo: SourceInfo): T = _applyImpl(idx, clock) + + /** 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)(implicit sourceInfo: SourceInfo): T = _readImpl(idx) + + /** Creates a read accessor into the memory with dynamic addressing. + * Takes a clock parameter to bind a clock that may be different + * from the implicit clock. See the class documentation of the memory + * for more detailed information. + */ + def read(idx: UInt, clock: Clock)(implicit sourceInfo: SourceInfo): T = _readImpl(idx, clock) + + /** 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)(implicit sourceInfo: SourceInfo): Unit = _writeImpl(idx, data) + + /** Creates a write accessor into the memory with a clock + * that may be different from the implicit clock. + * + * @param idx memory element index to write into + * @param data new data to write + * @param clock clock to bind to this accessor + */ + def write(idx: UInt, data: T, clock: Clock)(implicit sourceInfo: SourceInfo): Unit = _writeImpl(idx, data, clock) + + /** 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 Seq of Bool: a write to the Vec element in + * memory is only performed if the corresponding mask index is true. + * + * @note this is only allowed if the memory's element data type is a Vec + */ + def write( + idx: UInt, + data: T, + mask: Seq[Bool] + )( + implicit evidence: T <:< Vec[_], + sourceInfo: SourceInfo + ): Unit = _writeImpl(idx, data, mask) + + /** Creates a masked write accessor into the memory with a clock + * that may be different from the implicit clock. + * + * @param idx memory element index to write into + * @param data new data to write + * @param mask write mask as a Seq of Bool: a write to the Vec element in + * memory is only performed if the corresponding mask index is true. + * @param clock clock to bind to this accessor + * + * @note this is only allowed if the memory's element data type is a Vec + */ + def write( + idx: UInt, + data: T, + mask: Seq[Bool], + clock: Clock + )( + implicit evidence: T <:< Vec[_], + sourceInfo: SourceInfo + ): Unit = _writeImpl(idx, data, mask, clock) +} + +/** A combinational/asynchronous-read, sequential/synchronous-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] private[chisel3] (t: T, length: BigInt, sourceInfo: SourceInfo) + extends MemBase(t, length, sourceInfo) + with MemImpl[T] + +object SyncReadMem extends ObjectSyncReadMemImpl { + + /** Creates a sequential/synchronous-read, sequential/synchronous-write [[SyncReadMem]]. + * + * @param size number of elements in the memory + * @param t data type of memory element + */ + def apply[T <: Data]( + size: Int, + t: T + )( + implicit sourceInfo: SourceInfo + ): SyncReadMem[T] = _applyImpl(size, t) + + def apply[T <: Data]( + size: BigInt, + t: T, + ruw: ReadUnderWrite = Undefined + )( + implicit sourceInfo: SourceInfo + ): SyncReadMem[T] = _applyImpl(size, t, ruw) +} + +/** A sequential/synchronous-read, sequential/synchronous-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 SyncReadMem[T <: Data] private[chisel3] ( + t: T, + n: BigInt, + val readUnderWrite: SyncReadMem.ReadUnderWrite, + sourceInfo: SourceInfo) + extends MemBase[T](t, n, sourceInfo) + with SyncReadMemImpl[T] { + + override def read(idx: UInt)(implicit sourceInfo: SourceInfo): T = _readImpl(idx) + + def read(idx: UInt, en: Bool)(implicit sourceInfo: SourceInfo): T = _readImpl(idx, en) + + def read(idx: UInt, en: Bool, clock: Clock)(implicit sourceInfo: SourceInfo): T = _readImpl(idx, en, clock) + + /** Generates an explicit read-write port for this SyncReadMem. Note that this does not infer + * port directionality based on connection semantics and the `when` context unlike SyncReadMem.apply(), + * so the behavior of the port must be controlled by changing the values of the input parameters. + * + * @param idx memory element index to write into + * @param writeData new data to write + * @param enable enables access to the memory + * @param isWrite performs a write instead of a read when enable is true; the return + * value becomes undefined when this parameter is true + * + * @return The read data of the memory, which gives the value at idx when enable is true and isWrite is false, + * or an undefined value otherwise, on the following clock cycle. + * + * @example Controlling a read/write port with IO signals + * {{{ + * class MyMemWrapper extends Module { + * val width = 2 + * + * val io = IO(new Bundle { + * val address = Input(UInt()) + * val wdata = Input(UInt(width.W)) + * val enable = Input(Bool()) + * val isWrite = Input(Bool()) + * val rdata = Output(UInt(width.W)) + * }) + * + * val mem = SyncReadMem(2, UInt(width.W)) + * io.rdata := mem.readWrite(io.address, io.wdata, io.enable, io.isWrite) + * } + * + * }}} + */ + def readWrite(idx: UInt, writeData: T, en: Bool, isWrite: Bool)(implicit sourceInfo: SourceInfo): T = + _readWriteImpl(idx, writeData, en, isWrite) + + /** Generates an explicit read-write port for this SyncReadMem, using a clock that may be + * different from the implicit clock. + * + * @param idx memory element index to write into + * @param writeData new data to write + * @param enable enables access to the memory + * @param isWrite performs a write instead of a read when enable is true; the return + * value becomes undefined when this parameter is true + * @param clock clock to bind to this read-write port + * + * @return The read data of the memory, which gives the value at idx when enable is true and isWrite is false, + * or an undefined value otherwise, on the following clock cycle. + */ + def readWrite( + idx: UInt, + data: T, + en: Bool, + isWrite: Bool, + clock: Clock + )( + implicit sourceInfo: SourceInfo + ): T = _readWriteImpl(idx, data, en, isWrite, clock) + + /** Generates an explicit read-write port for this SyncReadMem, with a bytemask for + * performing partial writes to a Vec element. + * + * @param idx memory element index to write into + * @param writeData new data to write + * @param mask the write mask as a Seq of Bool: a write to the Vec element in + * memory is only performed if the corresponding mask index is true. + * @param enable enables access to the memory + * @param isWrite performs a write instead of a read when enable is true; the return + * value becomes undefined when this parameter is true + * + * @return The read data Vec of the memory at idx when enable is true and isWrite is false, + * or an undefined value otherwise, on the following clock cycle + * + * @example Controlling a read/masked write port with IO signals + * {{{ + * class MyMaskedMemWrapper extends Module { + * val width = 2 + * + * val io = IO(new Bundle { + * val address = Input(UInt()) + * val wdata = Input(Vec(2, UInt(width.W))) + * val mask = Input(Vec(2, Bool())) + * val enable = Input(Bool()) + * val isWrite = Input(Bool()) + * val rdata = Output(Vec(2, UInt(width.W))) + * }) + * + * val mem = SyncReadMem(2, Vec(2, UInt(width.W))) + * io.rdata := mem.readWrite(io.address, io.wdata, io.mask, io.enable, io.isWrite) + * } + * }}} + * + * @note this is only allowed if the memory's element data type is a Vec + */ + def readWrite( + idx: UInt, + writeData: T, + mask: Seq[Bool], + en: Bool, + isWrite: Bool + )( + implicit evidence: T <:< Vec[_], + sourceInfo: SourceInfo + ): T = _readWriteImpl(idx, writeData, mask, en, isWrite) + + /** Generates an explicit read-write port for this SyncReadMem, with a bytemask for + * performing partial writes to a Vec element and a clock that may be different from + * the implicit clock. + * + * @param idx memory element index to write into + * @param writeData new data to write + * @param mask the write mask as a Seq of Bool: a write to the Vec element in + * memory is only performed if the corresponding mask index is true. + * @param enable enables access to the memory + * @param isWrite performs a write instead of a read when enable is true; the return + * value becomes undefined when this parameter is true + * @param clock clock to bind to this read-write port + * + * @return The read data Vec of the memory at idx when enable is true and isWrite is false, + * or an undefined value otherwise, on the following clock cycle + * + * @note this is only allowed if the memory's element data type is a Vec + */ + def readWrite( + idx: UInt, + writeData: T, + mask: Seq[Bool], + en: Bool, + isWrite: Bool, + clock: Clock + )( + implicit evidence: T <:< Vec[_], + sourceInfo: SourceInfo + ): T = _readWriteImpl(idx, writeData, mask, en, isWrite, clock) +} diff --git a/core/src/main/scala-3/chisel3/Module.scala b/core/src/main/scala-3/chisel3/Module.scala new file mode 100644 index 00000000000..b424f678374 --- /dev/null +++ b/core/src/main/scala-3/chisel3/Module.scala @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3 + +import chisel3.experimental.{BaseModule, SourceInfo} + +object Module extends ObjectModuleImpl with SourceInfoDoc { + + /** A wrapper method that all Module instantiations must be wrapped in + * (necessary to help Chisel track internal state). + * + * @param bc the Module being created + * + * @return the input module `m` with Chisel metadata properly set + */ + def apply[T <: BaseModule](bc: => T): T = _applyImpl(bc) + def do_apply[T <: BaseModule](bc: => T)(implicit sourceInfo: SourceInfo): T = apply(bc) +} + +/** 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). + * This abstract base class includes an implicit clock and reset. + * + * @note Module instantiations must be wrapped in a Module() call. + */ +abstract class Module extends ModuleImpl diff --git a/core/src/main/scala-3/chisel3/Mux.scala b/core/src/main/scala-3/chisel3/Mux.scala new file mode 100644 index 00000000000..da5ac2985ac --- /dev/null +++ b/core/src/main/scala-3/chisel3/Mux.scala @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3 + +import chisel3.experimental.SourceInfo + +object Mux extends MuxImpl with SourceInfoDoc { + + /** 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 === 3.U, 3.U(4.W), 0.U(4.W)) + * }}} + */ + def apply[T <: Data]( + cond: Bool, + con: T, + alt: T + )( + implicit sourceInfo: SourceInfo + ): T = _applyImpl(cond, con, alt) +} diff --git a/core/src/main/scala-3/chisel3/Num.scala b/core/src/main/scala-3/chisel3/Num.scala new file mode 100644 index 00000000000..b63e1d34762 --- /dev/null +++ b/core/src/main/scala-3/chisel3/Num.scala @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3 + +// REVIEW TODO: Further discussion needed on what Num actually is. + +/** 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 generates a + * @define singleCycleMul @note $canGenerateA fully combinational multiplier which $canHaveHighCost. + * @define singleCycleDiv @note $canGenerateA fully combinational 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`. + */ +trait Num[T <: Data] { + self: Num[T] => + // def << (b: T): T + // def >> (b: T): T + //def unary_-(): T + + // REVIEW TODO: double check ops conventions against FIRRTL + + /** Addition operator + * + * @param that a $numType + * @return the sum of this $coll and `that` + * $maxWidth + * @group Arithmetic + */ + def +(that: T): T + + /** Multiplication operator + * + * @param that a $numType + * @return the product of this $coll and `that` + * $sumWidth + * $singleCycleMul + * @group Arithmetic + */ + def *(that: T): T + + /** Division operator + * + * @param that a $numType + * @return the quotient of this $coll divided by `that` + * $singleCycleDiv + * @todo full rules + * @group Arithmetic + */ + def /(that: T): T + + /** Modulo operator + * + * @param that a $numType + * @return the remainder of this $coll divided by `that` + * $singleCycleDiv + * @group Arithmetic + */ + def %(that: T): T + + /** Subtraction operator + * + * @param that a $numType + * @return the difference of this $coll less `that` + * $maxWidthPlusOne + * @group Arithmetic + */ + def -(that: T): T + + /** Less than operator + * + * @param that a $numType + * @return a hardware [[Bool]] asserted if this $coll is less than `that` + * @group Comparison + */ + def <(that: T): Bool + + /** 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 + */ + def <=(that: T): Bool + + /** Greater than operator + * + * @param that a hardware component + * @return a hardware [[Bool]] asserted if this $coll is greater than `that` + * @group Comparison + */ + def >(that: T): Bool + + /** 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 + */ + def >=(that: T): Bool + + /** Absolute value operator + * + * @return a $numType with a value equal to the absolute value of this $coll + * $unchangedWidth + * @group Arithmetic + */ + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) + def abs: T + + /** Minimum operator + * + * @param that a hardware $coll + * @return a $numType with a value equal to the minimum value of this $coll and `that` + * $maxWidth + * @group Arithmetic + */ + def min(that: T): T = + Mux(this < that, this.asInstanceOf[T], that) + + /** Maximum operator + * + * @param that a $numType + * @return a $numType with a value equal to the minimum value of this $coll and `that` + * $maxWidth + * @group Arithmetic + */ + def max(that: T): T = + Mux(this < that, that, this.asInstanceOf[T]) +} + +object Num extends NumObject diff --git a/core/src/main/scala-3/chisel3/Printf.scala b/core/src/main/scala-3/chisel3/Printf.scala new file mode 100644 index 00000000000..3bea14c34eb --- /dev/null +++ b/core/src/main/scala-3/chisel3/Printf.scala @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3 + +import chisel3.internal._ +import chisel3.internal.Builder.pushCommand +import chisel3.experimental.SourceInfo +import chisel3.PrintfMacrosCompat._ + +import scala.language.experimental.macros + +/** Prints a message in simulation + * + * See apply methods for use + */ +object printf { + + /** Named class for [[printf]]s. */ + final class Printf private[chisel3] (val pable: Printable) extends VerificationStatement + + /** Helper for packing escape characters */ + private[chisel3] def format(formatIn: String): String = { + require(formatIn.forall(c => c.toInt > 0 && c.toInt < 128), "format strings must comprise non-null ASCII values") + def escaped(x: Char) = { + require(x.toInt >= 0, s"char ${x} to Int ${x.toInt} must be >= 0") + if (x == '"' || x == '\\') { + s"\\${x}" + } else if (x == '\n') { + "\\n" + } else if (x == '\t') { + "\\t" + } else { + require( + x.toInt >= 32, + s"char ${x} to Int ${x.toInt} must be >= 32" + ) // TODO \xNN once FIRRTL issue #59 is resolved + x + } + } + formatIn.map(escaped).mkString("") + } + + /** Prints a message in simulation + * + * Prints a message every cycle. If defined within the scope of a [[when]] block, the message + * will only be printed on cycles that the when condition is true. + * + * 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), uses the current default clock + * and reset. These can be overriden with [[withClockAndReset]]. + * + * @see [[Printable]] documentation + * @param pable [[Printable]] to print + */ + def apply(pable: Printable)(implicit sourceInfo: SourceInfo): chisel3.printf.Printf = + PrintfMacrosCompat.printfWithReset(pable)(sourceInfo) +} diff --git a/core/src/main/scala-3/chisel3/PrintfMacros.scala b/core/src/main/scala-3/chisel3/PrintfMacros.scala new file mode 100644 index 00000000000..ac997b9a9f0 --- /dev/null +++ b/core/src/main/scala-3/chisel3/PrintfMacros.scala @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3 + +import chisel3.internal._ +import chisel3.internal.Builder.pushCommand +import chisel3.experimental.SourceInfo + +object PrintfMacrosCompat { + private[chisel3] def printfWithReset( + pable: Printable + )( + implicit sourceInfo: SourceInfo + ): chisel3.printf.Printf = { + var printfId: chisel3.printf.Printf = null + when(!Module.reset.asBool) { + printfId = printfWithoutReset(pable) + } + printfId + } + + private[chisel3] def printfWithoutReset( + pable: Printable + )( + implicit sourceInfo: SourceInfo + ): chisel3.printf.Printf = { + val clock = Builder.forcedClock + val printfId = new chisel3.printf.Printf(pable) + + Printable.checkScope(pable) + + pushCommand(chisel3.internal.firrtl.ir.Printf(printfId, sourceInfo, clock.ref, pable)) + printfId + } +} diff --git a/core/src/main/scala-3/chisel3/SourceInfoDoc.scala b/core/src/main/scala-3/chisel3/SourceInfoDoc.scala new file mode 100644 index 00000000000..4de4c26eb91 --- /dev/null +++ b/core/src/main/scala-3/chisel3/SourceInfoDoc.scala @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3 + +/** Does nothing */ +trait SourceInfoDoc diff --git a/core/src/main/scala-3/chisel3/VerificationStatement.scala b/core/src/main/scala-3/chisel3/VerificationStatement.scala new file mode 100644 index 00000000000..346cc4ef732 --- /dev/null +++ b/core/src/main/scala-3/chisel3/VerificationStatement.scala @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3 + +import chisel3.experimental.{BaseModule, SourceInfo} +import chisel3.internal._ +import chisel3.internal.Builder.pushCommand +import chisel3.internal.firrtl.ir._ +import chisel3.layer.block + +import scala.language.experimental.macros + +/** Scaladoc information for internal verification statement macros + * that are used in objects assert, assume and cover. + * + * @groupdesc VerifPrintMacros + * + *

+ * '''These internal methods are not part of the public-facing API!''' + *

+ *
+ * + * @groupprio VerifPrintMacros 1001 + */ +trait VerifPrintMacrosDoc + +object assert extends VerifPrintMacrosDoc { + + /** Named class for assertions. */ + final class Assert private[chisel3] () extends VerificationStatement + + /** An elaboration-time assertion. Calls the built-in Scala assert function. */ + def apply(cond: Boolean, message: => String): Unit = Predef.assert(cond, message) + + /** An elaboration-time assertion. Calls the built-in Scala assert function. */ + def apply(cond: Boolean): Unit = Predef.assert(cond, "") +} + +object assume extends VerifPrintMacrosDoc { + + /** Named class for assumptions. */ + final class Assume private[chisel3] () extends VerificationStatement + + /** An elaboration-time assumption. Calls the built-in Scala assume function. */ + def apply(cond: Boolean, message: => String): Unit = Predef.assume(cond, message) + + /** An elaboration-time assumption. Calls the built-in Scala assume function. */ + def apply(cond: Boolean): Unit = Predef.assume(cond, "") +} + +object cover extends VerifPrintMacrosDoc { + + /** Named class for cover statements. */ + final class Cover private[chisel3] () extends VerificationStatement + + type SourceLineInfo = (String, Int) +} + diff --git a/core/src/main/scala-3/chisel3/VerificationStatementMacros.scala b/core/src/main/scala-3/chisel3/VerificationStatementMacros.scala new file mode 100644 index 00000000000..7e37ea935dc --- /dev/null +++ b/core/src/main/scala-3/chisel3/VerificationStatementMacros.scala @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3 + +import chisel3.experimental.SourceInfo +import chisel3.PrintfMacrosCompat._ +import chisel3.internal.firrtl.ir._ +import chisel3.layer.block +import chisel3.layers +import chisel3.util.circt.IfElseFatalIntrinsic +import chisel3.internal.Builder.pushCommand +import chisel3.internal._ + +import scala.annotation.nowarn + +object VerifStmtMacrosCompat { + + type SourceLineInfo = (String, Int) + + def formatFailureMessage( + kind: String, + lineInfo: SourceLineInfo, + cond: Bool, + message: Option[Printable] + )( + implicit sourceInfo: SourceInfo + ): Printable = { + val (filename, line) = lineInfo + val lineMsg = s"$filename:$line".replaceAll("%", "%%") + message match { + case Some(msg) => + p"$kind failed: $msg\n" + case None => p"$kind failed at $lineMsg\n" + } + } +} diff --git a/core/src/main/scala-3/chisel3/experimental/SourceInfo.scala b/core/src/main/scala-3/chisel3/experimental/SourceInfo.scala new file mode 100644 index 00000000000..c4d8528cc07 --- /dev/null +++ b/core/src/main/scala-3/chisel3/experimental/SourceInfo.scala @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: Apache-2.0 + +// This file contains macros for adding source locators at the point of invocation. +// +// This is not part of coreMacros to disallow this macro from being implicitly invoked in Chisel +// frontend (and generating source locators in Chisel core), which is almost certainly a bug. +// +// Note: While these functions and definitions are not private (macros can't be +// private), these are NOT meant to be part of the public API (yet) and no +// forward compatibility guarantees are made. +// A future revision may stabilize the source locator API to allow library +// writers to append source locator information at the point of a library +// function invocation. + +package chisel3.experimental + +/** Abstract base class for generalized source information. + */ +sealed trait SourceInfo { + + /** A prettier toString + * + * Make a useful message if SourceInfo is available, nothing otherwise + */ + def makeMessage(f: String => String = x => x): String + + /** The filename for the originating source file, if known */ + def filenameOption: Option[String] +} + +sealed trait NoSourceInfo extends SourceInfo { + def makeMessage(f: String => String = x => x): String = "" + def filenameOption: Option[String] = None +} + +/** For when source info can't be generated because of a technical limitation, like for Reg because + * Scala macros don't support named or default arguments. + */ +case object UnlocatableSourceInfo extends NoSourceInfo + +/** For when source info isn't generated because the function is deprecated and we're lazy. + */ +case object DeprecatedSourceInfo extends NoSourceInfo + +/** For FIRRTL lines from a Scala source line. + * + * @note A column == 0 indicates no column + */ +case class SourceLine(filename: String, line: Int, col: Int) extends SourceInfo with SourceLineImpl { + def makeMessage(f: String => String = x => x): String = _makeMessageImpl(f) +} + +object SourceInfo extends ObjectSourceInfoImpl { + implicit def materialize: SourceInfo = ??? +} diff --git a/core/src/main/scala-3/chisel3/experimental/dataview/ChiselSubtypeOf.scala b/core/src/main/scala-3/chisel3/experimental/dataview/ChiselSubtypeOf.scala new file mode 100644 index 00000000000..0a993335d26 --- /dev/null +++ b/core/src/main/scala-3/chisel3/experimental/dataview/ChiselSubtypeOf.scala @@ -0,0 +1,5 @@ +package chisel3.experimental + +import chisel3._ + +sealed trait ChiselSubtypeOf[A, B] diff --git a/core/src/main/scala-3/chisel3/experimental/dataview/InvertibleDataView.scala b/core/src/main/scala-3/chisel3/experimental/dataview/InvertibleDataView.scala new file mode 100644 index 00000000000..b787f92de27 --- /dev/null +++ b/core/src/main/scala-3/chisel3/experimental/dataview/InvertibleDataView.scala @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3.experimental.dataview + +import chisel3._ + +private[chisel3] trait InvertibleDataView diff --git a/core/src/main/scala-3/chisel3/experimental/hierarchy/HierarchyMarker.scala b/core/src/main/scala-3/chisel3/experimental/hierarchy/HierarchyMarker.scala new file mode 100644 index 00000000000..c1838b4c56b --- /dev/null +++ b/core/src/main/scala-3/chisel3/experimental/hierarchy/HierarchyMarker.scala @@ -0,0 +1,3 @@ +package chisel3.experimental + +trait Markers \ No newline at end of file diff --git a/core/src/main/scala-3/chisel3/experimental/hierarchy/core/Hierarchy.scala b/core/src/main/scala-3/chisel3/experimental/hierarchy/core/Hierarchy.scala new file mode 100644 index 00000000000..c6f13498b58 --- /dev/null +++ b/core/src/main/scala-3/chisel3/experimental/hierarchy/core/Hierarchy.scala @@ -0,0 +1,62 @@ +package chisel3.experimental.hierarchy.core + +import chisel3._ +import scala.collection.mutable.{HashMap, HashSet} +import chisel3.experimental.BaseModule +import _root_.firrtl.annotations.IsModule + +trait Hierarchy[+A] extends HierarchyImpl[A] { +/** Determine whether underlying proto is of type provided. + * + * @note IMPORTANT: this function requires summoning a TypeTag[B], which will fail if B is an inner class. + * @note IMPORTANT: this function IGNORES type parameters, akin to normal type erasure. + * @note IMPORTANT: this function relies on Java reflection for underlying proto, but Scala reflection for provided type + * + * E.g. isA[List[Int]] will return true, even if underlying proto is of type List[String] + * @return Whether underlying proto is of provided type (with caveats outlined above) + */ + def isA[B]: Boolean = false + +} + +object Hierarchy { + implicit class HierarchyBaseModuleExtensions[T <: BaseModule](i: Hierarchy[T]) { + + /** Returns the toTarget of this hierarchy + * @return target of this hierarchy + */ + def toTarget: IsModule = i match { + case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toTarget + case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toTarget + case _ => throw new InternalErrorException("Match error: toTarget i=$i") + } + + /** Returns the toAbsoluteTarget of this hierarchy + * @return absoluteTarget of this Hierarchy + */ + def toAbsoluteTarget: IsModule = i match { + case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toAbsoluteTarget + case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toAbsoluteTarget + case _ => throw new InternalErrorException("Match error: toAbsoluteTarget i=$i") + } + + /** Returns the toRelativeTarget of this hierarchy + * @return relativeTarget of this Hierarchy + */ + def toRelativeTarget(root: Option[BaseModule]): IsModule = i match { + case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toRelativeTarget(root) + case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toRelativeTarget(root) + case _ => throw new InternalErrorException("Match error: toAbsoluteTarget i=$i") + } + + /** Returns the toRelativeTarget of this hierarchy + * @return relativeTarget of this Hierarchy + */ + def toRelativeTargetToHierarchy(root: Option[Hierarchy[BaseModule]]): IsModule = i match { + case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toRelativeTargetToHierarchy(root) + case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toRelativeTargetToHierarchy(root) + case _ => throw new InternalErrorException("Match error: toAbsoluteTarget i=$i") + } + + } +} diff --git a/core/src/main/scala-3/chisel3/probe/Probe.scala b/core/src/main/scala-3/chisel3/probe/Probe.scala new file mode 100644 index 00000000000..11d477c5252 --- /dev/null +++ b/core/src/main/scala-3/chisel3/probe/Probe.scala @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3.probe + +import chisel3._ +import chisel3.experimental.SourceInfo + +object Probe extends ProbeBase { + + /** Mark a Chisel type as with a probe modifier. + */ + def apply[T <: Data](source: => T)(implicit sourceInfo: SourceInfo): T = + super.apply(source, false, None) + + def apply[T <: Data](source: => T, color: Option[layer.Layer])(implicit sourceInfo: SourceInfo): T = + super.apply(source, false, color) +} + +object RWProbe extends ProbeBase with SourceInfoDoc { + + /** Mark a Chisel type with a writable probe modifier. + */ + def apply[T <: Data](source: => T)(implicit sourceInfo: SourceInfo): T = super.apply(source, true) +} diff --git a/core/src/main/scala-3/chisel3/probe/ProbeValue.scala b/core/src/main/scala-3/chisel3/probe/ProbeValue.scala new file mode 100644 index 00000000000..85b132ded56 --- /dev/null +++ b/core/src/main/scala-3/chisel3/probe/ProbeValue.scala @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3.probe + +import chisel3.{Data, SourceInfoDoc} +import chisel3.experimental.SourceInfo + +object ProbeValue extends ProbeValueBase with SourceInfoDoc { + + /** Create a read-only probe expression. */ + def apply[T <: Data](source: T)(implicit sourceInfo: SourceInfo): T = super.apply(source, writable = false) +} + +object RWProbeValue extends ProbeValueBase with SourceInfoDoc { + + /** Create a read/write probe expression. */ + def apply[T <: Data](source: T)(implicit sourceInfo: SourceInfo): T = super.apply(source, writable = true) +} diff --git a/core/src/main/scala-3/chisel3/probe/package.scala b/core/src/main/scala-3/chisel3/probe/package.scala new file mode 100644 index 00000000000..107e46be1a4 --- /dev/null +++ b/core/src/main/scala-3/chisel3/probe/package.scala @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3 + +import chisel3._ +import chisel3.experimental.SourceInfo + +package object probe extends ObjectProbeImpl { + + /** Access the value of a probe. + * + * @param source probe whose value is getting accessed + */ + def read[T <: Data](source: T)(implicit sourceInfo: SourceInfo): T = _readImpl(source) +} diff --git a/core/src/main/scala-3/chisel3/properties/Object.scala b/core/src/main/scala-3/chisel3/properties/Object.scala new file mode 100644 index 00000000000..a149deafb68 --- /dev/null +++ b/core/src/main/scala-3/chisel3/properties/Object.scala @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3.properties + +import chisel3.experimental.SourceInfo +import chisel3.internal.firrtl.ir.{DefClass, DefObject, Node} +import chisel3.internal.{throwException, Builder, HasId, NamedComponent} +import chisel3.internal.binding.ObjectFieldBinding + +/** Represents an instance of a Class. + * + * This cannot be instantiated directly, instead see Class.unsafeGetDynamicObject. + * + * The DynamicObject is generally unsafe, in that its getField method does not check the name, type, or direction of + * the accessed field. It may be used with care, and a more typesafe version called StaticObject has been added, which + * works with the Definition / Instance APIs. + * + * To create a DynamicObject directly, wrap a Class with DynamicObject.apply. For example: + * + * {{{ + * val obj = DynamicObject(new Class { + * override def desiredName = "Test" + * val in = IO(Input(Property[Int]())) + * val out = IO(Output(Property[Int]())) + * out := in + * }) + * }}} + */ +class DynamicObject private[chisel3] (val className: ClassType) extends DynamicObjectImpl + +object DynamicObject extends ObjectDynamicObjectImpl diff --git a/firrtl/src/main/scala-3/Macros.scala b/firrtl/src/main/scala-3/Macros.scala new file mode 100644 index 00000000000..c11a84eae03 --- /dev/null +++ b/firrtl/src/main/scala-3/Macros.scala @@ -0,0 +1,13 @@ +package firrtl.macros + +import scala.quoted._ + +object Macros { + inline def isSingletonImpl[T](obj: T): Boolean = ${ isModuleClassImpl('obj) } + + def isModuleClassImpl[T: Type](obj: Expr[T])(using Quotes): Expr[Boolean] = { + import quotes.reflect._ + val objType = TypeRepr.of[T] + Expr(objType.typeSymbol.flags.is(Flags.Module)) + } +} diff --git a/src/main/scala-3/chisel3/FixedIOModule.scala b/src/main/scala-3/chisel3/FixedIOModule.scala new file mode 100644 index 00000000000..25d3a456c03 --- /dev/null +++ b/src/main/scala-3/chisel3/FixedIOModule.scala @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3 + +import chisel3.experimental.{BaseModule, ExtModule, Param} + +/** A module or external module whose IO is generated from a specific generator. + * This module may have no additional IO created other than what is specified + * by its `ioGenerator` abstract member. + */ +sealed trait FixedIOBaseModule[A <: Data] extends BaseModule { + + /** A generator of IO */ + protected def ioGenerator: A + + final val io = FlatIO(ioGenerator) + endIOCreation() + +} + +/** A Chisel module whose IO is determined by an IO generator. This module + * cannot have additional IO created by modules that extend it. + * + * @param ioGenerator + */ +class FixedIORawModule[A <: Data](final val ioGenerator: A) extends RawModule with FixedIOBaseModule[A] + +/** A Chisel blackbox whose IO is determined by an IO generator. This module + * cannot have additional IO created by modules that extend it. + * + * @param ioGenerator + * @param params + */ +class FixedIOExtModule[A <: Data](final val ioGenerator: A, params: Map[String, Param] = Map.empty[String, Param]) + extends ExtModule(params) + with FixedIOBaseModule[A] diff --git a/src/main/scala-3/chisel3/choice/ModuleChoice.scala b/src/main/scala-3/chisel3/choice/ModuleChoice.scala new file mode 100644 index 00000000000..dedd695357d --- /dev/null +++ b/src/main/scala-3/chisel3/choice/ModuleChoice.scala @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3.choice + +import chisel3.{Data, FixedIOBaseModule, SourceInfoDoc} +import chisel3.experimental.SourceInfo + +object ModuleChoice extends ModuleChoiceImpl { + + /** A wrapper method for Module instantiation based on option choices. + * (necessary to help Chisel track internal state). + * @see [[chisel3.choice.Group]] on how to declare the options for the alternatives. + * + * Example: + * ``` + * val module = ModuleChoice(new DefaultModule)(Seq( + * Platform.FPGA -> new FPGATarget, + * Platform.ASIC -> new ASICTarget + * )) + * ``` + * + * @param default the Module to instantiate if no module is specified + * @param choices the mapping from cases to module generators + * + * @return the input module `m` with Chisel metadata properly set + * + * @throws java.lang.IllegalArgumentException if the cases do not belong to the same option. + */ + def apply[T <: Data]( + default: => FixedIOBaseModule[T], + choices: Seq[(Case, () => FixedIOBaseModule[T])] + )( + implicit sourceInfo: SourceInfo + ): T = _applyImpl(default, choices) +} diff --git a/src/main/scala-3/chisel3/util/BitPat.scala b/src/main/scala-3/chisel3/util/BitPat.scala new file mode 100644 index 00000000000..b939dd58bf3 --- /dev/null +++ b/src/main/scala-3/chisel3/util/BitPat.scala @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3.util + +import chisel3._ +import chisel3.experimental.SourceInfo +import scala.collection.mutable +import scala.util.hashing.MurmurHash3 + +object BitPat extends ObjectBitPatImpl { + implicit class fromUIntToBitPatComparable(x: UInt) { + def ===(that: BitPat)(implicit sourceInfo: SourceInfo): Bool = that === x + def =/=(that: BitPat)(implicit sourceInfo: SourceInfo): Bool = that =/= x + } +} + +sealed class BitPat(val value: BigInt, val mask: BigInt, val width: Int) extends BitPatImpl with SourceInfoDoc { + import chisel3.util.experimental.BitSet + def terms = Set(this) + + def apply(x: Int)(implicit sourceInfo: SourceInfo): BitPat = _applyImpl(x) + def apply(x: Int, y: Int)(implicit sourceInfo: SourceInfo): BitPat = _applyImpl(x, y) + def ===(that: UInt)(implicit sourceInfo: SourceInfo): Bool = _impl_===(that) + def =/=(that: UInt)(implicit sourceInfo: SourceInfo): Bool = _impl_=/=(that) + def ##(that: BitPat)(implicit sourceInfo: SourceInfo): BitPat = _impl_##(that) +} diff --git a/src/main/scala-3/chisel3/util/Bitwise.scala b/src/main/scala-3/chisel3/util/Bitwise.scala new file mode 100644 index 00000000000..f48b4f1e040 --- /dev/null +++ b/src/main/scala-3/chisel3/util/Bitwise.scala @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: Apache-2.0 + +/** Miscellaneous circuit generators operating on bits. + */ + +package chisel3.util + +import chisel3._ +import chisel3.experimental.SourceInfo + +/** Creates repetitions of each bit of the input in order. + * + * @example {{{ + * FillInterleaved(2, "b1 0 0 0".U) // equivalent to "b11 00 00 00".U + * FillInterleaved(2, "b1 0 0 1".U) // equivalent to "b11 00 00 11".U + * FillInterleaved(2, myUIntWire) // dynamic interleaved fill + * + * FillInterleaved(2, Seq(false.B, false.B, false.B, true.B)) // equivalent to "b11 00 00 00".U + * FillInterleaved(2, Seq(true.B, false.B, false.B, true.B)) // equivalent to "b11 00 00 11".U + * }}} + */ +object FillInterleaved extends FillInterleavedImpl { + + /** Creates n repetitions of each bit of x in order. + * + * Output data-equivalent to in(size(in)-1) (n times) ## ... ## in(1) (n times) ## in(0) (n times) + */ + def apply(n: Int, in: UInt)(implicit sourceInfo: SourceInfo): UInt = _applyImpl(n, in) + + /** Creates n repetitions of each bit of x in order. + * + * Output data-equivalent to in(size(in)-1) (n times) ## ... ## in(1) (n times) ## in(0) (n times) + */ + def apply(n: Int, in: Seq[Bool])(implicit sourceInfo: SourceInfo): UInt = _applyImpl(n, in) +} + +/** Returns the number of bits set (value is 1 or true) in the input signal. + * + * @example {{{ + * PopCount(Seq(true.B, false.B, true.B, true.B)) // evaluates to 3.U + * PopCount(Seq(false.B, false.B, true.B, false.B)) // evaluates to 1.U + * + * PopCount("b1011".U) // evaluates to 3.U + * PopCount("b0010".U) // evaluates to 1.U + * PopCount(myUIntWire) // dynamic count + * }}} + */ +object PopCount extends PopCountImpl { + + def apply(in: Iterable[Bool])(implicit sourceInfo: SourceInfo): UInt = _applyImpl(in) + def apply(in: Bits)(implicit sourceInfo: SourceInfo): UInt = _applyImpl(in) +} + +/** Create repetitions of the input using a tree fanout topology. + * + * @example {{{ + * Fill(2, "b1000".U) // equivalent to "b1000 1000".U + * Fill(2, "b1001".U) // equivalent to "b1001 1001".U + * Fill(2, myUIntWire) // dynamic fill + * }}} + */ +object Fill extends FillImpl { + + /** Create n repetitions of x using a tree fanout topology. + * + * Output data-equivalent to x ## x ## ... ## x (n repetitions). + * @throws java.lang.IllegalArgumentException if `n` is less than zero + */ + def apply(n: Int, x: UInt)(implicit sourceInfo: SourceInfo): UInt = _applyImpl(n, x) +} + +/** Returns the input in bit-reversed order. Useful for little/big-endian conversion. + * + * @example {{{ + * Reverse("b1101".U) // equivalent to "b1011".U + * Reverse("b1101".U(8.W)) // equivalent to "b10110000".U + * Reverse(myUIntWire) // dynamic reverse + * }}} + */ +object Reverse extends ReverseImpl { + + def apply(in: UInt)(implicit sourceInfo: SourceInfo): UInt = _applyImpl(in) +} diff --git a/src/main/scala-3/chisel3/util/Cat.scala b/src/main/scala-3/chisel3/util/Cat.scala new file mode 100644 index 00000000000..2ebc69ab05e --- /dev/null +++ b/src/main/scala-3/chisel3/util/Cat.scala @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: Apache-2.0 +package chisel3.util + +import chisel3._ +import chisel3.experimental.SourceInfo + +/** Concatenates elements of the input, in order, together. + * + * @example {{{ + * Cat("b101".U, "b11".U) // equivalent to "b101 11".U + * Cat(myUIntWire0, myUIntWire1) + * + * Cat(Seq("b101".U, "b11".U)) // equivalent to "b101 11".U + * Cat(mySeqOfBits) + * }}} + */ +object Cat extends CatImpl { + + /** Concatenates the argument data elements, in argument order, together. The first argument + * forms the most significant bits, while the last argument forms the least significant bits. + */ + def apply[T <: Bits](a: T, r: T*)(implicit sourceInfo: SourceInfo): UInt = _applyImpl(a, r: _*) + + /** Concatenates the data elements of the input sequence, in reverse sequence order, together. + * The first element of the sequence forms the most significant bits, while the last element + * in the sequence forms the least significant bits. + * + * Equivalent to r(0) ## r(1) ## ... ## r(n-1). + * @note This returns a `0.U` if applied to a zero-element `Vec`. + */ + def apply[T <: Bits](r: Seq[T])(implicit sourceInfo: SourceInfo): UInt = _applyImpl(r) +} diff --git a/src/main/scala-3/chisel3/util/Mux.scala b/src/main/scala-3/chisel3/util/Mux.scala new file mode 100644 index 00000000000..48909210818 --- /dev/null +++ b/src/main/scala-3/chisel3/util/Mux.scala @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: Apache-2.0 + +/** Mux circuit generators. + */ + +package chisel3.util + +import chisel3._ +import chisel3.experimental.SourceInfo + +/** Creates a cascade of n Muxs to search for a key value. The Selector may be a UInt or an EnumType. + * + * @example {{{ + * MuxLookup(idx, default)(Seq(0.U -> a, 1.U -> b)) + * MuxLookup(myEnum, default)(Seq(MyEnum.a -> 1.U, MyEnum.b -> 2.U, MyEnum.c -> 3.U)) + * }}} + */ +object MuxLookup extends MuxLookupImpl { + + /** @param key a key to search for + * @param default a default value if nothing is found + * @param mapping a sequence to search of keys and values + * @return the value found or the default if not + */ + def applyEnum[S <: EnumType, T <: Data]( + key: S, + default: T, + mapping: Seq[(S, T)] + )( + implicit sourceinfo: SourceInfo + ): T = _applyEnumImpl(key, default, mapping) + + /** @param key a key to search for + * @param default a default value if nothing is found + * @param mapping a sequence to search of keys and values + * @return the value found or the default if not + */ + def apply[S <: UInt, T <: Data](key: S, default: T, mapping: Seq[(S, T)])(implicit sourceinfo: SourceInfo): T = + _applyImpl(key, default, mapping) +} diff --git a/src/main/scala-3/chisel3/util/Reg.scala b/src/main/scala-3/chisel3/util/Reg.scala new file mode 100644 index 00000000000..ba8e11c793d --- /dev/null +++ b/src/main/scala-3/chisel3/util/Reg.scala @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3.util + +import chisel3._ +import chisel3.experimental.SourceInfo + +object RegEnable extends RegEnableImpl { + + /** Returns a register with the specified next, update enable gate, and no reset initialization. + * + * @example {{{ + * val regWithEnable = RegEnable(nextVal, ena) + * }}} + */ + def apply[T <: Data](next: T, enable: Bool)(implicit sourceInfo: SourceInfo): T = _applyImpl(next, enable) + + /** Returns a register with the specified next, update enable gate, and reset initialization. + * + * @example {{{ + * val regWithEnableAndReset = RegEnable(nextVal, 0.U, ena) + * }}} + */ + def apply[T <: Data]( + next: T, + init: T, + enable: Bool + )( + implicit sourceInfo: SourceInfo + ): T = _applyImpl(next, init, enable) +} + +object ShiftRegister extends ShiftRegisterImpl { + + /** Returns the n-cycle delayed version of the input signal. + * + * @param in input to delay + * @param n number of cycles to delay + * @param en enable the shift + * + * @example {{{ + * val regDelayTwo = ShiftRegister(nextVal, 2, ena) + * }}} + */ + def apply[T <: Data]( + in: T, + n: Int, + en: Bool = true.B + )( + implicit sourceInfo: SourceInfo + ): T = + _applyImpl(in, n, en) + + /** Returns the n-cycle delayed version of the input signal. + * + * Enable is assumed to be true. + * + * @param in input to delay + * @param n number of cycles to delay + * + * @example {{{ + * val regDelayTwo = ShiftRegister(nextVal, 2) + * }}} + */ + def apply[T <: Data](in: T, n: Int)(implicit sourceInfo: SourceInfo): T = + _applyImpl(in, n) + + /** Returns the n-cycle delayed version of the input signal with reset initialization. + * + * @param in input to delay + * @param n number of cycles to delay + * @param resetData reset value for each register in the shift + * @param en enable the shift + * + * @example {{{ + * val regDelayTwoReset = ShiftRegister(nextVal, 2, 0.U, ena) + * }}} + */ + def apply[T <: Data]( + in: T, + n: Int, + resetData: T, + en: Bool + )( + implicit sourceInfo: SourceInfo + ): T = _applyImpl(in, n, resetData, en) + + /** Returns the n-cycle delayed version of the input signal (SyncReadMem-based ShiftRegister implementation). + * + * @param in input to delay + * @param n number of cycles to delay + * @param en enable the shift + * @param useDualPortSram dual port or single port SRAM based implementation + * @param name name of SyncReadMem object + */ + def mem[T <: Data]( + in: T, + n: Int, + en: Bool, + useDualPortSram: Boolean, + name: Option[String] + )( + implicit sourceInfo: SourceInfo + ): T = _applyImplMem(in, n, en, useDualPortSram, name) +} + +object ShiftRegisters extends ShiftRegistersImpl { + + /** Returns a sequence of delayed input signal registers from 1 to n. + * + * @param in input to delay + * @param n number of cycles to delay + * @param en enable the shift + */ + def apply[T <: Data]( + in: T, + n: Int, + en: Bool + )( + implicit sourceInfo: SourceInfo + ): Seq[T] = _applyImpl(in, n, en) + + /** Returns a sequence of delayed input signal registers from 1 to n. + * + * Enable is assumed to be true. + * + * @param in input to delay + * @param n number of cycles to delay + */ + def apply[T <: Data](in: T, n: Int)(implicit sourceInfo: SourceInfo): Seq[T] = + _applyImpl(in, n) + + /** Returns delayed input signal registers with reset initialization from 1 to n. + * + * @param in input to delay + * @param n number of cycles to delay + * @param resetData reset value for each register in the shift + * @param en enable the shift + */ + def apply[T <: Data]( + in: T, + n: Int, + resetData: T, + en: Bool + )( + implicit sourceInfo: SourceInfo + ): Seq[T] = _applyImpl(in, n, resetData, en) +} diff --git a/src/main/scala-3/chisel3/util/Switch.scala b/src/main/scala-3/chisel3/util/Switch.scala new file mode 100644 index 00000000000..553b5069dcc --- /dev/null +++ b/src/main/scala-3/chisel3/util/Switch.scala @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: Apache-2.0 + +/** Conditional blocks. + */ + +package chisel3.util + +import chisel3._ + +object switch { + def apply[T <: Element](cond: T)(x: => Any): Unit = println("Not supported yet") +} From cbaeaa5a760d7435dff49b4ed0851910bcee4ee2 Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Wed, 20 Nov 2024 12:00:44 -0800 Subject: [PATCH 02/30] Update build.sc --- build.sc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build.sc b/build.sc index 20480dd3830..1f2c8c06f73 100644 --- a/build.sc +++ b/build.sc @@ -38,6 +38,7 @@ object v extends Module { } val scalaCrossVersions = Seq( + "3.3.3", "2.13.15" ) @@ -251,7 +252,7 @@ trait Core extends CrossSbtModule with HasScala2MacroAnno with ScalafmtModule { ) override def ivyDeps = if (v.isScala3(crossScalaVersion)) { - super.ivyDeps() ++ commonDeps + super.ivyDeps() ++ commonDeps ++ Agg(v.firtoolResolver.withDottyCompat(scalaVersion())) } else { super.ivyDeps() ++ commonDeps ++ Agg(v.firtoolResolver) } @@ -313,7 +314,7 @@ trait Plugin extends CrossSbtModule with ScalafmtModule with ChiselPublishModule } object chisel extends Cross[Chisel](v.scalaCrossVersions) -trait Chisel extends CrossSbtModule with HasScala2MacroAnno with HasScala2Plugin with ScalafmtModule { +trait Chisel extends CrossSbtModule with HasScala2MacroAnno with ScalafmtModule { override def millSourcePath = super.millSourcePath / os.up def svsimModule = svsim(crossScalaVersion) def coreModule = core(crossScalaVersion) From fa910dcbce8ca52d9a8d338cd58261d90d209f0d Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Wed, 20 Nov 2024 12:00:51 -0800 Subject: [PATCH 03/30] Fix SerializableModuleGenerator --- .../chisel3/experimental/SerializableModuleGenerator.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/chisel3/experimental/SerializableModuleGenerator.scala b/core/src/main/scala/chisel3/experimental/SerializableModuleGenerator.scala index a48c2448e02..78526c18f77 100644 --- a/core/src/main/scala/chisel3/experimental/SerializableModuleGenerator.scala +++ b/core/src/main/scala/chisel3/experimental/SerializableModuleGenerator.scala @@ -63,7 +63,7 @@ case class SerializableModuleGenerator[M <: SerializableModule[P], P <: Serializ parameter: P )( implicit val pTag: universe.TypeTag[P], - implicit val mTag: universe.TypeTag[M]) { + val mTag: universe.TypeTag[M]) { private[chisel3] def construct: M with BaseModule = { require( generator.getConstructors.length == 1, From 88c18b6213f626351c77b2d0f6311f3ff0c3cdf7 Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Wed, 20 Nov 2024 12:23:20 -0800 Subject: [PATCH 04/30] Fix D/I sources to cross compile --- .../hierarchy/InstantiateImpl.scala | 104 ++++++++++++++++++ .../hierarchy/core/Hierarchy.scala | 68 ++++++++++++ .../hierarchy/core/Definition.scala | 1 - .../{Hierarchy.scala => HierarchyImpl.scala} | 61 +--------- .../hierarchy/core/Instance.scala | 2 +- 5 files changed, 174 insertions(+), 62 deletions(-) create mode 100644 core/src/main/scala-2/chisel3/experimental/hierarchy/InstantiateImpl.scala create mode 100644 core/src/main/scala-2/chisel3/experimental/hierarchy/core/Hierarchy.scala rename core/src/main/scala/chisel3/experimental/hierarchy/core/{Hierarchy.scala => HierarchyImpl.scala} (51%) diff --git a/core/src/main/scala-2/chisel3/experimental/hierarchy/InstantiateImpl.scala b/core/src/main/scala-2/chisel3/experimental/hierarchy/InstantiateImpl.scala new file mode 100644 index 00000000000..67f7fb9eadb --- /dev/null +++ b/core/src/main/scala-2/chisel3/experimental/hierarchy/InstantiateImpl.scala @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3.experimental.hierarchy + +import scala.reflect.runtime.{universe => ru} +import scala.collection.mutable + +import chisel3._ +import chisel3.experimental.{BaseModule, SourceInfo, UnlocatableSourceInfo} +import chisel3.reflect.DataMirror +import chisel3.reflect.DataMirror.internal.isSynthesizable +import chisel3.internal.Builder + +private[chisel3] trait InstantiateImpl { + + // Data uses referential equality by default, but for looking up Data in the cache, we need to use + // structural equality for Data unbound types and literal values + // Note that this is somewhat incomplete because we can't handle the general case of user-defined + // types that contain Data. + // A more complete and robust solution would require either refining hashCode and equality on Data + // to have the desired behavior, or using a different Map implementation that uses typeclasses for + // equality and hashcode (eg. cats-collections-core's HashMap) + private class DataBox(private val d: Data) { + + private def convertDataForHashing(data: Data): Any = data match { + // Using toString is a bit weird but it works + case elt: Element => elt.toString + case rec: Record => + // Purely structural, actual class of Record isn't involved + rec.elements.map { case (name, data) => name -> convertDataForHashing(data) } + case vec: Vec[_] => + // We could map on elements but that's a lot of duplicated work for a type + // Note that empty vecs of the same type will give same hash value, probably should be equal + // as well, but Vec.typeEquivalent checks sample_element so they will not be equal + ("Vec", vec.size, vec.headOption.map(convertDataForHashing(_))) + } + + override def hashCode: Int = convertDataForHashing(d).hashCode + + // If literals, check same types and equal + // If types, chck same types + // If bound, fall back to normal equality + override def equals(that: Any): Boolean = { + that match { + case that: DataBox => + // def because it's not needed by non-literal but is synthesizable check + def sameTypes = DataMirror.checkTypeEquivalence(this.d, that.d) + // Lits are synthesizable so must check them first + if (this.d.isLit) { + that.d.isLit && + (this.d.litValue == that.d.litValue) && + sameTypes + } else if (isSynthesizable(this.d)) { + this.d.equals(that.d) + } else { + // We have checked that this.d is not synthesizable but need to check that.d as well + sameTypes && !isSynthesizable(that.d) + } + + case _ => false + } + } + } + + // Recursively box all Data (by traversing Products and Iterables) in DataBoxes + private def boxAllData(a: Any): Any = a match { + case d: Data => new DataBox(d) // Must check this before Iterable because Vec is Iterable + // Must check before Product, because many Iterables are Products, but can still be equal, eg. List(1) == Vector(1) + case it: Iterable[_] => it.map(boxAllData(_)) + case p: Product => Vector(p.getClass) ++ p.productIterator.map(boxAllData(_)) + case other => other + } + + import chisel3.internal.BuilderContextCache + // Include type of module in key since different modules could have the same arguments + private case class CacheKey[A <: BaseModule](args: Any, tt: Any, modulePrefix: List[String]) + extends BuilderContextCache.Key[Definition[A]] + + protected def _instanceImpl[K, A <: BaseModule]( + args: K, + f: K => A, + tt: Any + )( + implicit sourceInfo: SourceInfo + ): Instance[A] = Instance.do_apply(_definitionImpl(args, f, tt))(sourceInfo) + + /** This is not part of the public API, do not call directly! */ + protected def _definitionImpl[K, A <: BaseModule]( + args: K, + f: K => A, + tt: Any + ): Definition[A] = { + val modulePrefix = Builder.getModulePrefixList + Builder.contextCache + .getOrElseUpdate( + CacheKey[A](boxAllData(args), tt, modulePrefix), { + // The definition needs to have no source locator because otherwise it will be unstably + // derived from the first invocation of Instantiate for the particular Module + Definition.do_apply(f(args))(UnlocatableSourceInfo) + } + ) + .asInstanceOf[Definition[A]] + } +} diff --git a/core/src/main/scala-2/chisel3/experimental/hierarchy/core/Hierarchy.scala b/core/src/main/scala-2/chisel3/experimental/hierarchy/core/Hierarchy.scala new file mode 100644 index 00000000000..7a6512a755b --- /dev/null +++ b/core/src/main/scala-2/chisel3/experimental/hierarchy/core/Hierarchy.scala @@ -0,0 +1,68 @@ +package chisel3.experimental.hierarchy.core + +import chisel3._ +import scala.collection.mutable.{HashMap, HashSet} +import chisel3.experimental.BaseModule +import _root_.firrtl.annotations.IsModule +import scala.reflect.runtime.universe.TypeTag + +trait Hierarchy[+A] extends HierarchyImpl[A] { +/** Determine whether underlying proto is of type provided. + * + * @note IMPORTANT: this function requires summoning a TypeTag[B], which will fail if B is an inner class. + * @note IMPORTANT: this function IGNORES type parameters, akin to normal type erasure. + * @note IMPORTANT: this function relies on Java reflection for underlying proto, but Scala reflection for provided type + * + * E.g. isA[List[Int]] will return true, even if underlying proto is of type List[String] + * @return Whether underlying proto is of provided type (with caveats outlined above) + */ + def isA[B: TypeTag]: Boolean = { + val tptag = implicitly[TypeTag[B]] + // drop any type information for the comparison, because the proto will not have that information. + val name = tptag.tpe.toString.takeWhile(_ != '[') + inBaseClasses(name) + } + +} + +object Hierarchy { + implicit class HierarchyBaseModuleExtensions[T <: BaseModule](i: Hierarchy[T]) { + + /** Returns the toTarget of this hierarchy + * @return target of this hierarchy + */ + def toTarget: IsModule = i match { + case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toTarget + case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toTarget + case _ => throw new InternalErrorException("Match error: toTarget i=$i") + } + + /** Returns the toAbsoluteTarget of this hierarchy + * @return absoluteTarget of this Hierarchy + */ + def toAbsoluteTarget: IsModule = i match { + case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toAbsoluteTarget + case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toAbsoluteTarget + case _ => throw new InternalErrorException("Match error: toAbsoluteTarget i=$i") + } + + /** Returns the toRelativeTarget of this hierarchy + * @return relativeTarget of this Hierarchy + */ + def toRelativeTarget(root: Option[BaseModule]): IsModule = i match { + case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toRelativeTarget(root) + case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toRelativeTarget(root) + case _ => throw new InternalErrorException("Match error: toAbsoluteTarget i=$i") + } + + /** Returns the toRelativeTarget of this hierarchy + * @return relativeTarget of this Hierarchy + */ + def toRelativeTargetToHierarchy(root: Option[Hierarchy[BaseModule]]): IsModule = i match { + case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toRelativeTargetToHierarchy(root) + case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toRelativeTargetToHierarchy(root) + case _ => throw new InternalErrorException("Match error: toAbsoluteTarget i=$i") + } + + } +} diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/core/Definition.scala b/core/src/main/scala/chisel3/experimental/hierarchy/core/Definition.scala index 7f584963877..398dccefc2b 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/core/Definition.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/core/Definition.scala @@ -9,7 +9,6 @@ import chisel3.internal.{Builder, DynamicContext} import chisel3.internal.firrtl.Converter import chisel3.experimental.{BaseModule, SourceInfo} import firrtl.annotations.{IsModule, ModuleTarget, NoTargetAnnotation} - import firrtl.seqToAnnoSeq import scala.annotation.nowarn diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/core/Hierarchy.scala b/core/src/main/scala/chisel3/experimental/hierarchy/core/HierarchyImpl.scala similarity index 51% rename from core/src/main/scala/chisel3/experimental/hierarchy/core/Hierarchy.scala rename to core/src/main/scala/chisel3/experimental/hierarchy/core/HierarchyImpl.scala index a3d212f0543..f7e09d568e4 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/core/Hierarchy.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/core/HierarchyImpl.scala @@ -5,7 +5,6 @@ package chisel3.experimental.hierarchy.core import chisel3._ import scala.collection.mutable.{HashMap, HashSet} -import scala.reflect.runtime.universe.TypeTag import chisel3.experimental.BaseModule import _root_.firrtl.annotations.IsModule @@ -15,7 +14,7 @@ import scala.annotation.implicitNotFound * * Enables writing functions which are Instance/Definition agnostic */ -sealed trait Hierarchy[+A] { +trait HierarchyImpl[+A] { private[chisel3] def underlying: Underlying[A] private[chisel3] def proto: A = underlying match { case Proto(value) => value @@ -26,22 +25,6 @@ sealed trait Hierarchy[+A] { private[chisel3] val cache = HashMap[Data, Data]() private[chisel3] def getInnerDataContext: Option[BaseModule] - /** Determine whether underlying proto is of type provided. - * - * @note IMPORTANT: this function requires summoning a TypeTag[B], which will fail if B is an inner class. - * @note IMPORTANT: this function IGNORES type parameters, akin to normal type erasure. - * @note IMPORTANT: this function relies on Java reflection for underlying proto, but Scala reflection for provided type - * - * E.g. isA[List[Int]] will return true, even if underlying proto is of type List[String] - * @return Whether underlying proto is of provided type (with caveats outlined above) - */ - def isA[B: TypeTag]: Boolean = { - val tptag = implicitly[TypeTag[B]] - // drop any type information for the comparison, because the proto will not have that information. - val name = tptag.tpe.toString.takeWhile(_ != '[') - inBaseClasses(name) - } - // This code handles a special-case where, within an mdoc context, the type returned from // scala reflection (typetag) looks different than when returned from java reflection. // This function detects this case and reshapes the string to match. @@ -95,45 +78,3 @@ sealed trait Hierarchy[+A] { // Used to effectively seal Hierarchy, without requiring Definition and Instance to be in this file. private[chisel3] trait SealedHierarchy[+A] extends Hierarchy[A] - -object Hierarchy { - implicit class HierarchyBaseModuleExtensions[T <: BaseModule](i: Hierarchy[T]) { - - /** Returns the toTarget of this hierarchy - * @return target of this hierarchy - */ - def toTarget: IsModule = i match { - case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toTarget - case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toTarget - case _ => throw new InternalErrorException(s"Match error: toTarget i=$i") - } - - /** Returns the toAbsoluteTarget of this hierarchy - * @return absoluteTarget of this Hierarchy - */ - def toAbsoluteTarget: IsModule = i match { - case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toAbsoluteTarget - case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toAbsoluteTarget - case _ => throw new InternalErrorException(s"Match error: toAbsoluteTarget i=$i") - } - - /** Returns the toRelativeTarget of this hierarchy - * @return relativeTarget of this Hierarchy - */ - def toRelativeTarget(root: Option[BaseModule]): IsModule = i match { - case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toRelativeTarget(root) - case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toRelativeTarget(root) - case _ => throw new InternalErrorException(s"Match error: toAbsoluteTarget i=$i") - } - - /** Returns the toRelativeTarget of this hierarchy - * @return relativeTarget of this Hierarchy - */ - def toRelativeTargetToHierarchy(root: Option[Hierarchy[BaseModule]]): IsModule = i match { - case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toRelativeTargetToHierarchy(root) - case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toRelativeTargetToHierarchy(root) - case _ => throw new InternalErrorException(s"Match error: toAbsoluteTarget i=$i") - } - - } -} diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/core/Instance.scala b/core/src/main/scala/chisel3/experimental/hierarchy/core/Instance.scala index ebacfee5a95..d10a667303b 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/core/Instance.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/core/Instance.scala @@ -166,7 +166,7 @@ object Instance extends SourceInfoDoc { Some(component) } } - Definition(new EmptyExtModule() {}) + Definition(new EmptyExtModule() {}.asInstanceOf[Underlying[_]]) } val ports = experimental.CloneModuleAsRecord(definition.proto) From c8a1fcc1bb552a71af7cf4b8b66bead78992e62e Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Wed, 20 Nov 2024 12:24:29 -0800 Subject: [PATCH 05/30] Move SerializableModuleGenerator --- .../chisel3/experimental/SerializableModuleGenerator.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename core/src/main/{scala => scala-2}/chisel3/experimental/SerializableModuleGenerator.scala (98%) diff --git a/core/src/main/scala/chisel3/experimental/SerializableModuleGenerator.scala b/core/src/main/scala-2/chisel3/experimental/SerializableModuleGenerator.scala similarity index 98% rename from core/src/main/scala/chisel3/experimental/SerializableModuleGenerator.scala rename to core/src/main/scala-2/chisel3/experimental/SerializableModuleGenerator.scala index 78526c18f77..a48c2448e02 100644 --- a/core/src/main/scala/chisel3/experimental/SerializableModuleGenerator.scala +++ b/core/src/main/scala-2/chisel3/experimental/SerializableModuleGenerator.scala @@ -63,7 +63,7 @@ case class SerializableModuleGenerator[M <: SerializableModule[P], P <: Serializ parameter: P )( implicit val pTag: universe.TypeTag[P], - val mTag: universe.TypeTag[M]) { + implicit val mTag: universe.TypeTag[M]) { private[chisel3] def construct: M with BaseModule = { require( generator.getConstructors.length == 1, From fe3a9a7acc59c3b395d8beb930bd63c63932162d Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Wed, 20 Nov 2024 12:26:50 -0800 Subject: [PATCH 06/30] Remove copy method from IR --- .../src/main/scala/chisel3/internal/firrtl/IR.scala | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/core/src/main/scala/chisel3/internal/firrtl/IR.scala b/core/src/main/scala/chisel3/internal/firrtl/IR.scala index dd2ae4816f9..85cf656759c 100644 --- a/core/src/main/scala/chisel3/internal/firrtl/IR.scala +++ b/core/src/main/scala/chisel3/internal/firrtl/IR.scala @@ -544,19 +544,6 @@ private[chisel3] object ir { annotations.flatMap(_.toFirrtl.update(renames)) ++ newAnnotations.flatMap( _.toFirrtl.flatMap(_.update(renames)) ) - - // TODO this method doesn't compile with Scala3 because it - // conflicts with the built-in `copy` method - def copy( - name: String = name, - components: Seq[Component] = components, - annotations: Seq[ChiselAnnotation] = annotations, - renames: RenameMap = renames, - typeAliases: Seq[DefTypeAlias] = typeAliases, - layers: Seq[Layer] = layers, - options: Seq[DefOption] = options - ) = Circuit(name, components, annotations, renames, newAnnotations, typeAliases, layers, options) - } object Circuit From cb866e2cef1545924c99b046e4a379fe620eb278 Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Wed, 20 Nov 2024 12:27:25 -0800 Subject: [PATCH 07/30] Explicit import in ModuleImpl --- core/src/main/scala/chisel3/ModuleImpl.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/scala/chisel3/ModuleImpl.scala b/core/src/main/scala/chisel3/ModuleImpl.scala index 30b220148a1..95cd323b6c6 100644 --- a/core/src/main/scala/chisel3/ModuleImpl.scala +++ b/core/src/main/scala/chisel3/ModuleImpl.scala @@ -5,6 +5,7 @@ package chisel3 import scala.collection.immutable.{ListMap, VectorBuilder} import scala.collection.mutable.{ArrayBuffer, HashMap, LinkedHashSet} +import chisel3.experimental.hierarchy.core.Hierarchy.HierarchyBaseModuleExtensions import chisel3.internal._ import chisel3.internal.binding._ import chisel3.internal.Builder._ From 8103a017cd7998bdd0b60f00fddda6aef7955604 Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Mon, 25 Nov 2024 14:35:35 -0800 Subject: [PATCH 08/30] Cross compilation fixes --- .../dataview/ChiselSubtypeOf.scala | 2 + core/src/main/scala/chisel3/BitsImpl.scala | 16 +-- .../main/scala/chisel3/ChiselEnumImpl.scala | 19 +++- .../experimental/dataview/DataView.scala | 1 - .../experimental/dataview/package.scala | 2 +- .../hierarchy/InstantiateImpl.scala | 104 ------------------ .../scala/chisel3/experimental/package.scala | 6 +- core/src/main/scala/chisel3/package.scala | 1 - .../scala/chisel3/properties/Property.scala | 13 +-- 9 files changed, 28 insertions(+), 136 deletions(-) delete mode 100644 core/src/main/scala/chisel3/experimental/hierarchy/InstantiateImpl.scala diff --git a/core/src/main/scala-2/chisel3/experimental/dataview/ChiselSubtypeOf.scala b/core/src/main/scala-2/chisel3/experimental/dataview/ChiselSubtypeOf.scala index b8ca824c7ab..3a6932552f6 100644 --- a/core/src/main/scala-2/chisel3/experimental/dataview/ChiselSubtypeOf.scala +++ b/core/src/main/scala-2/chisel3/experimental/dataview/ChiselSubtypeOf.scala @@ -27,6 +27,8 @@ import scala.reflect.macros.blackbox.Context */ sealed trait ChiselSubtypeOf[A, B] + +// return an empty tree here instead of a quasiquote for scala3 compatibility object ChiselSubtypeOf { // TODO return an empty tree here instead of a quasiquote for scala3 compatibility def genChiselSubtypeOf[A: c.WeakTypeTag, B: c.WeakTypeTag](c: Context): c.Tree = { diff --git a/core/src/main/scala/chisel3/BitsImpl.scala b/core/src/main/scala/chisel3/BitsImpl.scala index a6f44a938cd..98c5f2b6f42 100644 --- a/core/src/main/scala/chisel3/BitsImpl.scala +++ b/core/src/main/scala/chisel3/BitsImpl.scala @@ -23,15 +23,15 @@ private[chisel3] trait BitsImpl extends Element { self: Bits => // Only used for in a few cases, hopefully to be removed private[chisel3] def cloneTypeWidth(width: Width): this.type - def cloneType: this.type = cloneTypeWidth(width) + def cloneType: this.type = cloneTypeWidth(this.width) /** A non-ambiguous name of this `Bits` instance for use in generated Verilog names * Inserts the width directly after the typeName, e.g. UInt4, SInt1 */ - override def typeName: String = s"${simpleClassName(this.getClass)}$width" + override def typeName: String = s"${simpleClassName(this.getClass)}${this.width}" protected def _tailImpl(n: Int)(implicit sourceInfo: SourceInfo): UInt = { - val w = width match { + val w = this.width match { case KnownWidth(x) => require(x >= n, s"Can't tail($n) for width $x < $n") Width(x - n) @@ -99,7 +99,7 @@ private[chisel3] trait BitsImpl extends Element { self: Bits => } protected def _applyImpl(x: UInt)(implicit sourceInfo: SourceInfo): Bool = - do_extract(x) + extract(x) protected def _applyImpl(x: Int, y: Int)(implicit sourceInfo: SourceInfo): UInt = { if ((x < y && !(x == -1 && y == 0)) || y < 0) { @@ -330,15 +330,15 @@ private[chisel3] trait UIntImpl extends BitsImpl with Num[UInt] { self: UInt => protected def _rotateLeftImpl(n: Int)(implicit sourceInfo: SourceInfo): UInt = width match { case _ if (n == 0) => this case KnownWidth(w) if (w <= 1) => this - case KnownWidth(w) if n >= w => do_rotateLeft(n % w) - case _ if (n < 0) => do_rotateRight(-n) + case KnownWidth(w) if n >= w => rotateLeft(n % w) + case _ if (n < 0) => rotateRight(-n) case _ => tail(n) ## head(n) } protected def _rotateRightImpl(n: Int)(implicit sourceInfo: SourceInfo): UInt = width match { - case _ if (n <= 0) => do_rotateLeft(-n) + case _ if (n <= 0) => rotateLeft(-n) case KnownWidth(w) if (w <= 1) => this - case KnownWidth(w) if n >= w => do_rotateRight(n % w) + case KnownWidth(w) if n >= w => rotateRight(n % w) case _ => this(n - 1, 0) ## (this >> n) } diff --git a/core/src/main/scala/chisel3/ChiselEnumImpl.scala b/core/src/main/scala/chisel3/ChiselEnumImpl.scala index f0cfd7534dc..2d3af56f596 100644 --- a/core/src/main/scala/chisel3/ChiselEnumImpl.scala +++ b/core/src/main/scala/chisel3/ChiselEnumImpl.scala @@ -70,8 +70,8 @@ private[chisel3] abstract class EnumTypeImpl(private[chisel3] val factory: Chise _wire := this.asUInt _wire } - _padded.do_asTypeOf(that) - case None => super.do_asTypeOf(that) + _padded.asTypeOf(that) + case None => super.asTypeOf(that) } } @@ -154,7 +154,7 @@ private[chisel3] abstract class EnumTypeImpl(private[chisel3] val factory: Chise } // This function conducts a depth-wise search to find all enum-type fields within a vector or bundle (or vector of bundles) - private def enumFields(d: Aggregate): Seq[Seq[String]] = d match { + private def enumFields(d: Data): Seq[Seq[String]] = d match { case v: Vec[_] => v.sample_element match { case b: Bundle => enumFields(b) @@ -222,7 +222,15 @@ private[chisel3] abstract class EnumTypeImpl(private[chisel3] val factory: Chise for ((name, value) <- allNamesPadded) { when(this === value) { for ((r, c) <- result.zip(name)) { - r := c.toChar.U + // todo: this doesn't work in scala3 + // r := c.toChar.U + // ^^^^^^^^^^ + // value U is not a member of Char. + // An extension method was tried, + // but could not be fully constructed: + // + // chisel3.fromLongToLiteral(c.toChar) + // r := c.toChar.U } } } @@ -355,7 +363,8 @@ private[chisel3] trait ChiselEnumImpl { self: ChiselEnum => // This is an enum type that can be connected directly to UInts. It is used as a "glue" to cast non-literal UInts // to enums. private[chisel3] class UnsafeEnum(override val width: Width) extends EnumType(UnsafeEnum, selfAnnotating = false) { - override def cloneType: this.type = new UnsafeEnum(width).asInstanceOf[this.type] + + override def _cloneType: Data = new UnsafeEnum(width) } private object UnsafeEnum extends ChiselEnum diff --git a/core/src/main/scala/chisel3/experimental/dataview/DataView.scala b/core/src/main/scala/chisel3/experimental/dataview/DataView.scala index a9e22e8ca50..7641b39c99a 100644 --- a/core/src/main/scala/chisel3/experimental/dataview/DataView.scala +++ b/core/src/main/scala/chisel3/experimental/dataview/DataView.scala @@ -7,7 +7,6 @@ import chisel3.reflect.DataMirror.internal.chiselTypeClone import chisel3.experimental.{HWTuple10, HWTuple2, HWTuple3, HWTuple4, HWTuple5, HWTuple6, HWTuple7, HWTuple8, HWTuple9} import chisel3.experimental.{ChiselSubtypeOf, SourceInfo, UnlocatableSourceInfo} -import scala.reflect.runtime.universe.WeakTypeTag import annotation.implicitNotFound /** Mapping between a target type `T` and a view type `V` diff --git a/core/src/main/scala/chisel3/experimental/dataview/package.scala b/core/src/main/scala/chisel3/experimental/dataview/package.scala index 6e8b0320094..9f2947172e7 100644 --- a/core/src/main/scala/chisel3/experimental/dataview/package.scala +++ b/core/src/main/scala/chisel3/experimental/dataview/package.scala @@ -73,7 +73,7 @@ package object dataview { /** View a [[Bundle]] or [[Record]] as a parent type (upcast) */ def viewAsSupertype[V <: Record](proto: V)(implicit ev: ChiselSubtypeOf[T, V], sourceInfo: SourceInfo): V = { - implicit val dataView = PartialDataView.supertype[T, V](_ => proto) + implicit val dataView: DataView[T, V] = PartialDataView.supertype[T, V](_ => proto) target.viewAs[V] } } diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/InstantiateImpl.scala b/core/src/main/scala/chisel3/experimental/hierarchy/InstantiateImpl.scala deleted file mode 100644 index aa052e5c870..00000000000 --- a/core/src/main/scala/chisel3/experimental/hierarchy/InstantiateImpl.scala +++ /dev/null @@ -1,104 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -package chisel3.experimental.hierarchy - -import scala.reflect.runtime.{universe => ru} -import scala.collection.mutable - -import chisel3._ -import chisel3.experimental.{BaseModule, SourceInfo, UnlocatableSourceInfo} -import chisel3.reflect.DataMirror -import chisel3.reflect.DataMirror.internal.isSynthesizable -import chisel3.internal.Builder - -private[chisel3] trait InstantiateImpl { - - // Data uses referential equality by default, but for looking up Data in the cache, we need to use - // structural equality for Data unbound types and literal values - // Note that this is somewhat incomplete because we can't handle the general case of user-defined - // types that contain Data. - // A more complete and robust solution would require either refining hashCode and equality on Data - // to have the desired behavior, or using a different Map implementation that uses typeclasses for - // equality and hashcode (eg. cats-collections-core's HashMap) - private class DataBox(private val d: Data) { - - private def convertDataForHashing(data: Data): Any = data match { - // Using toString is a bit weird but it works - case elt: Element => elt.toString - case rec: Record => - // Purely structural, actual class of Record isn't involved - rec.elements.map { case (name, data) => name -> convertDataForHashing(data) } - case vec: Vec[_] => - // We could map on elements but that's a lot of duplicated work for a type - // Note that empty vecs of the same type will give same hash value, probably should be equal - // as well, but Vec.typeEquivalent checks sample_element so they will not be equal - ("Vec", vec.size, vec.headOption.map(convertDataForHashing(_))) - } - - override def hashCode: Int = convertDataForHashing(d).hashCode - - // If literals, check same types and equal - // If types, chck same types - // If bound, fall back to normal equality - override def equals(that: Any): Boolean = { - that match { - case that: DataBox => - // def because it's not needed by non-literal but is synthesizable check - def sameTypes = DataMirror.checkTypeEquivalence(this.d, that.d) - // Lits are synthesizable so must check them first - if (this.d.isLit) { - that.d.isLit && - (this.d.litValue == that.d.litValue) && - sameTypes - } else if (isSynthesizable(this.d)) { - this.d.equals(that.d) - } else { - // We have checked that this.d is not synthesizable but need to check that.d as well - sameTypes && !isSynthesizable(that.d) - } - - case _ => false - } - } - } - - // Recursively box all Data (by traversing Products and Iterables) in DataBoxes - private def boxAllData(a: Any): Any = a match { - case d: Data => new DataBox(d) // Must check this before Iterable because Vec is Iterable - // Must check before Product, because many Iterables are Products, but can still be equal, eg. List(1) == Vector(1) - case it: Iterable[_] => it.map(boxAllData(_)) - case p: Product => Vector(p.getClass) ++ p.productIterator.map(boxAllData(_)) - case other => other - } - - import chisel3.internal.BuilderContextCache - // Include type of module in key since different modules could have the same arguments - private case class CacheKey[A <: BaseModule](args: Any, tt: Any, modulePrefix: String) - extends BuilderContextCache.Key[Definition[A]] - - protected def _instanceImpl[K, A <: BaseModule]( - args: K, - f: K => A, - tt: Any - )( - implicit sourceInfo: SourceInfo - ): Instance[A] = Instance.apply(_definitionImpl(args, f, tt))(sourceInfo) - - /** This is not part of the public API, do not call directly! */ - protected def _definitionImpl[K, A <: BaseModule]( - args: K, - f: K => A, - tt: Any - ): Definition[A] = { - val modulePrefix = Module.currentModulePrefix - Builder.contextCache - .getOrElseUpdate( - CacheKey[A](boxAllData(args), tt, modulePrefix), { - // The definition needs to have no source locator because otherwise it will be unstably - // derived from the first invocation of Instantiate for the particular Module - Definition.apply(f(args))(UnlocatableSourceInfo) - } - ) - .asInstanceOf[Definition[A]] - } -} diff --git a/core/src/main/scala/chisel3/experimental/package.scala b/core/src/main/scala/chisel3/experimental/package.scala index b8e47563ba2..38420729e69 100644 --- a/core/src/main/scala/chisel3/experimental/package.scala +++ b/core/src/main/scala/chisel3/experimental/package.scala @@ -91,9 +91,6 @@ package object experimental { @deprecated("FlatIO has moved to package chisel3", "Chisel 6.0") val FlatIO = chisel3.FlatIO - class dump extends chisel3.internal.naming.dump - class treedump extends chisel3.internal.naming.treedump - /** Generate prefixes from values of this type in the Chisel compiler plugin * * Users can mixin this trait to tell the Chisel compiler plugin to include the names of @@ -132,7 +129,8 @@ package object experimental { object BundleLiterals { implicit class AddBundleLiteralConstructor[T <: Record](x: T) { def Lit(elems: (T => (Data, Data))*)(implicit sourceInfo: SourceInfo): T = { - x._makeLit(elems: _*) + val fs = elems.map(_.asInstanceOf[Data => (Data, Data)]) + x._makeLit(fs: _*).asInstanceOf[T] } } } diff --git a/core/src/main/scala/chisel3/package.scala b/core/src/main/scala/chisel3/package.scala index 4f349d76151..f150f5c0c99 100644 --- a/core/src/main/scala/chisel3/package.scala +++ b/core/src/main/scala/chisel3/package.scala @@ -12,7 +12,6 @@ import scala.annotation.{nowarn, tailrec} /** This package contains the main chisel3 API. */ package object chisel3 { - import internal.chiselRuntimeDeprecated import experimental.{DeprecatedSourceInfo, UnlocatableSourceInfo} import internal.firrtl.ir.Port import internal.Builder diff --git a/core/src/main/scala/chisel3/properties/Property.scala b/core/src/main/scala/chisel3/properties/Property.scala index 1287e9ec685..8526bb34fd3 100644 --- a/core/src/main/scala/chisel3/properties/Property.scala +++ b/core/src/main/scala/chisel3/properties/Property.scala @@ -10,7 +10,6 @@ import chisel3.internal.binding._ import chisel3.internal.firrtl.{ir, Converter} import chisel3.experimental.{prefix, requireIsHardware, Analog, SourceInfo} import chisel3.experimental.hierarchy.Instance -import scala.reflect.runtime.universe.{typeOf, TypeTag} import scala.annotation.{implicitAmbiguous, implicitNotFound} import chisel3.experimental.BaseModule import chisel3.internal.NamedComponent @@ -278,18 +277,8 @@ sealed trait Property[T] extends Element { self => /** Clone type by simply constructing a new Property[T]. */ - override def cloneType: this.type = new Property[T] { + override def _cloneType: Data = new Property[T] { val tpe = self.tpe - }.asInstanceOf[this.type] - - /** Clone type with extra information preserved. - * - * The only extra information present on a Property type is directionality. - */ - private[chisel3] override def cloneTypeFull: this.type = { - val clone = this.cloneType - clone.specifiedDirection = specifiedDirection - clone } /** Get the IR PropertyType for this Property. From dbd96b793bd6ee0ae217afcdb772e1250ed908ea Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Mon, 25 Nov 2024 14:41:24 -0800 Subject: [PATCH 09/30] Convert cloneType to an extension method This removes much of the use of this.type in Chisel which is necessary to upgrade to Scala 3. --- core/src/main/scala-2/chisel3/Bits.scala | 6 +- .../main/scala/chisel3/AggregateImpl.scala | 19 ++++--- core/src/main/scala/chisel3/BitsImpl.scala | 21 ++++--- .../main/scala/chisel3/ChiselEnumImpl.scala | 2 +- core/src/main/scala/chisel3/ClockImpl.scala | 2 +- core/src/main/scala/chisel3/DataImpl.scala | 56 ++++++++++++------- core/src/main/scala/chisel3/IO.scala | 1 + core/src/main/scala/chisel3/Intrinsic.scala | 1 + core/src/main/scala/chisel3/MemImpl.scala | 1 + core/src/main/scala/chisel3/ModuleImpl.scala | 3 +- core/src/main/scala/chisel3/Reg.scala | 1 + .../scala/chisel3/experimental/Analog.scala | 2 +- .../hierarchy/core/Lookupable.scala | 1 + .../scala/chisel3/probe/PackageImpl.scala | 1 + .../scala/chisel3/probe/ProbeValueBase.scala | 2 +- .../scala/chisel3/reflect/DataMirror.scala | 1 + .../chisel3/choice/ModuleChoiceImpl.scala | 1 + src/main/scala/chisel3/util/MixedVec.scala | 1 + 18 files changed, 72 insertions(+), 50 deletions(-) diff --git a/core/src/main/scala-2/chisel3/Bits.scala b/core/src/main/scala-2/chisel3/Bits.scala index a2c5b4274b0..8fd844c4ea6 100644 --- a/core/src/main/scala-2/chisel3/Bits.scala +++ b/core/src/main/scala-2/chisel3/Bits.scala @@ -160,10 +160,10 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends BitsImpl w * @note For [[SInt]]s only, this will do sign extension. * @group Bitwise */ - final def pad(that: Int): this.type = macro SourceInfoTransform.thatArg + final def pad(that: Int): Bits = macro SourceInfoWhiteboxTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_pad(that: Int)(implicit sourceInfo: SourceInfo): this.type = _padImpl(that) + def do_pad(that: Int)(implicit sourceInfo: SourceInfo): Bits = _padImpl(that) /** Bitwise inversion operator * @@ -182,8 +182,6 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends BitsImpl w * $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 */ diff --git a/core/src/main/scala/chisel3/AggregateImpl.scala b/core/src/main/scala/chisel3/AggregateImpl.scala index e878c8c089f..67bf233ff11 100644 --- a/core/src/main/scala/chisel3/AggregateImpl.scala +++ b/core/src/main/scala/chisel3/AggregateImpl.scala @@ -4,6 +4,7 @@ package chisel3 import chisel3.experimental.VecLiterals.AddVecLiteralConstructor import chisel3.experimental.dataview.{isView, reify, reifyIdentityView, InvalidViewException} +import chisel3.Data.DataExtensions import scala.collection.immutable.{SeqMap, VectorMap} import scala.collection.mutable.{HashSet, LinkedHashMap} @@ -421,9 +422,7 @@ private[chisel3] abstract class VecImpl[T <: Data] private[chisel3] (gen: => T, */ def apply(idx: Int): T = self(idx) - override def cloneType: this.type = { - new Vec(gen.cloneTypeFull, length).asInstanceOf[this.type] - } + override def _cloneType: Vec[T] = new Vec(gen.cloneTypeFull, length) override def getElements: Seq[Data] = self @@ -491,7 +490,7 @@ private[chisel3] abstract class VecImpl[T <: Data] private[chisel3] (gen: => T, elementInitializers: (Int, T)* )( implicit sourceInfo: SourceInfo - ): this.type = { + ): Vec[T] = { def checkLiteralConstruction(): Unit = { val dupKeys = elementInitializers.map { x => x._1 }.groupBy(x => x).flatMap { @@ -543,7 +542,7 @@ private[chisel3] abstract class VecImpl[T <: Data] private[chisel3] (gen: => T, requireIsChiselType(this, "vec literal constructor model") checkLiteralConstruction() - val clone = cloneType + val clone = this.cloneType val cloneFields = getRecursiveFields(clone, "(vec root)").toMap // Create the Vec literal binding from litArgs of arguments @@ -832,8 +831,10 @@ private[chisel3] trait RecordImpl extends AggregateImpl { thiz: Record => } } - override def cloneType: this.type = { - val clone = _cloneTypeImpl.asInstanceOf[this.type] + // Note that _cloneTypeImpl is implemented by the compiler plugin and must be a different method name because + // We want to run checkClone after calling _cloneTypeImpl + final override def _cloneType: Data = { + val clone = _cloneTypeImpl checkClone(clone) clone } @@ -953,10 +954,10 @@ private[chisel3] trait RecordImpl extends AggregateImpl { thiz: Record => * ) * }}} */ - private[chisel3] def _makeLit(elems: (this.type => (Data, Data))*)(implicit sourceInfo: SourceInfo): this.type = { + private[chisel3] def _makeLit(elems: (Data => (Data, Data))*)(implicit sourceInfo: SourceInfo): Data = { requireIsChiselType(this, "bundle literal constructor model") - val clone = cloneType + val clone = this.cloneType val cloneFields = getRecursiveFields(clone, "_").toMap // Create the Bundle literal binding from litargs of arguments diff --git a/core/src/main/scala/chisel3/BitsImpl.scala b/core/src/main/scala/chisel3/BitsImpl.scala index 98c5f2b6f42..d003c1ddb22 100644 --- a/core/src/main/scala/chisel3/BitsImpl.scala +++ b/core/src/main/scala/chisel3/BitsImpl.scala @@ -2,6 +2,7 @@ package chisel3 +import chisel3.Data.DataExtensions import chisel3.experimental.{requireIsHardware, SourceInfo} import chisel3.internal.{_resizeToWidth, throwException, BaseModule} import chisel3.internal.Builder.pushOp @@ -21,9 +22,9 @@ private[chisel3] trait BitsImpl extends Element { self: Bits => // Arguments against: generates down to a FIRRTL UInt anyways // Only used for in a few cases, hopefully to be removed - private[chisel3] def cloneTypeWidth(width: Width): this.type + private[chisel3] def cloneTypeWidth(width: Width): Bits - def cloneType: this.type = cloneTypeWidth(this.width) + override def _cloneType: Data = cloneTypeWidth(this.width) /** A non-ambiguous name of this `Bits` instance for use in generated Verilog names * Inserts the width directly after the typeName, e.g. UInt4, SInt1 @@ -167,7 +168,7 @@ private[chisel3] trait BitsImpl extends Element { self: Bits => // Pad literal to that width protected def _padLit(that: Int): this.type - protected def _padImpl(that: Int)(implicit sourceInfo: SourceInfo): this.type = this.width match { + protected def _padImpl(that: Int)(implicit sourceInfo: SourceInfo): Bits = this.width match { case KnownWidth(w) if w >= that => this case _ if this.isLit => this._padLit(that) case _ => binop(sourceInfo, cloneTypeWidth(this.width.max(Width(that))), PadOp, that) @@ -222,8 +223,7 @@ private[chisel3] trait UIntImpl extends BitsImpl with Num[UInt] { self: UInt => } } - private[chisel3] override def cloneTypeWidth(w: Width): this.type = - new UInt(w).asInstanceOf[this.type] + private[chisel3] override def cloneTypeWidth(w: Width): UInt = new UInt(w) override protected def _padLit(that: Int): this.type = { val value = this.litValue @@ -403,8 +403,7 @@ private[chisel3] trait SIntImpl extends BitsImpl with Num[SInt] { self: SInt => } } - private[chisel3] override def cloneTypeWidth(w: Width): this.type = - new SInt(w).asInstanceOf[this.type] + private[chisel3] override def cloneTypeWidth(w: Width): SInt = new SInt(w) override protected def _padLit(that: Int): this.type = { val value = this.litValue @@ -529,7 +528,7 @@ private[chisel3] trait ResetTypeImpl extends Element { self: Reset => override def toString: String = stringAccessor("Reset") - def cloneType: this.type = Reset().asInstanceOf[this.type] + override def _cloneType: Data = Reset() override def litOption: Option[BigInt] = None @@ -558,7 +557,7 @@ private[chisel3] trait AsyncResetImpl extends Element { self: AsyncReset => override def toString: String = stringAccessor("AsyncReset") - def cloneType: this.type = AsyncReset().asInstanceOf[this.type] + override def _cloneType: Data = AsyncReset() override def litOption: Option[BigInt] = None @@ -599,9 +598,9 @@ private[chisel3] trait BoolImpl extends UIntImpl { self: Bool => } } - private[chisel3] override def cloneTypeWidth(w: Width): this.type = { + private[chisel3] override def cloneTypeWidth(w: Width): Bool = { require(!w.known || w.get == 1) - new Bool().asInstanceOf[this.type] + new Bool() } /** Convert to a [[scala.Option]] of [[scala.Boolean]] */ diff --git a/core/src/main/scala/chisel3/ChiselEnumImpl.scala b/core/src/main/scala/chisel3/ChiselEnumImpl.scala index 2d3af56f596..390afc47f71 100644 --- a/core/src/main/scala/chisel3/ChiselEnumImpl.scala +++ b/core/src/main/scala/chisel3/ChiselEnumImpl.scala @@ -30,7 +30,7 @@ private[chisel3] abstract class EnumTypeImpl(private[chisel3] val factory: Chise } } - override def cloneType: this.type = factory().asInstanceOf[this.type] + override def _cloneType: Data = factory() private[chisel3] def compop(sourceInfo: SourceInfo, op: PrimOp, other: EnumType): Bool = { requireIsHardware(this, "bits operated on") diff --git a/core/src/main/scala/chisel3/ClockImpl.scala b/core/src/main/scala/chisel3/ClockImpl.scala index cf4e26b8d0e..70f2dfc0b05 100644 --- a/core/src/main/scala/chisel3/ClockImpl.scala +++ b/core/src/main/scala/chisel3/ClockImpl.scala @@ -13,7 +13,7 @@ private[chisel3] trait ClockImpl extends Element { override def toString: String = stringAccessor("Clock") - def cloneType: this.type = Clock().asInstanceOf[this.type] + override def _cloneType: Data = Clock() override def connect(that: Data)(implicit sourceInfo: SourceInfo): Unit = that match { diff --git a/core/src/main/scala/chisel3/DataImpl.scala b/core/src/main/scala/chisel3/DataImpl.scala index e262dbd7bdc..6dc94ba1b10 100644 --- a/core/src/main/scala/chisel3/DataImpl.scala +++ b/core/src/main/scala/chisel3/DataImpl.scala @@ -4,6 +4,7 @@ package chisel3 import chisel3.experimental.dataview.reify +import chisel3.Data.DataExtensions import chisel3.experimental.{requireIsChiselType, requireIsHardware, Analog, BaseModule} import chisel3.experimental.{prefix, SourceInfo, UnlocatableSourceInfo} import chisel3.experimental.dataview.{reifyIdentityView, reifySingleTarget, DataViewable} @@ -781,28 +782,12 @@ private[chisel3] trait DataImpl extends HasId with NamedComponent { self: Data = private[chisel3] def width: Width private[chisel3] def firrtlConnect(that: Data)(implicit sourceInfo: SourceInfo): Unit - /** Internal API; Chisel users should look at chisel3.chiselTypeOf(...). + /** Private implementation of cloneType * - * cloneType must be defined for any Chisel object extending Data. - * It is responsible for constructing a basic copy of the object being cloned. - * - * @return a copy of the object. - */ - def cloneType: this.type - - /** Internal API; Chisel users should look at chisel3.chiselTypeOf(...). - * - * Returns a copy of this data type, with hardware bindings (if any) removed. - * Directionality data and probe information is still preserved. + * _cloneType must be defined for any Chisel object extending Data. + * It is implemented by Chisel itself or by the compiler plugin for user-defined types. */ - private[chisel3] def cloneTypeFull: this.type = { - val clone = this.cloneType // get a fresh object, without bindings - // Only the top-level direction needs to be fixed up, cloneType should do the rest - clone.specifiedDirection = specifiedDirection - probe.setProbeModifier(clone, probeInfo) - clone.isConst = isConst - clone - } + def _cloneType: Data /** The "strong connect" operator. * @@ -994,6 +979,7 @@ private[chisel3] trait ObjectDataImpl { * * @param lhs The [[Data]] hardware on the left-hand side of the equality */ + // TODO fold this into DataExtensions implicit class DataEquality[T <: Data](lhs: T)(implicit sourceInfo: SourceInfo) { /** Dynamic recursive equality operator for generic [[Data]] @@ -1072,6 +1058,33 @@ private[chisel3] trait ObjectDataImpl { } } } + + implicit class DataExtensions[T <: Data](self: T) { + + /** Internal API; Chisel users should look at chisel3.chiselTypeOf(...). + * + * cloneType must be defined for any Chisel object extending Data. + * It is responsible for constructing a basic copy of the object being cloned. + * + * @return a copy of the object. + */ + def cloneType: T = self._cloneType.asInstanceOf[T] + + /** Internal API; Chisel users should look at chisel3.chiselTypeOf(...). + * + * Returns a copy of this data type, with hardware bindings (if any) removed. + * Directionality data and probe information is still preserved. + */ + private[chisel3] def cloneTypeFull: T = { + val clone = self.cloneType // get a fresh object, without bindings + // Only the top-level direction needs to be fixed up, cloneType should do the rest + clone.specifiedDirection = self.specifiedDirection + // TODO do we need to exclude probe and const from cloneTypeFull on Properties? + probe.setProbeModifier(clone, self.probeInfo) + clone.isConst = self.isConst + clone.asInstanceOf[T] + } + } } trait WireFactory { @@ -1243,7 +1256,8 @@ final case object DontCare extends Element with connectable.ConnectableDocs { private[chisel3] override val width: Width = UnknownWidth bind(DontCareBinding(), SpecifiedDirection.Output) - override def cloneType: this.type = DontCare + + override def _cloneType: Data = DontCare override def toString: String = "DontCare()" diff --git a/core/src/main/scala/chisel3/IO.scala b/core/src/main/scala/chisel3/IO.scala index 1814d6aa97a..201699b6744 100644 --- a/core/src/main/scala/chisel3/IO.scala +++ b/core/src/main/scala/chisel3/IO.scala @@ -1,5 +1,6 @@ package chisel3 +import chisel3.Data.DataExtensions import chisel3.internal.{throwException, Builder} import chisel3.experimental.{noPrefix, requireIsChiselType, SourceInfo} import chisel3.properties.{Class, Property} diff --git a/core/src/main/scala/chisel3/Intrinsic.scala b/core/src/main/scala/chisel3/Intrinsic.scala index 6f1d0d5e091..088faaa35e7 100644 --- a/core/src/main/scala/chisel3/Intrinsic.scala +++ b/core/src/main/scala/chisel3/Intrinsic.scala @@ -3,6 +3,7 @@ package chisel3 import chisel3._ +import chisel3.Data.DataExtensions import chisel3.experimental.{requireIsChiselType, Param, SourceInfo} import chisel3.internal.firrtl.ir._ import chisel3.internal.Builder diff --git a/core/src/main/scala/chisel3/MemImpl.scala b/core/src/main/scala/chisel3/MemImpl.scala index 5dcb5a3f8a8..89a52a30776 100644 --- a/core/src/main/scala/chisel3/MemImpl.scala +++ b/core/src/main/scala/chisel3/MemImpl.scala @@ -9,6 +9,7 @@ import chisel3.internal.binding._ import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl.ir._ import chisel3.experimental.{requireIsChiselType, requireIsHardware, SourceInfo, SourceLine} +import chisel3.Data.DataExtensions private[chisel3] trait ObjectMemImpl { diff --git a/core/src/main/scala/chisel3/ModuleImpl.scala b/core/src/main/scala/chisel3/ModuleImpl.scala index 95cd323b6c6..c9e63b20c13 100644 --- a/core/src/main/scala/chisel3/ModuleImpl.scala +++ b/core/src/main/scala/chisel3/ModuleImpl.scala @@ -28,6 +28,7 @@ import chisel3.internal.plugin.autoNameRecursively import chisel3.util.simpleClassName import chisel3.experimental.{annotate, ChiselAnnotation} import chisel3.experimental.hierarchy.Hierarchy +import chisel3.Data.DataExtensions private[chisel3] trait ObjectModuleImpl { @@ -370,7 +371,7 @@ package internal { private[chisel3] class ClonePorts(elts: (String, Data)*) extends Record { val elements: ListMap[String, Data] = ListMap(elts.map { case (name, d) => name -> d.cloneTypeFull }: _*) def apply(field: String) = elements(field) - override def cloneType = (new ClonePorts(elts: _*)).asInstanceOf[this.type] + override protected def _cloneTypeImpl: Record = (new ClonePorts(elts: _*)) } private[chisel3] def cloneIORecord( diff --git a/core/src/main/scala/chisel3/Reg.scala b/core/src/main/scala/chisel3/Reg.scala index 44958874168..06f1cf89bdc 100644 --- a/core/src/main/scala/chisel3/Reg.scala +++ b/core/src/main/scala/chisel3/Reg.scala @@ -7,6 +7,7 @@ import chisel3.internal.binding._ import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl.ir._ import chisel3.experimental.{requireIsChiselType, requireIsHardware, SourceInfo} +import chisel3.Data.DataExtensions /** Utility for constructing hardware registers * diff --git a/core/src/main/scala/chisel3/experimental/Analog.scala b/core/src/main/scala/chisel3/experimental/Analog.scala index c0136abe0ca..5988ac8ccdc 100644 --- a/core/src/main/scala/chisel3/experimental/Analog.scala +++ b/core/src/main/scala/chisel3/experimental/Analog.scala @@ -34,7 +34,7 @@ final class Analog private (private[chisel3] val width: Width) extends Element { override def litOption: Option[BigInt] = None - def cloneType: this.type = new Analog(width).asInstanceOf[this.type] + override def _cloneType: Data = new Analog(width) // Used to enforce single bulk connect of Analog types, multi-attach is still okay // Note that this really means 1 bulk connect per Module because a port can diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/core/Lookupable.scala b/core/src/main/scala/chisel3/experimental/hierarchy/core/Lookupable.scala index d5a25367788..1135ad6176a 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/core/Lookupable.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/core/Lookupable.scala @@ -12,6 +12,7 @@ import chisel3.experimental.dataview.{isView, reify, reifyIdentityView} import chisel3.internal.firrtl.ir.{Arg, ILit, Index, LitIndex, ModuleIO, Slot, ULit} import chisel3.internal.{throwException, Builder, ViewParent} import chisel3.internal.binding.{AggregateViewBinding, ChildBinding, CrossModuleBinding, ViewBinding, ViewWriteability} +import chisel3.Data.DataExtensions /** Typeclass used to recontextualize values from an original Definition to an Instance * diff --git a/core/src/main/scala/chisel3/probe/PackageImpl.scala b/core/src/main/scala/chisel3/probe/PackageImpl.scala index 6420385e9ff..fddf164681e 100644 --- a/core/src/main/scala/chisel3/probe/PackageImpl.scala +++ b/core/src/main/scala/chisel3/probe/PackageImpl.scala @@ -11,6 +11,7 @@ import chisel3.Data.ProbeInfo import chisel3.experimental.{requireIsHardware, SourceInfo} import chisel3.experimental.dataview.reifyIdentityView import chisel3.reflect.DataMirror.{checkTypeEquivalence, collectAllMembers, hasProbeTypeModifier} +import chisel3.Data.DataExtensions private[chisel3] trait ObjectProbeImpl { diff --git a/core/src/main/scala/chisel3/probe/ProbeValueBase.scala b/core/src/main/scala/chisel3/probe/ProbeValueBase.scala index f4193cfe122..46d4d36c5c7 100644 --- a/core/src/main/scala/chisel3/probe/ProbeValueBase.scala +++ b/core/src/main/scala/chisel3/probe/ProbeValueBase.scala @@ -28,6 +28,6 @@ private[chisel3] trait ProbeValueBase { } else { source.ref } clone.setRef(ProbeExpr(ref)) } - clone + clone.asInstanceOf[T] } } diff --git a/core/src/main/scala/chisel3/reflect/DataMirror.scala b/core/src/main/scala/chisel3/reflect/DataMirror.scala index 78a889c56dc..72abb033855 100644 --- a/core/src/main/scala/chisel3/reflect/DataMirror.scala +++ b/core/src/main/scala/chisel3/reflect/DataMirror.scala @@ -10,6 +10,7 @@ import chisel3.experimental.{requireIsHardware, BaseModule, SourceInfo} import chisel3.experimental.hierarchy.{Instance, ModuleClone} import chisel3.experimental.hierarchy.core.Clone import chisel3.properties.Property +import chisel3.Data.DataExtensions import scala.reflect.ClassTag object DataMirror { diff --git a/src/main/scala/chisel3/choice/ModuleChoiceImpl.scala b/src/main/scala/chisel3/choice/ModuleChoiceImpl.scala index 8eb606b0426..6bac3539017 100644 --- a/src/main/scala/chisel3/choice/ModuleChoiceImpl.scala +++ b/src/main/scala/chisel3/choice/ModuleChoiceImpl.scala @@ -5,6 +5,7 @@ package chisel3.choice import scala.collection.immutable.ListMap import chisel3.{Data, FixedIOBaseModule, Module, SourceInfoDoc} +import chisel3.Data.DataExtensions import chisel3.experimental.{BaseModule, SourceInfo} import chisel3.internal.{groupByIntoSeq, Builder} import chisel3.internal.binding.WireBinding diff --git a/src/main/scala/chisel3/util/MixedVec.scala b/src/main/scala/chisel3/util/MixedVec.scala index 5d64d89c1b7..8aabf4496b5 100644 --- a/src/main/scala/chisel3/util/MixedVec.scala +++ b/src/main/scala/chisel3/util/MixedVec.scala @@ -3,6 +3,7 @@ package chisel3.util import chisel3._ +import chisel3.Data.DataExtensions import chisel3.experimental.requireIsChiselType import scala.collection.immutable.ListMap From a5afb372a89d8d73b2ab3d031483a8a0e728301d Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Mon, 25 Nov 2024 16:47:48 -0800 Subject: [PATCH 10/30] Updates --- .../chisel3/experimental/hierarchy/core/Hierarchy.scala | 8 ++++---- core/src/main/scala/chisel3/ChiselEnumImpl.scala | 2 +- .../chisel3/experimental/hierarchy/InstantiateImpl.scala | 1 - .../experimental/hierarchy/core/HierarchyImpl.scala | 2 +- svsim/src/main/scala/Workspace.scala | 4 ++-- 5 files changed, 8 insertions(+), 9 deletions(-) rename core/src/main/{scala-2 => scala}/chisel3/experimental/hierarchy/InstantiateImpl.scala (98%) diff --git a/core/src/main/scala-2/chisel3/experimental/hierarchy/core/Hierarchy.scala b/core/src/main/scala-2/chisel3/experimental/hierarchy/core/Hierarchy.scala index 7a6512a755b..ad027fedda9 100644 --- a/core/src/main/scala-2/chisel3/experimental/hierarchy/core/Hierarchy.scala +++ b/core/src/main/scala-2/chisel3/experimental/hierarchy/core/Hierarchy.scala @@ -34,7 +34,7 @@ object Hierarchy { def toTarget: IsModule = i match { case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toTarget case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toTarget - case _ => throw new InternalErrorException("Match error: toTarget i=$i") + case _ => throw new InternalErrorException(s"Match error: toTarget i=$i") } /** Returns the toAbsoluteTarget of this hierarchy @@ -43,7 +43,7 @@ object Hierarchy { def toAbsoluteTarget: IsModule = i match { case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toAbsoluteTarget case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toAbsoluteTarget - case _ => throw new InternalErrorException("Match error: toAbsoluteTarget i=$i") + case _ => throw new InternalErrorException(s"Match error: toAbsoluteTarget i=$i") } /** Returns the toRelativeTarget of this hierarchy @@ -52,7 +52,7 @@ object Hierarchy { def toRelativeTarget(root: Option[BaseModule]): IsModule = i match { case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toRelativeTarget(root) case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toRelativeTarget(root) - case _ => throw new InternalErrorException("Match error: toAbsoluteTarget i=$i") + case _ => throw new InternalErrorException(s"Match error: toAbsoluteTarget i=$i") } /** Returns the toRelativeTarget of this hierarchy @@ -61,7 +61,7 @@ object Hierarchy { def toRelativeTargetToHierarchy(root: Option[Hierarchy[BaseModule]]): IsModule = i match { case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toRelativeTargetToHierarchy(root) case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toRelativeTargetToHierarchy(root) - case _ => throw new InternalErrorException("Match error: toAbsoluteTarget i=$i") + case _ => throw new InternalErrorException(s"Match error: toAbsoluteTarget i=$i") } } diff --git a/core/src/main/scala/chisel3/ChiselEnumImpl.scala b/core/src/main/scala/chisel3/ChiselEnumImpl.scala index 390afc47f71..4f8d3be1cc5 100644 --- a/core/src/main/scala/chisel3/ChiselEnumImpl.scala +++ b/core/src/main/scala/chisel3/ChiselEnumImpl.scala @@ -58,7 +58,7 @@ private[chisel3] abstract class EnumTypeImpl(private[chisel3] val factory: Chise // This override just ensures that if `that` has a known width, the result actually has that width // Put another way, this is preserving a case where #4159 does **not** occur // This can be deleted when Builder.useLegacyWidth is removed. - override def do_asTypeOf[T <: Data](that: T)(implicit sourceInfo: SourceInfo): T = { + override def _asTypeOfImpl[T <: Data](that: T)(implicit sourceInfo: SourceInfo): T = { that.widthOption match { // Note that default case will handle literals just fine case Some(w) => diff --git a/core/src/main/scala-2/chisel3/experimental/hierarchy/InstantiateImpl.scala b/core/src/main/scala/chisel3/experimental/hierarchy/InstantiateImpl.scala similarity index 98% rename from core/src/main/scala-2/chisel3/experimental/hierarchy/InstantiateImpl.scala rename to core/src/main/scala/chisel3/experimental/hierarchy/InstantiateImpl.scala index 67f7fb9eadb..fff3c91829e 100644 --- a/core/src/main/scala-2/chisel3/experimental/hierarchy/InstantiateImpl.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/InstantiateImpl.scala @@ -2,7 +2,6 @@ package chisel3.experimental.hierarchy -import scala.reflect.runtime.{universe => ru} import scala.collection.mutable import chisel3._ diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/core/HierarchyImpl.scala b/core/src/main/scala/chisel3/experimental/hierarchy/core/HierarchyImpl.scala index f7e09d568e4..ff1e29e9297 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/core/HierarchyImpl.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/core/HierarchyImpl.scala @@ -46,7 +46,7 @@ trait HierarchyImpl[+A] { Set.empty[String] } } - private def inBaseClasses(clz: String): Boolean = superClasses.contains(clz) + protected def inBaseClasses(clz: String): Boolean = superClasses.contains(clz) /** Used by Chisel's internal macros. DO NOT USE in your normal Chisel code!!! * Instead, mark the field you are accessing with [[public]] diff --git a/svsim/src/main/scala/Workspace.scala b/svsim/src/main/scala/Workspace.scala index 427910520aa..4b3fbe8bbcc 100644 --- a/svsim/src/main/scala/Workspace.scala +++ b/svsim/src/main/scala/Workspace.scala @@ -351,11 +351,11 @@ final class Workspace( //format: off // For this debug flow, we rebuild the simulation from scratch every time, to avoid issues if the simulation was originally compiled in a different environment, like using SiFive's `wake`. l("clean:") - l("\tls . | grep -v Makefile | grep -v execution-script.txt | xargs rm -rf") + l("\tls . | grep -v Makefile | grep -v execution-script.txt | xargs rm -rf") l() l("simulation: clean") l("\t$(compilerEnvironment) \\") - l("\t", parameters.compilerPath, " \\") + l("\t", parameters.compilerPath, " \\") for (argument <- parameters.compilerInvocation.arguments) { val sanitizedArugment = argument .replace("$", "$$") From 416cddafd27131b203e13f601e4ca1f6b7bec918 Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Wed, 27 Nov 2024 14:16:35 -0800 Subject: [PATCH 11/30] Add missing return type to unary_~ --- core/src/main/scala-3/chisel3/Bits.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala-3/chisel3/Bits.scala b/core/src/main/scala-3/chisel3/Bits.scala index 1c94b3a3b3b..773be4c7d62 100644 --- a/core/src/main/scala-3/chisel3/Bits.scala +++ b/core/src/main/scala-3/chisel3/Bits.scala @@ -305,7 +305,7 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with UIntI def abs: UInt = _absImpl - override def unary_~(implicit sourceInfo: SourceInfo) = _impl_unary_~ + override def unary_~(implicit sourceInfo: SourceInfo): UInt = _impl_unary_~ // REVIEW TODO: Can these be defined on Bits? /** Or reduction operator From 182770d3c84847bacb0053ce220a19652f1abc5f Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Wed, 27 Nov 2024 14:29:34 -0800 Subject: [PATCH 12/30] Remove do-apply pattern from Definition and Instance --- .../chisel3/experimental/hierarchy/InstantiateImpl.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/InstantiateImpl.scala b/core/src/main/scala/chisel3/experimental/hierarchy/InstantiateImpl.scala index fff3c91829e..3f9baadb21f 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/InstantiateImpl.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/InstantiateImpl.scala @@ -81,7 +81,7 @@ private[chisel3] trait InstantiateImpl { tt: Any )( implicit sourceInfo: SourceInfo - ): Instance[A] = Instance.do_apply(_definitionImpl(args, f, tt))(sourceInfo) + ): Instance[A] = Instance.apply(_definitionImpl(args, f, tt))(sourceInfo) /** This is not part of the public API, do not call directly! */ protected def _definitionImpl[K, A <: BaseModule]( @@ -95,7 +95,7 @@ private[chisel3] trait InstantiateImpl { CacheKey[A](boxAllData(args), tt, modulePrefix), { // The definition needs to have no source locator because otherwise it will be unstably // derived from the first invocation of Instantiate for the particular Module - Definition.do_apply(f(args))(UnlocatableSourceInfo) + Definition.apply(f(args))(UnlocatableSourceInfo) } ) .asInstanceOf[Definition[A]] From 3fb57790e29acc7ef2888449f11ea6c11bb500df Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Wed, 4 Dec 2024 08:28:40 -0800 Subject: [PATCH 13/30] Rebase fixes --- .../chisel3/experimental/hierarchy/InstantiateImpl.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/InstantiateImpl.scala b/core/src/main/scala/chisel3/experimental/hierarchy/InstantiateImpl.scala index 3f9baadb21f..b4aea3029a2 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/InstantiateImpl.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/InstantiateImpl.scala @@ -89,10 +89,10 @@ private[chisel3] trait InstantiateImpl { f: K => A, tt: Any ): Definition[A] = { - val modulePrefix = Builder.getModulePrefixList + val modulePrefix = Module.currentModulePrefix Builder.contextCache .getOrElseUpdate( - CacheKey[A](boxAllData(args), tt, modulePrefix), { + CacheKey[A](boxAllData(args), tt, Seq(modulePrefix).toList), { // The definition needs to have no source locator because otherwise it will be unstably // derived from the first invocation of Instantiate for the particular Module Definition.apply(f(args))(UnlocatableSourceInfo) From 65d04a1e4b827522a728548eb08da1c97939b385 Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Wed, 4 Dec 2024 08:44:26 -0800 Subject: [PATCH 14/30] Switch Scala3 sourceInfo implicits to contextual parameters --- core/src/main/scala-3/chisel3/Aggregate.scala | 40 +++--- core/src/main/scala-3/chisel3/Bits.scala | 136 +++++++++--------- .../src/main/scala-3/chisel3/ChiselEnum.scala | 12 +- core/src/main/scala-3/chisel3/Clock.scala | 2 +- core/src/main/scala-3/chisel3/Data.scala | 2 +- core/src/main/scala-3/chisel3/Disable.scala | 2 +- core/src/main/scala-3/chisel3/Mem.scala | 34 ++--- core/src/main/scala-3/chisel3/Module.scala | 2 + core/src/main/scala-3/chisel3/Mux.scala | 2 +- core/src/main/scala-3/chisel3/Printf.scala | 4 +- .../main/scala-3/chisel3/PrintfMacros.scala | 4 +- .../chisel3/VerificationStatementMacros.scala | 2 +- .../main/scala-3/chisel3/probe/Probe.scala | 6 +- .../scala-3/chisel3/probe/ProbeValue.scala | 4 +- .../main/scala-3/chisel3/probe/package.scala | 2 +- .../scala-3/chisel3/choice/ModuleChoice.scala | 2 +- src/main/scala-3/chisel3/util/BitPat.scala | 14 +- src/main/scala-3/chisel3/util/Bitwise.scala | 12 +- src/main/scala-3/chisel3/util/Cat.scala | 4 +- src/main/scala-3/chisel3/util/Reg.scala | 18 +-- 20 files changed, 153 insertions(+), 151 deletions(-) diff --git a/core/src/main/scala-3/chisel3/Aggregate.scala b/core/src/main/scala-3/chisel3/Aggregate.scala index 35a6d34b118..3583cc0f1d0 100644 --- a/core/src/main/scala-3/chisel3/Aggregate.scala +++ b/core/src/main/scala-3/chisel3/Aggregate.scala @@ -52,8 +52,8 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, length: Int) override def toString: String = super[VecImpl].toString - def apply(p: UInt)(implicit sourceInfo: SourceInfo): T = do_apply(p) - def do_apply(p: UInt)(implicit sourceInfo: SourceInfo): T = _applyImpl(p) + def apply(p: UInt)(using sourceInfo: SourceInfo): T = do_apply(p) + def do_apply(p: UInt)(using sourceInfo: SourceInfo): T = _applyImpl(p) /** A reduce operation in a tree like structure instead of sequentially * @example An adder tree @@ -76,7 +76,7 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, length: Int) redOp: (T, T) => T, layerOp: (T) => T = (x: T) => x )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): T = _reduceTreeImpl(redOp, layerOp) } @@ -93,7 +93,7 @@ object VecInit extends VecInitImpl with SourceInfoDoc { * element * @note output elements are connected from the input elements */ - def apply[T <: Data](elts: Seq[T])(implicit sourceInfo: SourceInfo): Vec[T] = _applyImpl(elts) + def apply[T <: Data](elts: Seq[T])(using sourceInfo: SourceInfo): Vec[T] = _applyImpl(elts) /** Creates a new [[Vec]] composed of the input [[Data]] nodes. * @@ -103,7 +103,7 @@ object VecInit extends VecInitImpl with SourceInfoDoc { * element * @note output elements are connected from the input elements */ - def apply[T <: Data](elt0: T, elts: T*)(implicit sourceInfo: SourceInfo): Vec[T] = _applyImpl(elt0, elts: _*) + def apply[T <: Data](elt0: T, elts: T*)(using sourceInfo: SourceInfo): Vec[T] = _applyImpl(elt0, elts: _*) /** 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. @@ -117,7 +117,7 @@ object VecInit extends VecInitImpl with SourceInfoDoc { n: Int )(gen: (Int) => T )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): Vec[T] = _tabulateImpl(n)(gen) /** Creates a new 2D [[Vec]] of length `n by m` composed of the results of the given @@ -134,7 +134,7 @@ object VecInit extends VecInitImpl with SourceInfoDoc { m: Int )(gen: (Int, Int) => T )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): Vec[Vec[T]] = _tabulateImpl(n, m)(gen) /** Creates a new 3D [[Vec]] of length `n by m by p` composed of the results of the given @@ -152,7 +152,7 @@ object VecInit extends VecInitImpl with SourceInfoDoc { p: Int )(gen: (Int, Int, Int) => T )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): Vec[Vec[Vec[T]]] = _tabulateImpl(n, m, p)(gen) /** Creates a new [[Vec]] of length `n` composed of the result of the given @@ -162,7 +162,7 @@ object VecInit extends VecInitImpl with SourceInfoDoc { * @param gen function that takes in an element T and returns an output * element of the same type */ - def fill[T <: Data](n: Int)(gen: => T)(implicit sourceInfo: SourceInfo): Vec[T] = _fillImpl(n)(gen) + def fill[T <: Data](n: Int)(gen: => T)(using sourceInfo: SourceInfo): Vec[T] = _fillImpl(n)(gen) /** Creates a new 2D [[Vec]] of length `n by m` composed of the result of the given * function applied to an element of data type T. @@ -177,7 +177,7 @@ object VecInit extends VecInitImpl with SourceInfoDoc { m: Int )(gen: => T )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): Vec[Vec[T]] = _fillImpl(n, m)(gen) /** Creates a new 3D [[Vec]] of length `n by m by p` composed of the result of the given @@ -195,7 +195,7 @@ object VecInit extends VecInitImpl with SourceInfoDoc { p: Int )(gen: => T )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): Vec[Vec[Vec[T]]] = _fillImpl(n, m, p)(gen) /** Creates a new [[Vec]] of length `n` composed of the result of the given @@ -211,7 +211,7 @@ object VecInit extends VecInitImpl with SourceInfoDoc { len: Int )(f: (T) => T )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): Vec[T] = _iterateImpl(start, len)(f) } @@ -222,32 +222,32 @@ trait VecLike[T <: Data] extends VecLikeImpl[T] with SourceInfoDoc { /** Creates a dynamically indexed read or write accessor into the array. */ - def apply(p: UInt)(implicit sourceInfo: SourceInfo): T + def apply(p: UInt)(using sourceInfo: SourceInfo): T /** Outputs true if p outputs true for every element. */ - def forall(p: T => Bool)(implicit sourceInfo: SourceInfo): Bool = _forallImpl(p) + def forall(p: T => Bool)(using sourceInfo: SourceInfo): Bool = _forallImpl(p) /** Outputs true if p outputs true for at least one element. */ - def exists(p: T => Bool)(implicit sourceInfo: SourceInfo): Bool = _existsImpl(p) + def exists(p: T => Bool)(using sourceInfo: SourceInfo): Bool = _existsImpl(p) /** Outputs true if the vector contains at least one element equal to x (using * the === operator). */ - def contains(x: T)(implicit sourceInfo: SourceInfo, ev: T <:< UInt): Bool = _containsImpl(x) + def contains(x: T)(using sourceInfo: SourceInfo, ev: T <:< UInt): Bool = _containsImpl(x) /** Outputs the number of elements for which p is true. */ - def count(p: T => Bool)(implicit sourceInfo: SourceInfo): UInt = _countImpl(p) + def count(p: T => Bool)(using sourceInfo: SourceInfo): UInt = _countImpl(p) /** Outputs the index of the first element for which p outputs true. */ - def indexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo): UInt = _indexWhereImpl(p) + def indexWhere(p: T => Bool)(using sourceInfo: SourceInfo): UInt = _indexWhereImpl(p) /** Outputs the index of the last element for which p outputs true. */ - def lastIndexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo): UInt = _lastIndexWhereImpl(p) + def lastIndexWhere(p: T => Bool)(using sourceInfo: SourceInfo): UInt = _lastIndexWhereImpl(p) /** Outputs the index of the element for which p outputs true, assuming that * the there is exactly one such element. @@ -259,7 +259,7 @@ trait VecLike[T <: Data] extends VecLikeImpl[T] with SourceInfoDoc { * 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)(implicit sourceInfo: SourceInfo): UInt = _onlyIndexWhereImpl(p) + def onlyIndexWhere(p: T => Bool)(using sourceInfo: SourceInfo): UInt = _onlyIndexWhereImpl(p) } /** Base class for Aggregates based on key values pairs of String and Data diff --git a/core/src/main/scala-3/chisel3/Bits.scala b/core/src/main/scala-3/chisel3/Bits.scala index 773be4c7d62..f197bce4356 100644 --- a/core/src/main/scala-3/chisel3/Bits.scala +++ b/core/src/main/scala-3/chisel3/Bits.scala @@ -32,7 +32,7 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends BitsImpl w * @return This $coll with the `n` most significant bits removed. * @group Bitwise */ - def tail(n: Int)(implicit sourceInfo: SourceInfo): UInt = _tailImpl(n) + def tail(n: Int)(using sourceInfo: SourceInfo): UInt = _tailImpl(n) /** Head operator * @@ -40,7 +40,7 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends BitsImpl w * @return The `n` most significant bits of this $coll * @group Bitwise */ - def head(n: Int)(implicit sourceInfo: SourceInfo): UInt = _headImpl(n) + def head(n: Int)(using sourceInfo: SourceInfo): UInt = _headImpl(n) /** Returns the specified bit on this $coll as a [[Bool]], statically addressed. * @@ -48,31 +48,31 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends BitsImpl w * @return the specified bit */ - final def extract(x: BigInt)(implicit sourceInfo: SourceInfo): Bool = _extractImpl(x) + final def extract(x: BigInt)(using sourceInfo: SourceInfo): Bool = _extractImpl(x) /** Returns the specified bit on this $coll as a [[Bool]], statically addressed. * * @param x an index * @return the specified bit */ - final def apply(x: Int)(implicit sourceInfo: SourceInfo): Bool = _applyImpl(x) + final def apply(x: Int)(using sourceInfo: SourceInfo): Bool = _applyImpl(x) /** Grab the bottom n bits. Return 0.U(0.W) if n==0. */ - final def take(n: Int)(implicit sourceInfo: SourceInfo): UInt = _takeImpl(n) + final def take(n: Int)(using sourceInfo: SourceInfo): UInt = _takeImpl(n) /** 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 extract(x: UInt)(implicit sourceInfo: SourceInfo): Bool = _extractImpl(x) + final def extract(x: UInt)(using sourceInfo: SourceInfo): Bool = _extractImpl(x) /** 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)(implicit sourceInfo: SourceInfo): Bool = _applyImpl(x) + final def apply(x: UInt)(using sourceInfo: SourceInfo): Bool = _applyImpl(x) /** Returns a subset of bits on this $coll from `hi` to `lo` (inclusive), statically addressed. * @@ -85,7 +85,7 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends BitsImpl w * @param y the low bit * @return a hardware component contain the requested bits */ - final def apply(x: Int, y: Int)(implicit sourceInfo: SourceInfo): UInt = _applyImpl(x, y) + final def apply(x: Int, y: Int)(using sourceInfo: SourceInfo): UInt = _applyImpl(x, y) // 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. @@ -99,7 +99,7 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends BitsImpl w * @param y the low bit * @return a hardware component contain the requested bits */ - final def apply(x: BigInt, y: BigInt)(implicit sourceInfo: SourceInfo): UInt = _applyImpl(x, y) + final def apply(x: BigInt, y: BigInt)(using sourceInfo: SourceInfo): UInt = _applyImpl(x, y) /** Pad operator * @@ -109,14 +109,14 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends BitsImpl w * @note For [[SInt]]s only, this will do sign extension. * @group Bitwise */ - def pad(that: Int)(implicit sourceInfo: SourceInfo): Bits = _padImpl(that) + def pad(that: Int)(using sourceInfo: SourceInfo): Bits = _padImpl(that) /** Bitwise inversion operator * * @return this $coll with each bit inverted * @group Bitwise */ - def unary_~(implicit sourceInfo: SourceInfo): Bits = _impl_unary_~ + def unary_~(using sourceInfo: SourceInfo): Bits = _impl_unary_~ /** Static left shift operator * @@ -125,7 +125,7 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends BitsImpl w * $sumWidthInt * @group Bitwise */ - def <<(that: BigInt)(implicit sourceInfo: SourceInfo): Bits = _impl_<<(that) + def <<(that: BigInt)(using sourceInfo: SourceInfo): Bits = _impl_<<(that) /** Static left shift operator * @@ -134,7 +134,7 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends BitsImpl w * $sumWidthInt * @group Bitwise */ - def <<(that: Int)(implicit sourceInfo: SourceInfo): Bits = _impl_<<(that) + def <<(that: Int)(using sourceInfo: SourceInfo): Bits = _impl_<<(that) /** Dynamic left shift operator * @@ -143,7 +143,7 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends BitsImpl w * @note The width of the returned $coll is `width of this + pow(2, width of that) - 1`. * @group Bitwise */ - def <<(that: UInt)(implicit sourceInfo: SourceInfo): Bits = _impl_<<(that) + def <<(that: UInt)(using sourceInfo: SourceInfo): Bits = _impl_<<(that) /** Static right shift operator * @@ -152,7 +152,7 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends BitsImpl w * $unchangedWidth * @group Bitwise */ - def >>(that: BigInt)(implicit sourceInfo: SourceInfo): Bits = _impl_>>(that) + def >>(that: BigInt)(using sourceInfo: SourceInfo): Bits = _impl_>>(that) /** Static right shift operator * @@ -161,7 +161,7 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends BitsImpl w * $unchangedWidth * @group Bitwise */ - def >>(that: Int)(implicit sourceInfo: SourceInfo): Bits = _impl_>>(that) + def >>(that: Int)(using sourceInfo: SourceInfo): Bits = _impl_>>(that) /** Dynamic right shift operator * @@ -171,17 +171,17 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends BitsImpl w * $unchangedWidth * @group Bitwise */ - def >>(that: UInt)(implicit sourceInfo: SourceInfo): Bits = _impl_>>(that) + def >>(that: UInt)(using sourceInfo: SourceInfo): Bits = _impl_>>(that) /** Returns the contents of this wire as a [[scala.collection.Seq]] of [[Bool]]. */ - def asBools(implicit sourceInfo: SourceInfo): Seq[Bool] = _asBoolsImpl + def asBools(using sourceInfo: SourceInfo): Seq[Bool] = _asBoolsImpl /** Reinterpret this $coll as an [[SInt]] * * @note The arithmetic value is not preserved if the most-significant bit is set. For example, a [[UInt]] of * width 3 and value 7 (0b111) would become an [[SInt]] of width 3 and value -1. */ - def asSInt(implicit sourceInfo: SourceInfo): SInt = _asSIntImpl + def asSInt(using sourceInfo: SourceInfo): SInt = _asSIntImpl def asBool: Bool = _asBoolImpl @@ -192,7 +192,7 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends BitsImpl w * $sumWidth * @group Bitwise */ - def ##(that: Bits)(implicit sourceInfo: SourceInfo): UInt = _impl_##(that) + def ##(that: Bits)(using sourceInfo: SourceInfo): UInt = _impl_##(that) } object Bits extends UIntFactory @@ -214,7 +214,7 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with UIntI * $constantWidth * @group Arithmetic */ - def unary_-(implicit sourceInfo: SourceInfo): UInt = _impl_unary_- + def unary_-(using sourceInfo: SourceInfo): UInt = _impl_unary_- /** Unary negation (constant width) * @@ -222,7 +222,7 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with UIntI * $constantWidth * @group Arithmetic */ - def unary_-%(implicit sourceInfo: SourceInfo): UInt = _impl_unary_-% + def unary_-%(using sourceInfo: SourceInfo): UInt = _impl_unary_-% override def +(that: UInt): UInt = _impl_+(that) override def -(that: UInt): UInt = _impl_-(that) @@ -305,7 +305,7 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with UIntI def abs: UInt = _absImpl - override def unary_~(implicit sourceInfo: SourceInfo): UInt = _impl_unary_~ + override def unary_~(using sourceInfo: SourceInfo): UInt = _impl_unary_~ // REVIEW TODO: Can these be defined on Bits? /** Or reduction operator @@ -327,7 +327,7 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with UIntI * @return a hardware [[Bool]] resulting from every bit of this $coll xor'd together * @group Bitwise */ - final def xorR(implicit sourceInfo: SourceInfo): Bool = _xorRImpl + final def xorR(using sourceInfo: SourceInfo): Bool = _xorRImpl override def <(that: UInt): Bool = _impl_<(that) override def >(that: UInt): Bool = _impl_>(that) @@ -340,7 +340,7 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with UIntI * @return a hardware [[Bool]] asserted if this $coll is not equal to `that` * @group Comparison */ - def =/=(that: UInt)(implicit sourceInfo: SourceInfo): Bool = _impl_=/=(that) + def =/=(that: UInt)(using sourceInfo: SourceInfo): Bool = _impl_=/=(that) /** Dynamic equals operator * @@ -348,40 +348,40 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with UIntI * @return a hardware [[Bool]] asserted if this $coll is equal to `that` * @group Comparison */ - def ===(that: UInt)(implicit sourceInfo: SourceInfo): Bool = _impl_===(that) + def ===(that: UInt)(using sourceInfo: SourceInfo): Bool = _impl_===(that) /** Unary not * * @return a hardware [[Bool]] asserted if this $coll equals zero * @group Bitwise */ - def unary_!(implicit sourceInfo: SourceInfo): Bool = _impl_unary_! + def unary_!(using sourceInfo: SourceInfo): Bool = _impl_unary_! - override def <<(that: Int)(implicit sourceInfo: SourceInfo): UInt = _impl_<<(that) - override def <<(that: BigInt)(implicit sourceInfo: SourceInfo): UInt = _impl_<<(that) - override def <<(that: UInt)(implicit sourceInfo: SourceInfo): UInt = _impl_<<(that) + override def <<(that: Int)(using sourceInfo: SourceInfo): UInt = _impl_<<(that) + override def <<(that: BigInt)(using sourceInfo: SourceInfo): UInt = _impl_<<(that) + override def <<(that: UInt)(using sourceInfo: SourceInfo): UInt = _impl_<<(that) - override def >>(that: Int)(implicit sourceInfo: SourceInfo): UInt = _impl_>>(that) - override def >>(that: BigInt)(implicit sourceInfo: SourceInfo): UInt = _impl_>>(that) - override def >>(that: UInt)(implicit sourceInfo: SourceInfo): UInt = _impl_>>(that) + override def >>(that: Int)(using sourceInfo: SourceInfo): UInt = _impl_>>(that) + override def >>(that: BigInt)(using sourceInfo: SourceInfo): UInt = _impl_>>(that) + override def >>(that: UInt)(using sourceInfo: SourceInfo): UInt = _impl_>>(that) /** * Circular shift to the left * @param that number of bits to rotate * @return UInt of same width rotated left n bits */ - def rotateLeft(n: Int)(implicit sourceInfo: SourceInfo): UInt = _rotateLeftImpl(n) + def rotateLeft(n: Int)(using sourceInfo: SourceInfo): UInt = _rotateLeftImpl(n) - def rotateLeft(n: UInt)(implicit sourceInfo: SourceInfo): UInt = _rotateLeftImpl(n) + def rotateLeft(n: UInt)(using sourceInfo: SourceInfo): UInt = _rotateLeftImpl(n) /** * Circular shift to the right * @param that number of bits to rotate * @return UInt of same width rotated right n bits */ - def rotateRight(n: Int)(implicit sourceInfo: SourceInfo): UInt = _rotateRightImpl(n) + def rotateRight(n: Int)(using sourceInfo: SourceInfo): UInt = _rotateRightImpl(n) - def rotateRight(n: UInt)(implicit sourceInfo: SourceInfo): UInt = _rotateRightImpl(n) + def rotateRight(n: UInt)(using sourceInfo: SourceInfo): UInt = _rotateRightImpl(n) /** Conditionally set or clear a bit * @@ -390,7 +390,7 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with UIntI * @return a hrdware $coll with bit `off` set or cleared based on the value of `dat` * $unchangedWidth */ - def bitSet(off: UInt, dat: Bool)(implicit sourceInfo: SourceInfo): UInt = _bitSetImpl(off, dat) + def bitSet(off: UInt, dat: Bool)(using sourceInfo: SourceInfo): UInt = _bitSetImpl(off, dat) // TODO: this eventually will be renamed as toSInt, once the existing toSInt // completes its deprecation phase. @@ -399,9 +399,9 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with UIntI * @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`. */ - def zext(implicit sourceInfo: SourceInfo): SInt = _zextImpl + def zext(using sourceInfo: SourceInfo): SInt = _zextImpl - override def asSInt(implicit sourceInfo: SourceInfo): SInt = _asSIntImpl + override def asSInt(using sourceInfo: SourceInfo): SInt = _asSIntImpl } object UInt extends UIntFactory @@ -414,7 +414,7 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with SIntI * $constantWidth * @group Arithmetic */ - final def unary_-(implicit sourceInfo: SourceInfo): SInt = _impl_unary_- + final def unary_-(using sourceInfo: SourceInfo): SInt = _impl_unary_- /** Unary negation (constant width) * @@ -422,7 +422,7 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with SIntI * $constantWidth * @group Arithmetic */ - def unary_-%(implicit sourceInfo: SourceInfo): SInt = _impl_unary_-% + def unary_-%(using sourceInfo: SourceInfo): SInt = _impl_unary_-% /** add (default - no growth) operator */ override def +(that: SInt): SInt = _impl_+(that) @@ -441,7 +441,7 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with SIntI * $singleCycleMul * @group Arithmetic */ - def *(that: UInt)(implicit sourceInfo: SourceInfo): SInt = _impl_*(that) + def *(that: UInt)(using sourceInfo: SourceInfo): SInt = _impl_*(that) /** Addition operator (expanding width) * @@ -450,7 +450,7 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with SIntI * $maxWidthPlusOne * @group Arithmetic */ - def +&(that: SInt)(implicit sourceInfo: SourceInfo): SInt = _impl_+&(that) + def +&(that: SInt)(using sourceInfo: SourceInfo): SInt = _impl_+&(that) /** Addition operator (constant width) * @@ -459,7 +459,7 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with SIntI * $maxWidth * @group Arithmetic */ - def +%(that: SInt)(implicit sourceInfo: SourceInfo): SInt = _impl_+%(that) + def +%(that: SInt)(using sourceInfo: SourceInfo): SInt = _impl_+%(that) /** Subtraction operator (increasing width) * @@ -468,7 +468,7 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with SIntI * $maxWidthPlusOne * @group Arithmetic */ - def -&(that: SInt)(implicit sourceInfo: SourceInfo): SInt = _impl_-&(that) + def -&(that: SInt)(using sourceInfo: SourceInfo): SInt = _impl_-&(that) /** Subtraction operator (constant width) * @@ -477,7 +477,7 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with SIntI * $maxWidth * @group Arithmetic */ - def -%(that: SInt)(implicit sourceInfo: SourceInfo): SInt = _impl_-%(that) + def -%(that: SInt)(using sourceInfo: SourceInfo): SInt = _impl_-%(that) /** Bitwise and operator * @@ -486,7 +486,7 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with SIntI * $maxWidth * @group Bitwise */ - def &(that: SInt)(implicit sourceInfo: SourceInfo): SInt = _impl_&(that) + def &(that: SInt)(using sourceInfo: SourceInfo): SInt = _impl_&(that) /** Bitwise or operator * @@ -504,9 +504,9 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with SIntI * $maxWidth * @group Bitwise */ - def ^(that: SInt)(implicit sourceInfo: SourceInfo): SInt = _impl_^(that) + def ^(that: SInt)(using sourceInfo: SourceInfo): SInt = _impl_^(that) - override def unary_~(implicit sourceInfo: SourceInfo): SInt = _impl_unary_~ + override def unary_~(using sourceInfo: SourceInfo): SInt = _impl_unary_~ override def <(that: SInt): Bool = _impl_<(that) override def >(that: SInt): Bool = _impl_>(that) @@ -531,22 +531,22 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with SIntI def abs: SInt = _absImpl - override def <<(that: Int)(implicit sourceInfo: SourceInfo): SInt = _impl_<<(that) - override def <<(that: BigInt)(implicit sourceInfo: SourceInfo): SInt = _impl_<<(that) - override def <<(that: UInt)(implicit sourceInfo: SourceInfo): SInt = _impl_<<(that) + override def <<(that: Int)(using sourceInfo: SourceInfo): SInt = _impl_<<(that) + override def <<(that: BigInt)(using sourceInfo: SourceInfo): SInt = _impl_<<(that) + override def <<(that: UInt)(using sourceInfo: SourceInfo): SInt = _impl_<<(that) - override def >>(that: Int)(implicit sourceInfo: SourceInfo): SInt = _impl_>>(that) - override def >>(that: BigInt)(implicit sourceInfo: SourceInfo): SInt = _impl_>>(that) - override def >>(that: UInt)(implicit sourceInfo: SourceInfo): SInt = _impl_>>(that) + override def >>(that: Int)(using sourceInfo: SourceInfo): SInt = _impl_>>(that) + override def >>(that: BigInt)(using sourceInfo: SourceInfo): SInt = _impl_>>(that) + override def >>(that: UInt)(using sourceInfo: SourceInfo): SInt = _impl_>>(that) - override def asSInt(implicit sourceInfo: SourceInfo): SInt = _asSIntImpl + override def asSInt(using sourceInfo: SourceInfo): SInt = _asSIntImpl } object SInt extends SIntFactory sealed trait Reset extends ResetImpl with ToBoolable { - def asAsyncReset(implicit sourceInfo: SourceInfo): AsyncReset - def asDisable(implicit sourceInfo: SourceInfo): Disable = _asDisableImpl + def asAsyncReset(using sourceInfo: SourceInfo): AsyncReset + def asDisable(using sourceInfo: SourceInfo): Disable = _asDisableImpl } object Reset { @@ -559,7 +559,7 @@ object Reset { * super type due to Bool inheriting from abstract class UInt */ final class ResetType(private[chisel3] val width: Width = Width(1)) extends Reset with ResetTypeImpl with ToBoolable { - def asAsyncReset(implicit sourceInfo: SourceInfo): AsyncReset = _asAsyncResetImpl + def asAsyncReset(using sourceInfo: SourceInfo): AsyncReset = _asAsyncResetImpl def asBool: Bool = _asBoolImpl def toBool: Bool = asBool } @@ -576,7 +576,7 @@ object AsyncReset { */ sealed class AsyncReset(private[chisel3] val width: Width = Width(1)) extends AsyncResetImpl with Reset { override def toString: String = stringAccessor("AsyncReset") - def asAsyncReset(implicit sourceInfo: SourceInfo): AsyncReset = _asAsyncResetImpl + def asAsyncReset(using sourceInfo: SourceInfo): AsyncReset = _asAsyncResetImpl def asBool: Bool = _asBoolImpl def toBool: Bool = _asBoolImpl } @@ -599,7 +599,7 @@ sealed class Bool() extends UInt(1.W) with BoolImpl with Reset { * @return the bitwise and of this $coll and `that` * @group Bitwise */ - def &(that: Bool)(implicit sourceInfo: SourceInfo): Bool = _impl_&(that) + def &(that: Bool)(using sourceInfo: SourceInfo): Bool = _impl_&(that) /** Bitwise or operator * @@ -615,9 +615,9 @@ sealed class Bool() extends UInt(1.W) with BoolImpl with Reset { * @return the bitwise xor of this $coll and `that` * @group Bitwise */ - def ^(that: Bool)(implicit sourceInfo: SourceInfo): Bool = _impl_^(that) + def ^(that: Bool)(using sourceInfo: SourceInfo): Bool = _impl_^(that) - override def unary_~(implicit sourceInfo: SourceInfo): Bool = _impl_unary_~ + override def unary_~(using sourceInfo: SourceInfo): Bool = _impl_unary_~ /** Logical or operator * @@ -626,7 +626,7 @@ sealed class Bool() extends UInt(1.W) with BoolImpl with Reset { * @note this is equivalent to [[Bool!.|(that:chisel3\.Bool)* Bool.|)]] * @group Logical */ - def ||(that: Bool)(implicit sourceInfo: SourceInfo): Bool = _impl_||(that) + def ||(that: Bool)(using sourceInfo: SourceInfo): Bool = _impl_||(that) /** Logical and operator * @@ -635,14 +635,14 @@ sealed class Bool() extends UInt(1.W) with BoolImpl with Reset { * @note this is equivalent to [[Bool!.&(that:chisel3\.Bool)* Bool.&]] * @group Logical */ - def &&(that: Bool)(implicit sourceInfo: SourceInfo): Bool = _impl_&&(that) + def &&(that: Bool)(using sourceInfo: SourceInfo): Bool = _impl_&&(that) override def asBool: Bool = _asBoolImpl /** Reinterprets this $coll as a clock */ - def asClock(implicit sourceInfo: SourceInfo): Clock = _asClockImpl + def asClock(using sourceInfo: SourceInfo): Clock = _asClockImpl - def asAsyncReset(implicit sourceInfo: SourceInfo): AsyncReset = _asAsyncResetImpl + def asAsyncReset(using sourceInfo: SourceInfo): AsyncReset = _asAsyncResetImpl } object Bool extends BoolFactory diff --git a/core/src/main/scala-3/chisel3/ChiselEnum.scala b/core/src/main/scala-3/chisel3/ChiselEnum.scala index d8032af1e41..5535de71de9 100644 --- a/core/src/main/scala-3/chisel3/ChiselEnum.scala +++ b/core/src/main/scala-3/chisel3/ChiselEnum.scala @@ -7,12 +7,12 @@ import chisel3.experimental.SourceInfo abstract class EnumType(factory: ChiselEnum, selfAnnotating: Boolean = true) extends EnumTypeImpl(factory, selfAnnotating) { - final def ===(that: EnumType)(implicit sourceInfo: SourceInfo): Bool = _impl_===(that) - final def =/=(that: EnumType)(implicit sourceInfo: SourceInfo): Bool = _impl_=/=(that) - final def <(that: EnumType)(implicit sourceInfo: SourceInfo): Bool = _impl_<(that) - final def <=(that: EnumType)(implicit sourceInfo: SourceInfo): Bool = _impl_>(that) - final def >(that: EnumType)(implicit sourceInfo: SourceInfo): Bool = _impl_<=(that) - final def >=(that: EnumType)(implicit sourceInfo: SourceInfo): Bool = _impl_>=(that) + final def ===(that: EnumType)(using sourceInfo: SourceInfo): Bool = _impl_===(that) + final def =/=(that: EnumType)(using sourceInfo: SourceInfo): Bool = _impl_=/=(that) + final def <(that: EnumType)(using sourceInfo: SourceInfo): Bool = _impl_<(that) + final def <=(that: EnumType)(using sourceInfo: SourceInfo): Bool = _impl_>(that) + final def >(that: EnumType)(using sourceInfo: SourceInfo): Bool = _impl_<=(that) + final def >=(that: EnumType)(using sourceInfo: SourceInfo): Bool = _impl_>=(that) } abstract class ChiselEnum extends ChiselEnumImpl diff --git a/core/src/main/scala-3/chisel3/Clock.scala b/core/src/main/scala-3/chisel3/Clock.scala index 05785b7c483..a8aa42f446d 100644 --- a/core/src/main/scala-3/chisel3/Clock.scala +++ b/core/src/main/scala-3/chisel3/Clock.scala @@ -12,5 +12,5 @@ object Clock { sealed class Clock extends ClockImpl { /** Returns the contents of the clock wire as a [[Bool]]. */ - def asBool(implicit sourceInfo: SourceInfo): Bool = _asBoolImpl + def asBool(using sourceInfo: SourceInfo): Bool = _asBoolImpl } diff --git a/core/src/main/scala-3/chisel3/Data.scala b/core/src/main/scala-3/chisel3/Data.scala index 101797d55c3..268aad8316e 100644 --- a/core/src/main/scala-3/chisel3/Data.scala +++ b/core/src/main/scala-3/chisel3/Data.scala @@ -22,7 +22,7 @@ abstract class Data extends DataImpl with SourceInfoDoc { * @note bit widths are NOT checked, may pad or drop bits from input * @note that should have known widths */ - def asTypeOf[T <: Data](that: T)(implicit sourceInfo: SourceInfo): T = _asTypeOfImpl(that) + def asTypeOf[T <: Data](that: T)(using sourceInfo: SourceInfo): T = _asTypeOfImpl(that) /** Reinterpret cast to UInt. * diff --git a/core/src/main/scala-3/chisel3/Disable.scala b/core/src/main/scala-3/chisel3/Disable.scala index fd67bb146c7..411638b6962 100644 --- a/core/src/main/scala-3/chisel3/Disable.scala +++ b/core/src/main/scala-3/chisel3/Disable.scala @@ -23,7 +23,7 @@ class Disable private[chisel3] (private[chisel3] val value: Bool) extends Disabl * @return invert the logical value of this `Disable` * @group Bitwise */ - def unary_!(implicit sourceInfo: SourceInfo): Disable = new Disable(!this.value) + def unary_!(using sourceInfo: SourceInfo): Disable = new Disable(!this.value) } object Disable extends ObectDisableImpl diff --git a/core/src/main/scala-3/chisel3/Mem.scala b/core/src/main/scala-3/chisel3/Mem.scala index b71cb108279..fb76fa19332 100644 --- a/core/src/main/scala-3/chisel3/Mem.scala +++ b/core/src/main/scala-3/chisel3/Mem.scala @@ -15,7 +15,7 @@ object Mem extends ObjectMemImpl with SourceInfoDoc { size: BigInt, t: T )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): Mem[T] = _applyImpl(size, t) /** Creates a combinational/asynchronous-read, sequential/synchronous-write [[Mem]]. @@ -23,7 +23,7 @@ object Mem extends ObjectMemImpl with SourceInfoDoc { * @param size number of elements in the memory * @param t data type of memory element */ - def apply[T <: Data](size: Int, t: T)(implicit sourceInfo: SourceInfo): Mem[T] = _applyImpl(size, t) + def apply[T <: Data](size: Int, t: T)(using sourceInfo: SourceInfo): Mem[T] = _applyImpl(size, t) } sealed abstract class MemBase[T <: Data](val t: T, val length: BigInt, protected val sourceInfo: SourceInfo) @@ -35,38 +35,38 @@ sealed abstract class MemBase[T <: Data](val t: T, val length: BigInt, protected /** Creates a read accessor into the memory with static addressing. See the * class documentation of the memory for more detailed information. */ - def apply(idx: BigInt)(implicit sourceInfo: SourceInfo): T = _applyImpl(idx) + def apply(idx: BigInt)(using sourceInfo: SourceInfo): T = _applyImpl(idx) /** 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)(implicit sourceInfo: SourceInfo): T = _applyImpl(idx) + def apply(idx: Int)(using sourceInfo: SourceInfo): T = _applyImpl(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)(implicit sourceInfo: SourceInfo): T = _applyImpl(idx) + def apply(idx: UInt)(using sourceInfo: SourceInfo): T = _applyImpl(idx) - def apply(idx: UInt, clock: Clock)(implicit sourceInfo: SourceInfo): T = _applyImpl(idx, clock) + def apply(idx: UInt, clock: Clock)(using sourceInfo: SourceInfo): T = _applyImpl(idx, clock) /** 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)(implicit sourceInfo: SourceInfo): T = _readImpl(idx) + def read(idx: UInt)(using sourceInfo: SourceInfo): T = _readImpl(idx) /** Creates a read accessor into the memory with dynamic addressing. * Takes a clock parameter to bind a clock that may be different * from the implicit clock. See the class documentation of the memory * for more detailed information. */ - def read(idx: UInt, clock: Clock)(implicit sourceInfo: SourceInfo): T = _readImpl(idx, clock) + def read(idx: UInt, clock: Clock)(using sourceInfo: SourceInfo): T = _readImpl(idx, clock) /** 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)(implicit sourceInfo: SourceInfo): Unit = _writeImpl(idx, data) + def write(idx: UInt, data: T)(using sourceInfo: SourceInfo): Unit = _writeImpl(idx, data) /** Creates a write accessor into the memory with a clock * that may be different from the implicit clock. @@ -75,7 +75,7 @@ sealed abstract class MemBase[T <: Data](val t: T, val length: BigInt, protected * @param data new data to write * @param clock clock to bind to this accessor */ - def write(idx: UInt, data: T, clock: Clock)(implicit sourceInfo: SourceInfo): Unit = _writeImpl(idx, data, clock) + def write(idx: UInt, data: T, clock: Clock)(using sourceInfo: SourceInfo): Unit = _writeImpl(idx, data, clock) /** Creates a masked write accessor into the memory. * @@ -141,7 +141,7 @@ object SyncReadMem extends ObjectSyncReadMemImpl { size: Int, t: T )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): SyncReadMem[T] = _applyImpl(size, t) def apply[T <: Data]( @@ -149,7 +149,7 @@ object SyncReadMem extends ObjectSyncReadMemImpl { t: T, ruw: ReadUnderWrite = Undefined )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): SyncReadMem[T] = _applyImpl(size, t, ruw) } @@ -171,11 +171,11 @@ sealed class SyncReadMem[T <: Data] private[chisel3] ( extends MemBase[T](t, n, sourceInfo) with SyncReadMemImpl[T] { - override def read(idx: UInt)(implicit sourceInfo: SourceInfo): T = _readImpl(idx) + override def read(idx: UInt)(using sourceInfo: SourceInfo): T = _readImpl(idx) - def read(idx: UInt, en: Bool)(implicit sourceInfo: SourceInfo): T = _readImpl(idx, en) + def read(idx: UInt, en: Bool)(using sourceInfo: SourceInfo): T = _readImpl(idx, en) - def read(idx: UInt, en: Bool, clock: Clock)(implicit sourceInfo: SourceInfo): T = _readImpl(idx, en, clock) + def read(idx: UInt, en: Bool, clock: Clock)(using sourceInfo: SourceInfo): T = _readImpl(idx, en, clock) /** Generates an explicit read-write port for this SyncReadMem. Note that this does not infer * port directionality based on connection semantics and the `when` context unlike SyncReadMem.apply(), @@ -209,7 +209,7 @@ sealed class SyncReadMem[T <: Data] private[chisel3] ( * * }}} */ - def readWrite(idx: UInt, writeData: T, en: Bool, isWrite: Bool)(implicit sourceInfo: SourceInfo): T = + def readWrite(idx: UInt, writeData: T, en: Bool, isWrite: Bool)(using sourceInfo: SourceInfo): T = _readWriteImpl(idx, writeData, en, isWrite) /** Generates an explicit read-write port for this SyncReadMem, using a clock that may be @@ -232,7 +232,7 @@ sealed class SyncReadMem[T <: Data] private[chisel3] ( isWrite: Bool, clock: Clock )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): T = _readWriteImpl(idx, data, en, isWrite, clock) /** Generates an explicit read-write port for this SyncReadMem, with a bytemask for diff --git a/core/src/main/scala-3/chisel3/Module.scala b/core/src/main/scala-3/chisel3/Module.scala index b424f678374..7bc01adf34a 100644 --- a/core/src/main/scala-3/chisel3/Module.scala +++ b/core/src/main/scala-3/chisel3/Module.scala @@ -13,6 +13,8 @@ object Module extends ObjectModuleImpl with SourceInfoDoc { * * @return the input module `m` with Chisel metadata properly set */ + // TODO(adkian-sifive) the callsite here explicitly passes + // sourceInfo so it cannot be a contextual parameter def apply[T <: BaseModule](bc: => T): T = _applyImpl(bc) def do_apply[T <: BaseModule](bc: => T)(implicit sourceInfo: SourceInfo): T = apply(bc) } diff --git a/core/src/main/scala-3/chisel3/Mux.scala b/core/src/main/scala-3/chisel3/Mux.scala index da5ac2985ac..b61e4e3a712 100644 --- a/core/src/main/scala-3/chisel3/Mux.scala +++ b/core/src/main/scala-3/chisel3/Mux.scala @@ -22,6 +22,6 @@ object Mux extends MuxImpl with SourceInfoDoc { con: T, alt: T )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): T = _applyImpl(cond, con, alt) } diff --git a/core/src/main/scala-3/chisel3/Printf.scala b/core/src/main/scala-3/chisel3/Printf.scala index 3bea14c34eb..213a460645f 100644 --- a/core/src/main/scala-3/chisel3/Printf.scala +++ b/core/src/main/scala-3/chisel3/Printf.scala @@ -54,6 +54,6 @@ object printf { * @see [[Printable]] documentation * @param pable [[Printable]] to print */ - def apply(pable: Printable)(implicit sourceInfo: SourceInfo): chisel3.printf.Printf = - PrintfMacrosCompat.printfWithReset(pable)(sourceInfo) + def apply(pable: Printable)(using sourceInfo: SourceInfo): chisel3.printf.Printf = + PrintfMacrosCompat.printfWithReset(pable)(using sourceInfo) } diff --git a/core/src/main/scala-3/chisel3/PrintfMacros.scala b/core/src/main/scala-3/chisel3/PrintfMacros.scala index ac997b9a9f0..08ac54d3cdc 100644 --- a/core/src/main/scala-3/chisel3/PrintfMacros.scala +++ b/core/src/main/scala-3/chisel3/PrintfMacros.scala @@ -10,7 +10,7 @@ object PrintfMacrosCompat { private[chisel3] def printfWithReset( pable: Printable )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): chisel3.printf.Printf = { var printfId: chisel3.printf.Printf = null when(!Module.reset.asBool) { @@ -22,7 +22,7 @@ object PrintfMacrosCompat { private[chisel3] def printfWithoutReset( pable: Printable )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): chisel3.printf.Printf = { val clock = Builder.forcedClock val printfId = new chisel3.printf.Printf(pable) diff --git a/core/src/main/scala-3/chisel3/VerificationStatementMacros.scala b/core/src/main/scala-3/chisel3/VerificationStatementMacros.scala index 7e37ea935dc..54764805c61 100644 --- a/core/src/main/scala-3/chisel3/VerificationStatementMacros.scala +++ b/core/src/main/scala-3/chisel3/VerificationStatementMacros.scala @@ -23,7 +23,7 @@ object VerifStmtMacrosCompat { cond: Bool, message: Option[Printable] )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): Printable = { val (filename, line) = lineInfo val lineMsg = s"$filename:$line".replaceAll("%", "%%") diff --git a/core/src/main/scala-3/chisel3/probe/Probe.scala b/core/src/main/scala-3/chisel3/probe/Probe.scala index 11d477c5252..1fd0b5d4da2 100644 --- a/core/src/main/scala-3/chisel3/probe/Probe.scala +++ b/core/src/main/scala-3/chisel3/probe/Probe.scala @@ -9,10 +9,10 @@ object Probe extends ProbeBase { /** Mark a Chisel type as with a probe modifier. */ - def apply[T <: Data](source: => T)(implicit sourceInfo: SourceInfo): T = + def apply[T <: Data](source: => T)(using sourceInfo: SourceInfo): T = super.apply(source, false, None) - def apply[T <: Data](source: => T, color: Option[layer.Layer])(implicit sourceInfo: SourceInfo): T = + def apply[T <: Data](source: => T, color: Option[layer.Layer])(using sourceInfo: SourceInfo): T = super.apply(source, false, color) } @@ -20,5 +20,5 @@ object RWProbe extends ProbeBase with SourceInfoDoc { /** Mark a Chisel type with a writable probe modifier. */ - def apply[T <: Data](source: => T)(implicit sourceInfo: SourceInfo): T = super.apply(source, true) + def apply[T <: Data](source: => T)(using sourceInfo: SourceInfo): T = super.apply(source, true) } diff --git a/core/src/main/scala-3/chisel3/probe/ProbeValue.scala b/core/src/main/scala-3/chisel3/probe/ProbeValue.scala index 85b132ded56..f6db3b0c592 100644 --- a/core/src/main/scala-3/chisel3/probe/ProbeValue.scala +++ b/core/src/main/scala-3/chisel3/probe/ProbeValue.scala @@ -8,11 +8,11 @@ import chisel3.experimental.SourceInfo object ProbeValue extends ProbeValueBase with SourceInfoDoc { /** Create a read-only probe expression. */ - def apply[T <: Data](source: T)(implicit sourceInfo: SourceInfo): T = super.apply(source, writable = false) + def apply[T <: Data](source: T)(using sourceInfo: SourceInfo): T = super.apply(source, writable = false) } object RWProbeValue extends ProbeValueBase with SourceInfoDoc { /** Create a read/write probe expression. */ - def apply[T <: Data](source: T)(implicit sourceInfo: SourceInfo): T = super.apply(source, writable = true) + def apply[T <: Data](source: T)(using sourceInfo: SourceInfo): T = super.apply(source, writable = true) } diff --git a/core/src/main/scala-3/chisel3/probe/package.scala b/core/src/main/scala-3/chisel3/probe/package.scala index 107e46be1a4..dd840f6f9b0 100644 --- a/core/src/main/scala-3/chisel3/probe/package.scala +++ b/core/src/main/scala-3/chisel3/probe/package.scala @@ -11,5 +11,5 @@ package object probe extends ObjectProbeImpl { * * @param source probe whose value is getting accessed */ - def read[T <: Data](source: T)(implicit sourceInfo: SourceInfo): T = _readImpl(source) + def read[T <: Data](source: T)(using sourceInfo: SourceInfo): T = _readImpl(source) } diff --git a/src/main/scala-3/chisel3/choice/ModuleChoice.scala b/src/main/scala-3/chisel3/choice/ModuleChoice.scala index dedd695357d..4ae812a4bf3 100644 --- a/src/main/scala-3/chisel3/choice/ModuleChoice.scala +++ b/src/main/scala-3/chisel3/choice/ModuleChoice.scala @@ -30,6 +30,6 @@ object ModuleChoice extends ModuleChoiceImpl { default: => FixedIOBaseModule[T], choices: Seq[(Case, () => FixedIOBaseModule[T])] )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): T = _applyImpl(default, choices) } diff --git a/src/main/scala-3/chisel3/util/BitPat.scala b/src/main/scala-3/chisel3/util/BitPat.scala index b939dd58bf3..9de580c5a54 100644 --- a/src/main/scala-3/chisel3/util/BitPat.scala +++ b/src/main/scala-3/chisel3/util/BitPat.scala @@ -9,8 +9,8 @@ import scala.util.hashing.MurmurHash3 object BitPat extends ObjectBitPatImpl { implicit class fromUIntToBitPatComparable(x: UInt) { - def ===(that: BitPat)(implicit sourceInfo: SourceInfo): Bool = that === x - def =/=(that: BitPat)(implicit sourceInfo: SourceInfo): Bool = that =/= x + def ===(that: BitPat)(using sourceInfo: SourceInfo): Bool = that === x + def =/=(that: BitPat)(using sourceInfo: SourceInfo): Bool = that =/= x } } @@ -18,9 +18,9 @@ sealed class BitPat(val value: BigInt, val mask: BigInt, val width: Int) extends import chisel3.util.experimental.BitSet def terms = Set(this) - def apply(x: Int)(implicit sourceInfo: SourceInfo): BitPat = _applyImpl(x) - def apply(x: Int, y: Int)(implicit sourceInfo: SourceInfo): BitPat = _applyImpl(x, y) - def ===(that: UInt)(implicit sourceInfo: SourceInfo): Bool = _impl_===(that) - def =/=(that: UInt)(implicit sourceInfo: SourceInfo): Bool = _impl_=/=(that) - def ##(that: BitPat)(implicit sourceInfo: SourceInfo): BitPat = _impl_##(that) + def apply(x: Int)(using sourceInfo: SourceInfo): BitPat = _applyImpl(x) + def apply(x: Int, y: Int)(using sourceInfo: SourceInfo): BitPat = _applyImpl(x, y) + def ===(that: UInt)(using sourceInfo: SourceInfo): Bool = _impl_===(that) + def =/=(that: UInt)(using sourceInfo: SourceInfo): Bool = _impl_=/=(that) + def ##(that: BitPat)(using sourceInfo: SourceInfo): BitPat = _impl_##(that) } diff --git a/src/main/scala-3/chisel3/util/Bitwise.scala b/src/main/scala-3/chisel3/util/Bitwise.scala index f48b4f1e040..fa1fbca9f53 100644 --- a/src/main/scala-3/chisel3/util/Bitwise.scala +++ b/src/main/scala-3/chisel3/util/Bitwise.scala @@ -25,13 +25,13 @@ object FillInterleaved extends FillInterleavedImpl { * * Output data-equivalent to in(size(in)-1) (n times) ## ... ## in(1) (n times) ## in(0) (n times) */ - def apply(n: Int, in: UInt)(implicit sourceInfo: SourceInfo): UInt = _applyImpl(n, in) + def apply(n: Int, in: UInt)(using sourceInfo: SourceInfo): UInt = _applyImpl(n, in) /** Creates n repetitions of each bit of x in order. * * Output data-equivalent to in(size(in)-1) (n times) ## ... ## in(1) (n times) ## in(0) (n times) */ - def apply(n: Int, in: Seq[Bool])(implicit sourceInfo: SourceInfo): UInt = _applyImpl(n, in) + def apply(n: Int, in: Seq[Bool])(using sourceInfo: SourceInfo): UInt = _applyImpl(n, in) } /** Returns the number of bits set (value is 1 or true) in the input signal. @@ -47,8 +47,8 @@ object FillInterleaved extends FillInterleavedImpl { */ object PopCount extends PopCountImpl { - def apply(in: Iterable[Bool])(implicit sourceInfo: SourceInfo): UInt = _applyImpl(in) - def apply(in: Bits)(implicit sourceInfo: SourceInfo): UInt = _applyImpl(in) + def apply(in: Iterable[Bool])(using sourceInfo: SourceInfo): UInt = _applyImpl(in) + def apply(in: Bits)(using sourceInfo: SourceInfo): UInt = _applyImpl(in) } /** Create repetitions of the input using a tree fanout topology. @@ -66,7 +66,7 @@ object Fill extends FillImpl { * Output data-equivalent to x ## x ## ... ## x (n repetitions). * @throws java.lang.IllegalArgumentException if `n` is less than zero */ - def apply(n: Int, x: UInt)(implicit sourceInfo: SourceInfo): UInt = _applyImpl(n, x) + def apply(n: Int, x: UInt)(using sourceInfo: SourceInfo): UInt = _applyImpl(n, x) } /** Returns the input in bit-reversed order. Useful for little/big-endian conversion. @@ -79,5 +79,5 @@ object Fill extends FillImpl { */ object Reverse extends ReverseImpl { - def apply(in: UInt)(implicit sourceInfo: SourceInfo): UInt = _applyImpl(in) + def apply(in: UInt)(using sourceInfo: SourceInfo): UInt = _applyImpl(in) } diff --git a/src/main/scala-3/chisel3/util/Cat.scala b/src/main/scala-3/chisel3/util/Cat.scala index 2ebc69ab05e..ba05299db85 100644 --- a/src/main/scala-3/chisel3/util/Cat.scala +++ b/src/main/scala-3/chisel3/util/Cat.scala @@ -19,7 +19,7 @@ object Cat extends CatImpl { /** Concatenates the argument data elements, in argument order, together. The first argument * forms the most significant bits, while the last argument forms the least significant bits. */ - def apply[T <: Bits](a: T, r: T*)(implicit sourceInfo: SourceInfo): UInt = _applyImpl(a, r: _*) + def apply[T <: Bits](a: T, r: T*)(using sourceInfo: SourceInfo): UInt = _applyImpl(a, r: _*) /** Concatenates the data elements of the input sequence, in reverse sequence order, together. * The first element of the sequence forms the most significant bits, while the last element @@ -28,5 +28,5 @@ object Cat extends CatImpl { * Equivalent to r(0) ## r(1) ## ... ## r(n-1). * @note This returns a `0.U` if applied to a zero-element `Vec`. */ - def apply[T <: Bits](r: Seq[T])(implicit sourceInfo: SourceInfo): UInt = _applyImpl(r) + def apply[T <: Bits](r: Seq[T])(using sourceInfo: SourceInfo): UInt = _applyImpl(r) } diff --git a/src/main/scala-3/chisel3/util/Reg.scala b/src/main/scala-3/chisel3/util/Reg.scala index ba8e11c793d..9f058c3ea4b 100644 --- a/src/main/scala-3/chisel3/util/Reg.scala +++ b/src/main/scala-3/chisel3/util/Reg.scala @@ -13,7 +13,7 @@ object RegEnable extends RegEnableImpl { * val regWithEnable = RegEnable(nextVal, ena) * }}} */ - def apply[T <: Data](next: T, enable: Bool)(implicit sourceInfo: SourceInfo): T = _applyImpl(next, enable) + def apply[T <: Data](next: T, enable: Bool)(using sourceInfo: SourceInfo): T = _applyImpl(next, enable) /** Returns a register with the specified next, update enable gate, and reset initialization. * @@ -26,7 +26,7 @@ object RegEnable extends RegEnableImpl { init: T, enable: Bool )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): T = _applyImpl(next, init, enable) } @@ -47,7 +47,7 @@ object ShiftRegister extends ShiftRegisterImpl { n: Int, en: Bool = true.B )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): T = _applyImpl(in, n, en) @@ -62,7 +62,7 @@ object ShiftRegister extends ShiftRegisterImpl { * val regDelayTwo = ShiftRegister(nextVal, 2) * }}} */ - def apply[T <: Data](in: T, n: Int)(implicit sourceInfo: SourceInfo): T = + def apply[T <: Data](in: T, n: Int)(using sourceInfo: SourceInfo): T = _applyImpl(in, n) /** Returns the n-cycle delayed version of the input signal with reset initialization. @@ -82,7 +82,7 @@ object ShiftRegister extends ShiftRegisterImpl { resetData: T, en: Bool )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): T = _applyImpl(in, n, resetData, en) /** Returns the n-cycle delayed version of the input signal (SyncReadMem-based ShiftRegister implementation). @@ -100,7 +100,7 @@ object ShiftRegister extends ShiftRegisterImpl { useDualPortSram: Boolean, name: Option[String] )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): T = _applyImplMem(in, n, en, useDualPortSram, name) } @@ -117,7 +117,7 @@ object ShiftRegisters extends ShiftRegistersImpl { n: Int, en: Bool )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): Seq[T] = _applyImpl(in, n, en) /** Returns a sequence of delayed input signal registers from 1 to n. @@ -127,7 +127,7 @@ object ShiftRegisters extends ShiftRegistersImpl { * @param in input to delay * @param n number of cycles to delay */ - def apply[T <: Data](in: T, n: Int)(implicit sourceInfo: SourceInfo): Seq[T] = + def apply[T <: Data](in: T, n: Int)(using sourceInfo: SourceInfo): Seq[T] = _applyImpl(in, n) /** Returns delayed input signal registers with reset initialization from 1 to n. @@ -143,6 +143,6 @@ object ShiftRegisters extends ShiftRegistersImpl { resetData: T, en: Bool )( - implicit sourceInfo: SourceInfo + using sourceInfo: SourceInfo ): Seq[T] = _applyImpl(in, n, resetData, en) } From 8d327007eaf70e70b3201404dfff7c7304c245b7 Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Wed, 4 Dec 2024 08:58:34 -0800 Subject: [PATCH 15/30] Add Scala 3 compilation to CI --- .github/workflows/test.yml | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 655ff7e8cdc..2bcb5cfa56c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -134,6 +134,44 @@ jobs: - name: Compile with Mill run: ./mill __.compile + mill3: + name: compile scala-3 project with mill + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref }} + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: 'adopt' + java-version: '21' + - name: Install CIRCT + id: install-circt + if: ${{ inputs.circt }} + uses: circt/install-circt@v1.1.1 + with: + version: ${{ inputs.circt }} + github-token: ${{ github.token }} + # TODO have install-circt do this + - name: Set CHISEL_FIRTOOL_PATH and CIRCT_INSTALL_PATH + if: steps.install-circt.outcome == 'success' + run: | + bindir=$(dirname $(which firtool)) + installdir=$(dirname $bindir) + echo "CHISEL_FIRTOOL_PATH=$bindir" >> "$GITHUB_ENV" + echo "CIRCT_INSTALL_PATH=$installdir" >> "$GITHUB_ENV" + - name: Print firtool version + if: steps.install-circt.outcome == 'success' + run: | + echo "The CIRCT version used is:" >> $GITHUB_STEP_SUMMARY + echo \`\`\` >> $GITHUB_STEP_SUMMARY + $CHISEL_FIRTOOL_PATH/firtool -version >> $GITHUB_STEP_SUMMARY + echo \`\`\` >> $GITHUB_STEP_SUMMARY + - name: Compile with Mill + run: ./mill chisel[3.3.3].compile + doc: name: Formatting runs-on: ubuntu-22.04 From 365e0849e1819f6545b270d12d389417c67ade1f Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Wed, 4 Dec 2024 09:42:56 -0800 Subject: [PATCH 16/30] Update workflows with explicit scala version Cross compilation errors otherwise --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2bcb5cfa56c..9c7ee6d5e14 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -132,7 +132,7 @@ jobs: $CHISEL_FIRTOOL_PATH/firtool -version >> $GITHUB_STEP_SUMMARY echo \`\`\` >> $GITHUB_STEP_SUMMARY - name: Compile with Mill - run: ./mill __.compile + run: ./mill chisel[2.13.15].compile mill3: name: compile scala-3 project with mill @@ -188,7 +188,7 @@ jobs: - name: Check Build Script Formatting run: ./mill --meta-level 1 mill.scalalib.scalafmt.ScalafmtModule/checkFormatAll sources - name: Check Source File Format - run: ./mill __.checkFormat + run: ./mill chisel[2.13.15].checkFormat integration: name: Integration Tests @@ -221,7 +221,7 @@ jobs: dir=$(dirname $(which firtool)) echo "CHISEL_FIRTOOL_PATH=$dir" >> "$GITHUB_ENV" - name: Integration Tests - run: ./mill -j0 integrationTests[_].test + run: ./mill -j0 integrationTests[2.13.15].test # Currently just a sanity check that the benchmarking flow works benchmark: From cee3eeabef81ef3bd15439b4f486cb92aefdbe3c Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Wed, 4 Dec 2024 15:48:00 -0800 Subject: [PATCH 17/30] CI and build.sc updates --- .github/workflows/test.yml | 6 +++--- build.sc | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9c7ee6d5e14..a1837c40549 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -132,7 +132,7 @@ jobs: $CHISEL_FIRTOOL_PATH/firtool -version >> $GITHUB_STEP_SUMMARY echo \`\`\` >> $GITHUB_STEP_SUMMARY - name: Compile with Mill - run: ./mill chisel[2.13.15].compile + run: ./mill chisel[].compile mill3: name: compile scala-3 project with mill @@ -188,7 +188,7 @@ jobs: - name: Check Build Script Formatting run: ./mill --meta-level 1 mill.scalalib.scalafmt.ScalafmtModule/checkFormatAll sources - name: Check Source File Format - run: ./mill chisel[2.13.15].checkFormat + run: ./mill chisel[].checkFormat integration: name: Integration Tests @@ -221,7 +221,7 @@ jobs: dir=$(dirname $(which firtool)) echo "CHISEL_FIRTOOL_PATH=$dir" >> "$GITHUB_ENV" - name: Integration Tests - run: ./mill -j0 integrationTests[2.13.15].test + run: ./mill -j0 integrationTests[].test # Currently just a sanity check that the benchmarking flow works benchmark: diff --git a/build.sc b/build.sc index 1f2c8c06f73..6fe8c884fb9 100644 --- a/build.sc +++ b/build.sc @@ -38,8 +38,8 @@ object v extends Module { } val scalaCrossVersions = Seq( - "3.3.3", - "2.13.15" + "2.13.15", + "3.3.3" ) def isScala3(ver: String): Boolean = ver.startsWith("3.") @@ -314,7 +314,7 @@ trait Plugin extends CrossSbtModule with ScalafmtModule with ChiselPublishModule } object chisel extends Cross[Chisel](v.scalaCrossVersions) -trait Chisel extends CrossSbtModule with HasScala2MacroAnno with ScalafmtModule { +trait Chisel extends CrossSbtModule with HasScala2MacroAnno with HasScala2Plugin with ScalafmtModule { override def millSourcePath = super.millSourcePath / os.up def svsimModule = svsim(crossScalaVersion) def coreModule = core(crossScalaVersion) From 2f3df1518319d19d7b6fcc6a443803b481f12e5e Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Wed, 4 Dec 2024 16:05:37 -0800 Subject: [PATCH 18/30] Revert "Convert cloneType to an extension method" This reverts commit 0ba3c5d04a72d99d09ba14b4afa5d1371325aa97. --- core/src/main/scala-2/chisel3/Bits.scala | 6 +- .../main/scala/chisel3/AggregateImpl.scala | 19 +++---- core/src/main/scala/chisel3/BitsImpl.scala | 21 +++---- .../main/scala/chisel3/ChiselEnumImpl.scala | 2 +- core/src/main/scala/chisel3/ClockImpl.scala | 2 +- core/src/main/scala/chisel3/DataImpl.scala | 56 +++++++------------ core/src/main/scala/chisel3/IO.scala | 1 - core/src/main/scala/chisel3/Intrinsic.scala | 1 - core/src/main/scala/chisel3/MemImpl.scala | 1 - core/src/main/scala/chisel3/ModuleImpl.scala | 3 +- core/src/main/scala/chisel3/Reg.scala | 1 - .../scala/chisel3/experimental/Analog.scala | 2 +- .../hierarchy/core/Lookupable.scala | 1 - .../scala/chisel3/probe/PackageImpl.scala | 1 - .../scala/chisel3/probe/ProbeValueBase.scala | 2 +- .../scala/chisel3/reflect/DataMirror.scala | 1 - .../chisel3/choice/ModuleChoiceImpl.scala | 1 - src/main/scala/chisel3/util/MixedVec.scala | 1 - 18 files changed, 50 insertions(+), 72 deletions(-) diff --git a/core/src/main/scala-2/chisel3/Bits.scala b/core/src/main/scala-2/chisel3/Bits.scala index 8fd844c4ea6..a2c5b4274b0 100644 --- a/core/src/main/scala-2/chisel3/Bits.scala +++ b/core/src/main/scala-2/chisel3/Bits.scala @@ -160,10 +160,10 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends BitsImpl w * @note For [[SInt]]s only, this will do sign extension. * @group Bitwise */ - final def pad(that: Int): Bits = macro SourceInfoWhiteboxTransform.thatArg + final def pad(that: Int): this.type = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_pad(that: Int)(implicit sourceInfo: SourceInfo): Bits = _padImpl(that) + def do_pad(that: Int)(implicit sourceInfo: SourceInfo): this.type = _padImpl(that) /** Bitwise inversion operator * @@ -182,6 +182,8 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends BitsImpl w * $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 */ diff --git a/core/src/main/scala/chisel3/AggregateImpl.scala b/core/src/main/scala/chisel3/AggregateImpl.scala index 67bf233ff11..e878c8c089f 100644 --- a/core/src/main/scala/chisel3/AggregateImpl.scala +++ b/core/src/main/scala/chisel3/AggregateImpl.scala @@ -4,7 +4,6 @@ package chisel3 import chisel3.experimental.VecLiterals.AddVecLiteralConstructor import chisel3.experimental.dataview.{isView, reify, reifyIdentityView, InvalidViewException} -import chisel3.Data.DataExtensions import scala.collection.immutable.{SeqMap, VectorMap} import scala.collection.mutable.{HashSet, LinkedHashMap} @@ -422,7 +421,9 @@ private[chisel3] abstract class VecImpl[T <: Data] private[chisel3] (gen: => T, */ def apply(idx: Int): T = self(idx) - override def _cloneType: Vec[T] = new Vec(gen.cloneTypeFull, length) + override def cloneType: this.type = { + new Vec(gen.cloneTypeFull, length).asInstanceOf[this.type] + } override def getElements: Seq[Data] = self @@ -490,7 +491,7 @@ private[chisel3] abstract class VecImpl[T <: Data] private[chisel3] (gen: => T, elementInitializers: (Int, T)* )( implicit sourceInfo: SourceInfo - ): Vec[T] = { + ): this.type = { def checkLiteralConstruction(): Unit = { val dupKeys = elementInitializers.map { x => x._1 }.groupBy(x => x).flatMap { @@ -542,7 +543,7 @@ private[chisel3] abstract class VecImpl[T <: Data] private[chisel3] (gen: => T, requireIsChiselType(this, "vec literal constructor model") checkLiteralConstruction() - val clone = this.cloneType + val clone = cloneType val cloneFields = getRecursiveFields(clone, "(vec root)").toMap // Create the Vec literal binding from litArgs of arguments @@ -831,10 +832,8 @@ private[chisel3] trait RecordImpl extends AggregateImpl { thiz: Record => } } - // Note that _cloneTypeImpl is implemented by the compiler plugin and must be a different method name because - // We want to run checkClone after calling _cloneTypeImpl - final override def _cloneType: Data = { - val clone = _cloneTypeImpl + override def cloneType: this.type = { + val clone = _cloneTypeImpl.asInstanceOf[this.type] checkClone(clone) clone } @@ -954,10 +953,10 @@ private[chisel3] trait RecordImpl extends AggregateImpl { thiz: Record => * ) * }}} */ - private[chisel3] def _makeLit(elems: (Data => (Data, Data))*)(implicit sourceInfo: SourceInfo): Data = { + private[chisel3] def _makeLit(elems: (this.type => (Data, Data))*)(implicit sourceInfo: SourceInfo): this.type = { requireIsChiselType(this, "bundle literal constructor model") - val clone = this.cloneType + val clone = cloneType val cloneFields = getRecursiveFields(clone, "_").toMap // Create the Bundle literal binding from litargs of arguments diff --git a/core/src/main/scala/chisel3/BitsImpl.scala b/core/src/main/scala/chisel3/BitsImpl.scala index d003c1ddb22..98c5f2b6f42 100644 --- a/core/src/main/scala/chisel3/BitsImpl.scala +++ b/core/src/main/scala/chisel3/BitsImpl.scala @@ -2,7 +2,6 @@ package chisel3 -import chisel3.Data.DataExtensions import chisel3.experimental.{requireIsHardware, SourceInfo} import chisel3.internal.{_resizeToWidth, throwException, BaseModule} import chisel3.internal.Builder.pushOp @@ -22,9 +21,9 @@ private[chisel3] trait BitsImpl extends Element { self: Bits => // Arguments against: generates down to a FIRRTL UInt anyways // Only used for in a few cases, hopefully to be removed - private[chisel3] def cloneTypeWidth(width: Width): Bits + private[chisel3] def cloneTypeWidth(width: Width): this.type - override def _cloneType: Data = cloneTypeWidth(this.width) + def cloneType: this.type = cloneTypeWidth(this.width) /** A non-ambiguous name of this `Bits` instance for use in generated Verilog names * Inserts the width directly after the typeName, e.g. UInt4, SInt1 @@ -168,7 +167,7 @@ private[chisel3] trait BitsImpl extends Element { self: Bits => // Pad literal to that width protected def _padLit(that: Int): this.type - protected def _padImpl(that: Int)(implicit sourceInfo: SourceInfo): Bits = this.width match { + protected def _padImpl(that: Int)(implicit sourceInfo: SourceInfo): this.type = this.width match { case KnownWidth(w) if w >= that => this case _ if this.isLit => this._padLit(that) case _ => binop(sourceInfo, cloneTypeWidth(this.width.max(Width(that))), PadOp, that) @@ -223,7 +222,8 @@ private[chisel3] trait UIntImpl extends BitsImpl with Num[UInt] { self: UInt => } } - private[chisel3] override def cloneTypeWidth(w: Width): UInt = new UInt(w) + private[chisel3] override def cloneTypeWidth(w: Width): this.type = + new UInt(w).asInstanceOf[this.type] override protected def _padLit(that: Int): this.type = { val value = this.litValue @@ -403,7 +403,8 @@ private[chisel3] trait SIntImpl extends BitsImpl with Num[SInt] { self: SInt => } } - private[chisel3] override def cloneTypeWidth(w: Width): SInt = new SInt(w) + private[chisel3] override def cloneTypeWidth(w: Width): this.type = + new SInt(w).asInstanceOf[this.type] override protected def _padLit(that: Int): this.type = { val value = this.litValue @@ -528,7 +529,7 @@ private[chisel3] trait ResetTypeImpl extends Element { self: Reset => override def toString: String = stringAccessor("Reset") - override def _cloneType: Data = Reset() + def cloneType: this.type = Reset().asInstanceOf[this.type] override def litOption: Option[BigInt] = None @@ -557,7 +558,7 @@ private[chisel3] trait AsyncResetImpl extends Element { self: AsyncReset => override def toString: String = stringAccessor("AsyncReset") - override def _cloneType: Data = AsyncReset() + def cloneType: this.type = AsyncReset().asInstanceOf[this.type] override def litOption: Option[BigInt] = None @@ -598,9 +599,9 @@ private[chisel3] trait BoolImpl extends UIntImpl { self: Bool => } } - private[chisel3] override def cloneTypeWidth(w: Width): Bool = { + private[chisel3] override def cloneTypeWidth(w: Width): this.type = { require(!w.known || w.get == 1) - new Bool() + new Bool().asInstanceOf[this.type] } /** Convert to a [[scala.Option]] of [[scala.Boolean]] */ diff --git a/core/src/main/scala/chisel3/ChiselEnumImpl.scala b/core/src/main/scala/chisel3/ChiselEnumImpl.scala index 4f8d3be1cc5..c69e769f0dd 100644 --- a/core/src/main/scala/chisel3/ChiselEnumImpl.scala +++ b/core/src/main/scala/chisel3/ChiselEnumImpl.scala @@ -30,7 +30,7 @@ private[chisel3] abstract class EnumTypeImpl(private[chisel3] val factory: Chise } } - override def _cloneType: Data = factory() + override def cloneType: this.type = factory().asInstanceOf[this.type] private[chisel3] def compop(sourceInfo: SourceInfo, op: PrimOp, other: EnumType): Bool = { requireIsHardware(this, "bits operated on") diff --git a/core/src/main/scala/chisel3/ClockImpl.scala b/core/src/main/scala/chisel3/ClockImpl.scala index 70f2dfc0b05..cf4e26b8d0e 100644 --- a/core/src/main/scala/chisel3/ClockImpl.scala +++ b/core/src/main/scala/chisel3/ClockImpl.scala @@ -13,7 +13,7 @@ private[chisel3] trait ClockImpl extends Element { override def toString: String = stringAccessor("Clock") - override def _cloneType: Data = Clock() + def cloneType: this.type = Clock().asInstanceOf[this.type] override def connect(that: Data)(implicit sourceInfo: SourceInfo): Unit = that match { diff --git a/core/src/main/scala/chisel3/DataImpl.scala b/core/src/main/scala/chisel3/DataImpl.scala index 6dc94ba1b10..e262dbd7bdc 100644 --- a/core/src/main/scala/chisel3/DataImpl.scala +++ b/core/src/main/scala/chisel3/DataImpl.scala @@ -4,7 +4,6 @@ package chisel3 import chisel3.experimental.dataview.reify -import chisel3.Data.DataExtensions import chisel3.experimental.{requireIsChiselType, requireIsHardware, Analog, BaseModule} import chisel3.experimental.{prefix, SourceInfo, UnlocatableSourceInfo} import chisel3.experimental.dataview.{reifyIdentityView, reifySingleTarget, DataViewable} @@ -782,12 +781,28 @@ private[chisel3] trait DataImpl extends HasId with NamedComponent { self: Data = private[chisel3] def width: Width private[chisel3] def firrtlConnect(that: Data)(implicit sourceInfo: SourceInfo): Unit - /** Private implementation of cloneType + /** Internal API; Chisel users should look at chisel3.chiselTypeOf(...). * - * _cloneType must be defined for any Chisel object extending Data. - * It is implemented by Chisel itself or by the compiler plugin for user-defined types. + * cloneType must be defined for any Chisel object extending Data. + * It is responsible for constructing a basic copy of the object being cloned. + * + * @return a copy of the object. + */ + def cloneType: this.type + + /** Internal API; Chisel users should look at chisel3.chiselTypeOf(...). + * + * Returns a copy of this data type, with hardware bindings (if any) removed. + * Directionality data and probe information is still preserved. */ - def _cloneType: Data + private[chisel3] def cloneTypeFull: this.type = { + val clone = this.cloneType // get a fresh object, without bindings + // Only the top-level direction needs to be fixed up, cloneType should do the rest + clone.specifiedDirection = specifiedDirection + probe.setProbeModifier(clone, probeInfo) + clone.isConst = isConst + clone + } /** The "strong connect" operator. * @@ -979,7 +994,6 @@ private[chisel3] trait ObjectDataImpl { * * @param lhs The [[Data]] hardware on the left-hand side of the equality */ - // TODO fold this into DataExtensions implicit class DataEquality[T <: Data](lhs: T)(implicit sourceInfo: SourceInfo) { /** Dynamic recursive equality operator for generic [[Data]] @@ -1058,33 +1072,6 @@ private[chisel3] trait ObjectDataImpl { } } } - - implicit class DataExtensions[T <: Data](self: T) { - - /** Internal API; Chisel users should look at chisel3.chiselTypeOf(...). - * - * cloneType must be defined for any Chisel object extending Data. - * It is responsible for constructing a basic copy of the object being cloned. - * - * @return a copy of the object. - */ - def cloneType: T = self._cloneType.asInstanceOf[T] - - /** Internal API; Chisel users should look at chisel3.chiselTypeOf(...). - * - * Returns a copy of this data type, with hardware bindings (if any) removed. - * Directionality data and probe information is still preserved. - */ - private[chisel3] def cloneTypeFull: T = { - val clone = self.cloneType // get a fresh object, without bindings - // Only the top-level direction needs to be fixed up, cloneType should do the rest - clone.specifiedDirection = self.specifiedDirection - // TODO do we need to exclude probe and const from cloneTypeFull on Properties? - probe.setProbeModifier(clone, self.probeInfo) - clone.isConst = self.isConst - clone.asInstanceOf[T] - } - } } trait WireFactory { @@ -1256,8 +1243,7 @@ final case object DontCare extends Element with connectable.ConnectableDocs { private[chisel3] override val width: Width = UnknownWidth bind(DontCareBinding(), SpecifiedDirection.Output) - - override def _cloneType: Data = DontCare + override def cloneType: this.type = DontCare override def toString: String = "DontCare()" diff --git a/core/src/main/scala/chisel3/IO.scala b/core/src/main/scala/chisel3/IO.scala index 201699b6744..1814d6aa97a 100644 --- a/core/src/main/scala/chisel3/IO.scala +++ b/core/src/main/scala/chisel3/IO.scala @@ -1,6 +1,5 @@ package chisel3 -import chisel3.Data.DataExtensions import chisel3.internal.{throwException, Builder} import chisel3.experimental.{noPrefix, requireIsChiselType, SourceInfo} import chisel3.properties.{Class, Property} diff --git a/core/src/main/scala/chisel3/Intrinsic.scala b/core/src/main/scala/chisel3/Intrinsic.scala index 088faaa35e7..6f1d0d5e091 100644 --- a/core/src/main/scala/chisel3/Intrinsic.scala +++ b/core/src/main/scala/chisel3/Intrinsic.scala @@ -3,7 +3,6 @@ package chisel3 import chisel3._ -import chisel3.Data.DataExtensions import chisel3.experimental.{requireIsChiselType, Param, SourceInfo} import chisel3.internal.firrtl.ir._ import chisel3.internal.Builder diff --git a/core/src/main/scala/chisel3/MemImpl.scala b/core/src/main/scala/chisel3/MemImpl.scala index 89a52a30776..5dcb5a3f8a8 100644 --- a/core/src/main/scala/chisel3/MemImpl.scala +++ b/core/src/main/scala/chisel3/MemImpl.scala @@ -9,7 +9,6 @@ import chisel3.internal.binding._ import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl.ir._ import chisel3.experimental.{requireIsChiselType, requireIsHardware, SourceInfo, SourceLine} -import chisel3.Data.DataExtensions private[chisel3] trait ObjectMemImpl { diff --git a/core/src/main/scala/chisel3/ModuleImpl.scala b/core/src/main/scala/chisel3/ModuleImpl.scala index c9e63b20c13..95cd323b6c6 100644 --- a/core/src/main/scala/chisel3/ModuleImpl.scala +++ b/core/src/main/scala/chisel3/ModuleImpl.scala @@ -28,7 +28,6 @@ import chisel3.internal.plugin.autoNameRecursively import chisel3.util.simpleClassName import chisel3.experimental.{annotate, ChiselAnnotation} import chisel3.experimental.hierarchy.Hierarchy -import chisel3.Data.DataExtensions private[chisel3] trait ObjectModuleImpl { @@ -371,7 +370,7 @@ package internal { private[chisel3] class ClonePorts(elts: (String, Data)*) extends Record { val elements: ListMap[String, Data] = ListMap(elts.map { case (name, d) => name -> d.cloneTypeFull }: _*) def apply(field: String) = elements(field) - override protected def _cloneTypeImpl: Record = (new ClonePorts(elts: _*)) + override def cloneType = (new ClonePorts(elts: _*)).asInstanceOf[this.type] } private[chisel3] def cloneIORecord( diff --git a/core/src/main/scala/chisel3/Reg.scala b/core/src/main/scala/chisel3/Reg.scala index 06f1cf89bdc..44958874168 100644 --- a/core/src/main/scala/chisel3/Reg.scala +++ b/core/src/main/scala/chisel3/Reg.scala @@ -7,7 +7,6 @@ import chisel3.internal.binding._ import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl.ir._ import chisel3.experimental.{requireIsChiselType, requireIsHardware, SourceInfo} -import chisel3.Data.DataExtensions /** Utility for constructing hardware registers * diff --git a/core/src/main/scala/chisel3/experimental/Analog.scala b/core/src/main/scala/chisel3/experimental/Analog.scala index 5988ac8ccdc..c0136abe0ca 100644 --- a/core/src/main/scala/chisel3/experimental/Analog.scala +++ b/core/src/main/scala/chisel3/experimental/Analog.scala @@ -34,7 +34,7 @@ final class Analog private (private[chisel3] val width: Width) extends Element { override def litOption: Option[BigInt] = None - override def _cloneType: Data = new Analog(width) + def cloneType: this.type = new Analog(width).asInstanceOf[this.type] // Used to enforce single bulk connect of Analog types, multi-attach is still okay // Note that this really means 1 bulk connect per Module because a port can diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/core/Lookupable.scala b/core/src/main/scala/chisel3/experimental/hierarchy/core/Lookupable.scala index 1135ad6176a..d5a25367788 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/core/Lookupable.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/core/Lookupable.scala @@ -12,7 +12,6 @@ import chisel3.experimental.dataview.{isView, reify, reifyIdentityView} import chisel3.internal.firrtl.ir.{Arg, ILit, Index, LitIndex, ModuleIO, Slot, ULit} import chisel3.internal.{throwException, Builder, ViewParent} import chisel3.internal.binding.{AggregateViewBinding, ChildBinding, CrossModuleBinding, ViewBinding, ViewWriteability} -import chisel3.Data.DataExtensions /** Typeclass used to recontextualize values from an original Definition to an Instance * diff --git a/core/src/main/scala/chisel3/probe/PackageImpl.scala b/core/src/main/scala/chisel3/probe/PackageImpl.scala index fddf164681e..6420385e9ff 100644 --- a/core/src/main/scala/chisel3/probe/PackageImpl.scala +++ b/core/src/main/scala/chisel3/probe/PackageImpl.scala @@ -11,7 +11,6 @@ import chisel3.Data.ProbeInfo import chisel3.experimental.{requireIsHardware, SourceInfo} import chisel3.experimental.dataview.reifyIdentityView import chisel3.reflect.DataMirror.{checkTypeEquivalence, collectAllMembers, hasProbeTypeModifier} -import chisel3.Data.DataExtensions private[chisel3] trait ObjectProbeImpl { diff --git a/core/src/main/scala/chisel3/probe/ProbeValueBase.scala b/core/src/main/scala/chisel3/probe/ProbeValueBase.scala index 46d4d36c5c7..f4193cfe122 100644 --- a/core/src/main/scala/chisel3/probe/ProbeValueBase.scala +++ b/core/src/main/scala/chisel3/probe/ProbeValueBase.scala @@ -28,6 +28,6 @@ private[chisel3] trait ProbeValueBase { } else { source.ref } clone.setRef(ProbeExpr(ref)) } - clone.asInstanceOf[T] + clone } } diff --git a/core/src/main/scala/chisel3/reflect/DataMirror.scala b/core/src/main/scala/chisel3/reflect/DataMirror.scala index 72abb033855..78a889c56dc 100644 --- a/core/src/main/scala/chisel3/reflect/DataMirror.scala +++ b/core/src/main/scala/chisel3/reflect/DataMirror.scala @@ -10,7 +10,6 @@ import chisel3.experimental.{requireIsHardware, BaseModule, SourceInfo} import chisel3.experimental.hierarchy.{Instance, ModuleClone} import chisel3.experimental.hierarchy.core.Clone import chisel3.properties.Property -import chisel3.Data.DataExtensions import scala.reflect.ClassTag object DataMirror { diff --git a/src/main/scala/chisel3/choice/ModuleChoiceImpl.scala b/src/main/scala/chisel3/choice/ModuleChoiceImpl.scala index 6bac3539017..8eb606b0426 100644 --- a/src/main/scala/chisel3/choice/ModuleChoiceImpl.scala +++ b/src/main/scala/chisel3/choice/ModuleChoiceImpl.scala @@ -5,7 +5,6 @@ package chisel3.choice import scala.collection.immutable.ListMap import chisel3.{Data, FixedIOBaseModule, Module, SourceInfoDoc} -import chisel3.Data.DataExtensions import chisel3.experimental.{BaseModule, SourceInfo} import chisel3.internal.{groupByIntoSeq, Builder} import chisel3.internal.binding.WireBinding diff --git a/src/main/scala/chisel3/util/MixedVec.scala b/src/main/scala/chisel3/util/MixedVec.scala index 8aabf4496b5..5d64d89c1b7 100644 --- a/src/main/scala/chisel3/util/MixedVec.scala +++ b/src/main/scala/chisel3/util/MixedVec.scala @@ -3,7 +3,6 @@ package chisel3.util import chisel3._ -import chisel3.Data.DataExtensions import chisel3.experimental.requireIsChiselType import scala.collection.immutable.ListMap From c0fe7bb2fe8dde68f5797aeb886cebfed3bb46be Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Wed, 4 Dec 2024 16:24:35 -0800 Subject: [PATCH 19/30] Get things working with this.type --- core/src/main/scala/chisel3/AggregateImpl.scala | 6 +++--- core/src/main/scala/chisel3/ChiselEnumImpl.scala | 3 +-- core/src/main/scala/chisel3/DataImpl.scala | 2 +- .../src/main/scala/chisel3/properties/Property.scala | 12 +++++++++++- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/core/src/main/scala/chisel3/AggregateImpl.scala b/core/src/main/scala/chisel3/AggregateImpl.scala index e878c8c089f..1cb43f2e1f7 100644 --- a/core/src/main/scala/chisel3/AggregateImpl.scala +++ b/core/src/main/scala/chisel3/AggregateImpl.scala @@ -543,7 +543,7 @@ private[chisel3] abstract class VecImpl[T <: Data] private[chisel3] (gen: => T, requireIsChiselType(this, "vec literal constructor model") checkLiteralConstruction() - val clone = cloneType + val clone: this.type = this.cloneType val cloneFields = getRecursiveFields(clone, "(vec root)").toMap // Create the Vec literal binding from litArgs of arguments @@ -833,7 +833,7 @@ private[chisel3] trait RecordImpl extends AggregateImpl { thiz: Record => } override def cloneType: this.type = { - val clone = _cloneTypeImpl.asInstanceOf[this.type] + val clone: this.type = _cloneTypeImpl.asInstanceOf[this.type] checkClone(clone) clone } @@ -956,7 +956,7 @@ private[chisel3] trait RecordImpl extends AggregateImpl { thiz: Record => private[chisel3] def _makeLit(elems: (this.type => (Data, Data))*)(implicit sourceInfo: SourceInfo): this.type = { requireIsChiselType(this, "bundle literal constructor model") - val clone = cloneType + val clone: this.type = cloneType val cloneFields = getRecursiveFields(clone, "_").toMap // Create the Bundle literal binding from litargs of arguments diff --git a/core/src/main/scala/chisel3/ChiselEnumImpl.scala b/core/src/main/scala/chisel3/ChiselEnumImpl.scala index c69e769f0dd..c44b45a0e44 100644 --- a/core/src/main/scala/chisel3/ChiselEnumImpl.scala +++ b/core/src/main/scala/chisel3/ChiselEnumImpl.scala @@ -363,8 +363,7 @@ private[chisel3] trait ChiselEnumImpl { self: ChiselEnum => // This is an enum type that can be connected directly to UInts. It is used as a "glue" to cast non-literal UInts // to enums. private[chisel3] class UnsafeEnum(override val width: Width) extends EnumType(UnsafeEnum, selfAnnotating = false) { - - override def _cloneType: Data = new UnsafeEnum(width) + override def cloneType: this.type = new UnsafeEnum(width).asInstanceOf[this.type] } private object UnsafeEnum extends ChiselEnum diff --git a/core/src/main/scala/chisel3/DataImpl.scala b/core/src/main/scala/chisel3/DataImpl.scala index e262dbd7bdc..dc7201ca7fd 100644 --- a/core/src/main/scala/chisel3/DataImpl.scala +++ b/core/src/main/scala/chisel3/DataImpl.scala @@ -796,7 +796,7 @@ private[chisel3] trait DataImpl extends HasId with NamedComponent { self: Data = * Directionality data and probe information is still preserved. */ private[chisel3] def cloneTypeFull: this.type = { - val clone = this.cloneType // get a fresh object, without bindings + val clone: this.type = this.cloneType // get a fresh object, without bindings // Only the top-level direction needs to be fixed up, cloneType should do the rest clone.specifiedDirection = specifiedDirection probe.setProbeModifier(clone, probeInfo) diff --git a/core/src/main/scala/chisel3/properties/Property.scala b/core/src/main/scala/chisel3/properties/Property.scala index 8526bb34fd3..2bdf440246b 100644 --- a/core/src/main/scala/chisel3/properties/Property.scala +++ b/core/src/main/scala/chisel3/properties/Property.scala @@ -277,8 +277,18 @@ sealed trait Property[T] extends Element { self => /** Clone type by simply constructing a new Property[T]. */ - override def _cloneType: Data = new Property[T] { + override def cloneType: this.type = new Property[T] { val tpe = self.tpe + }.asInstanceOf[this.type] + + /** Clone type with extra information preserved. + * + * The only extra information present on a Property type is directionality. + */ + private[chisel3] override def cloneTypeFull: this.type = { + val clone: this.type = this.cloneType + clone.specifiedDirection = specifiedDirection + clone } /** Get the IR PropertyType for this Property. From 65f87c1ca65f921f12efb505a139a692d48c64fe Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Wed, 11 Dec 2024 17:31:13 -0800 Subject: [PATCH 20/30] Move plugins to plugin/src/main/scala-2 This simplifies build.sc handling of plugins --- .../chisel3/internal/plugin/BundleComponent.scala | 0 .../chisel3/internal/plugin/ChiselComponent.scala | 0 .../{scala => scala-2}/chisel3/internal/plugin/ChiselPlugin.scala | 0 .../{scala => scala-2}/chisel3/internal/plugin/ChiselUtils.scala | 0 .../chisel3/internal/plugin/DeprecateSFCComponent.scala | 0 .../chisel3/internal/plugin/IdentifierComponent.scala | 0 .../chisel3/internal/sourceinfo/SourceInfoFileResolver.scala | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename plugin/src/main/{scala => scala-2}/chisel3/internal/plugin/BundleComponent.scala (100%) rename plugin/src/main/{scala => scala-2}/chisel3/internal/plugin/ChiselComponent.scala (100%) rename plugin/src/main/{scala => scala-2}/chisel3/internal/plugin/ChiselPlugin.scala (100%) rename plugin/src/main/{scala => scala-2}/chisel3/internal/plugin/ChiselUtils.scala (100%) rename plugin/src/main/{scala => scala-2}/chisel3/internal/plugin/DeprecateSFCComponent.scala (100%) rename plugin/src/main/{scala => scala-2}/chisel3/internal/plugin/IdentifierComponent.scala (100%) rename plugin/src/main/{scala => scala-2}/chisel3/internal/sourceinfo/SourceInfoFileResolver.scala (100%) diff --git a/plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala b/plugin/src/main/scala-2/chisel3/internal/plugin/BundleComponent.scala similarity index 100% rename from plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala rename to plugin/src/main/scala-2/chisel3/internal/plugin/BundleComponent.scala diff --git a/plugin/src/main/scala/chisel3/internal/plugin/ChiselComponent.scala b/plugin/src/main/scala-2/chisel3/internal/plugin/ChiselComponent.scala similarity index 100% rename from plugin/src/main/scala/chisel3/internal/plugin/ChiselComponent.scala rename to plugin/src/main/scala-2/chisel3/internal/plugin/ChiselComponent.scala diff --git a/plugin/src/main/scala/chisel3/internal/plugin/ChiselPlugin.scala b/plugin/src/main/scala-2/chisel3/internal/plugin/ChiselPlugin.scala similarity index 100% rename from plugin/src/main/scala/chisel3/internal/plugin/ChiselPlugin.scala rename to plugin/src/main/scala-2/chisel3/internal/plugin/ChiselPlugin.scala diff --git a/plugin/src/main/scala/chisel3/internal/plugin/ChiselUtils.scala b/plugin/src/main/scala-2/chisel3/internal/plugin/ChiselUtils.scala similarity index 100% rename from plugin/src/main/scala/chisel3/internal/plugin/ChiselUtils.scala rename to plugin/src/main/scala-2/chisel3/internal/plugin/ChiselUtils.scala diff --git a/plugin/src/main/scala/chisel3/internal/plugin/DeprecateSFCComponent.scala b/plugin/src/main/scala-2/chisel3/internal/plugin/DeprecateSFCComponent.scala similarity index 100% rename from plugin/src/main/scala/chisel3/internal/plugin/DeprecateSFCComponent.scala rename to plugin/src/main/scala-2/chisel3/internal/plugin/DeprecateSFCComponent.scala diff --git a/plugin/src/main/scala/chisel3/internal/plugin/IdentifierComponent.scala b/plugin/src/main/scala-2/chisel3/internal/plugin/IdentifierComponent.scala similarity index 100% rename from plugin/src/main/scala/chisel3/internal/plugin/IdentifierComponent.scala rename to plugin/src/main/scala-2/chisel3/internal/plugin/IdentifierComponent.scala diff --git a/plugin/src/main/scala/chisel3/internal/sourceinfo/SourceInfoFileResolver.scala b/plugin/src/main/scala-2/chisel3/internal/sourceinfo/SourceInfoFileResolver.scala similarity index 100% rename from plugin/src/main/scala/chisel3/internal/sourceinfo/SourceInfoFileResolver.scala rename to plugin/src/main/scala-2/chisel3/internal/sourceinfo/SourceInfoFileResolver.scala From 5763b57ebf394b6eabed17bb1dbf2b21bebc5948 Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Wed, 11 Dec 2024 17:31:59 -0800 Subject: [PATCH 21/30] Add plugin 3.3.4 stub and change version to 3.3.4 Update plugin dependency handling for Scala3 --- .github/workflows/test.yml | 2 +- build.sc | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a1837c40549..393389f2f63 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -170,7 +170,7 @@ jobs: $CHISEL_FIRTOOL_PATH/firtool -version >> $GITHUB_STEP_SUMMARY echo \`\`\` >> $GITHUB_STEP_SUMMARY - name: Compile with Mill - run: ./mill chisel[3.3.3].compile + run: ./mill chisel[3.3.4].compile doc: name: Formatting diff --git a/build.sc b/build.sc index 6fe8c884fb9..a8630e56cd6 100644 --- a/build.sc +++ b/build.sc @@ -34,12 +34,13 @@ object v extends Module { val java21Min213 = 11 val minVersion = if (javaVersion > 11) java21Min213 else 0 val versions = minVersion to latest213 - versions.map(v => s"2.13.$v").toSeq + val versionSeq = versions.map(v => s"2.13.$v").toSeq + versionSeq ++ Seq("3.3.4") } val scalaCrossVersions = Seq( "2.13.15", - "3.3.3" + "3.3.4" ) def isScala3(ver: String): Boolean = ver.startsWith("3.") @@ -310,7 +311,13 @@ trait Plugin extends CrossSbtModule with ScalafmtModule with ChiselPublishModule def scalaReflectIvy = v.scalaReflect(crossScalaVersion) def scalaCompilerIvy: Dep = v.scalaCompiler(crossScalaVersion) - def ivyDeps = super.ivyDeps() ++ Agg(scalaLibraryIvy, scalaReflectIvy, scalaCompilerIvy) + def ivyDeps = T { + if (!v.isScala3(crossScalaVersion)) { + super.ivyDeps() ++ Agg(scalaLibraryIvy, scalaReflectIvy, scalaCompilerIvy) + } else { + super.ivyDeps() + } + } } object chisel extends Cross[Chisel](v.scalaCrossVersions) From 04821b77977dd681ac2ddcb8ed1e40113676238e Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Tue, 17 Dec 2024 15:49:18 -0800 Subject: [PATCH 22/30] Code review updates Format code --- .../chisel3/experimental/dataview/ChiselSubtypeOf.scala | 1 - .../chisel3/experimental/hierarchy/core/Hierarchy.scala | 3 ++- core/src/main/scala-3/chisel3/Aggregate.scala | 3 +-- core/src/main/scala-3/chisel3/Disable.scala | 3 +-- core/src/main/scala-3/chisel3/Module.scala | 2 +- core/src/main/scala-3/chisel3/VerificationStatement.scala | 1 - .../chisel3/experimental/hierarchy/HierarchyMarker.scala | 2 +- .../chisel3/experimental/hierarchy/core/Hierarchy.scala | 3 ++- core/src/main/scala/chisel3/ChiselEnumImpl.scala | 2 +- 9 files changed, 9 insertions(+), 11 deletions(-) diff --git a/core/src/main/scala-2/chisel3/experimental/dataview/ChiselSubtypeOf.scala b/core/src/main/scala-2/chisel3/experimental/dataview/ChiselSubtypeOf.scala index 3a6932552f6..f30d868065e 100644 --- a/core/src/main/scala-2/chisel3/experimental/dataview/ChiselSubtypeOf.scala +++ b/core/src/main/scala-2/chisel3/experimental/dataview/ChiselSubtypeOf.scala @@ -27,7 +27,6 @@ import scala.reflect.macros.blackbox.Context */ sealed trait ChiselSubtypeOf[A, B] - // return an empty tree here instead of a quasiquote for scala3 compatibility object ChiselSubtypeOf { // TODO return an empty tree here instead of a quasiquote for scala3 compatibility diff --git a/core/src/main/scala-2/chisel3/experimental/hierarchy/core/Hierarchy.scala b/core/src/main/scala-2/chisel3/experimental/hierarchy/core/Hierarchy.scala index ad027fedda9..80b004eba1f 100644 --- a/core/src/main/scala-2/chisel3/experimental/hierarchy/core/Hierarchy.scala +++ b/core/src/main/scala-2/chisel3/experimental/hierarchy/core/Hierarchy.scala @@ -7,7 +7,8 @@ import _root_.firrtl.annotations.IsModule import scala.reflect.runtime.universe.TypeTag trait Hierarchy[+A] extends HierarchyImpl[A] { -/** Determine whether underlying proto is of type provided. + + /** Determine whether underlying proto is of type provided. * * @note IMPORTANT: this function requires summoning a TypeTag[B], which will fail if B is an inner class. * @note IMPORTANT: this function IGNORES type parameters, akin to normal type erasure. diff --git a/core/src/main/scala-3/chisel3/Aggregate.scala b/core/src/main/scala-3/chisel3/Aggregate.scala index 3583cc0f1d0..b7c6e778918 100644 --- a/core/src/main/scala-3/chisel3/Aggregate.scala +++ b/core/src/main/scala-3/chisel3/Aggregate.scala @@ -52,8 +52,7 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, length: Int) override def toString: String = super[VecImpl].toString - def apply(p: UInt)(using sourceInfo: SourceInfo): T = do_apply(p) - def do_apply(p: UInt)(using sourceInfo: SourceInfo): T = _applyImpl(p) + def apply(p: UInt)(using sourceInfo: SourceInfo): T = _applyImpl(p) /** A reduce operation in a tree like structure instead of sequentially * @example An adder tree diff --git a/core/src/main/scala-3/chisel3/Disable.scala b/core/src/main/scala-3/chisel3/Disable.scala index 411638b6962..8affd4068df 100644 --- a/core/src/main/scala-3/chisel3/Disable.scala +++ b/core/src/main/scala-3/chisel3/Disable.scala @@ -3,8 +3,7 @@ package chisel3 import chisel3.internal._ -import chisel3.experimental.{OpaqueType, SourceInfo} -import scala.collection.immutable.ListMap +import chisel3.experimental.SourceInfo /** API for handling disabling of simulation constructs * diff --git a/core/src/main/scala-3/chisel3/Module.scala b/core/src/main/scala-3/chisel3/Module.scala index 7bc01adf34a..2cb99c235f6 100644 --- a/core/src/main/scala-3/chisel3/Module.scala +++ b/core/src/main/scala-3/chisel3/Module.scala @@ -15,7 +15,7 @@ object Module extends ObjectModuleImpl with SourceInfoDoc { */ // TODO(adkian-sifive) the callsite here explicitly passes // sourceInfo so it cannot be a contextual parameter - def apply[T <: BaseModule](bc: => T): T = _applyImpl(bc) + def apply[T <: BaseModule](bc: => T): T = _applyImpl(bc) def do_apply[T <: BaseModule](bc: => T)(implicit sourceInfo: SourceInfo): T = apply(bc) } diff --git a/core/src/main/scala-3/chisel3/VerificationStatement.scala b/core/src/main/scala-3/chisel3/VerificationStatement.scala index 346cc4ef732..b4b3c691f49 100644 --- a/core/src/main/scala-3/chisel3/VerificationStatement.scala +++ b/core/src/main/scala-3/chisel3/VerificationStatement.scala @@ -55,4 +55,3 @@ object cover extends VerifPrintMacrosDoc { type SourceLineInfo = (String, Int) } - diff --git a/core/src/main/scala-3/chisel3/experimental/hierarchy/HierarchyMarker.scala b/core/src/main/scala-3/chisel3/experimental/hierarchy/HierarchyMarker.scala index c1838b4c56b..f6268ca5c10 100644 --- a/core/src/main/scala-3/chisel3/experimental/hierarchy/HierarchyMarker.scala +++ b/core/src/main/scala-3/chisel3/experimental/hierarchy/HierarchyMarker.scala @@ -1,3 +1,3 @@ package chisel3.experimental -trait Markers \ No newline at end of file +trait Markers diff --git a/core/src/main/scala-3/chisel3/experimental/hierarchy/core/Hierarchy.scala b/core/src/main/scala-3/chisel3/experimental/hierarchy/core/Hierarchy.scala index c6f13498b58..078c2f85428 100644 --- a/core/src/main/scala-3/chisel3/experimental/hierarchy/core/Hierarchy.scala +++ b/core/src/main/scala-3/chisel3/experimental/hierarchy/core/Hierarchy.scala @@ -6,7 +6,8 @@ import chisel3.experimental.BaseModule import _root_.firrtl.annotations.IsModule trait Hierarchy[+A] extends HierarchyImpl[A] { -/** Determine whether underlying proto is of type provided. + + /** Determine whether underlying proto is of type provided. * * @note IMPORTANT: this function requires summoning a TypeTag[B], which will fail if B is an inner class. * @note IMPORTANT: this function IGNORES type parameters, akin to normal type erasure. diff --git a/core/src/main/scala/chisel3/ChiselEnumImpl.scala b/core/src/main/scala/chisel3/ChiselEnumImpl.scala index c44b45a0e44..967a5e39ae4 100644 --- a/core/src/main/scala/chisel3/ChiselEnumImpl.scala +++ b/core/src/main/scala/chisel3/ChiselEnumImpl.scala @@ -228,7 +228,7 @@ private[chisel3] abstract class EnumTypeImpl(private[chisel3] val factory: Chise // value U is not a member of Char. // An extension method was tried, // but could not be fully constructed: - // + // // chisel3.fromLongToLiteral(c.toChar) // r := c.toChar.U } From 77a10f4da945eda0a4532e7b559b6199afc27773 Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Tue, 17 Dec 2024 15:49:31 -0800 Subject: [PATCH 23/30] Add compileAll function in build.sc Use compileAll in CI Mill compilation --- .github/workflows/test.yml | 44 +++----------------------------------- build.sc | 12 +++++++++++ 2 files changed, 15 insertions(+), 41 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 393389f2f63..fea333dde76 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -90,7 +90,7 @@ jobs: $CHISEL_FIRTOOL_PATH/firtool -version >> $GITHUB_STEP_SUMMARY echo \`\`\` >> $GITHUB_STEP_SUMMARY - name: Test - run: ./mill -j0 firrtl[_].test + svsim[_].test + chisel[_].test + run: ./mill -j0 firrtl[].test + svsim[].test + chisel[].test - name: Binary compatibility # TODO either make this also check the plugin or decide that we don't # support binary compatibility for the plugin @@ -132,45 +132,7 @@ jobs: $CHISEL_FIRTOOL_PATH/firtool -version >> $GITHUB_STEP_SUMMARY echo \`\`\` >> $GITHUB_STEP_SUMMARY - name: Compile with Mill - run: ./mill chisel[].compile - - mill3: - name: compile scala-3 project with mill - runs-on: ubuntu-22.04 - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - ref: ${{ inputs.ref }} - - name: Setup Java - uses: actions/setup-java@v4 - with: - distribution: 'adopt' - java-version: '21' - - name: Install CIRCT - id: install-circt - if: ${{ inputs.circt }} - uses: circt/install-circt@v1.1.1 - with: - version: ${{ inputs.circt }} - github-token: ${{ github.token }} - # TODO have install-circt do this - - name: Set CHISEL_FIRTOOL_PATH and CIRCT_INSTALL_PATH - if: steps.install-circt.outcome == 'success' - run: | - bindir=$(dirname $(which firtool)) - installdir=$(dirname $bindir) - echo "CHISEL_FIRTOOL_PATH=$bindir" >> "$GITHUB_ENV" - echo "CIRCT_INSTALL_PATH=$installdir" >> "$GITHUB_ENV" - - name: Print firtool version - if: steps.install-circt.outcome == 'success' - run: | - echo "The CIRCT version used is:" >> $GITHUB_STEP_SUMMARY - echo \`\`\` >> $GITHUB_STEP_SUMMARY - $CHISEL_FIRTOOL_PATH/firtool -version >> $GITHUB_STEP_SUMMARY - echo \`\`\` >> $GITHUB_STEP_SUMMARY - - name: Compile with Mill - run: ./mill chisel[3.3.4].compile + run: ./mill compileAll doc: name: Formatting @@ -188,7 +150,7 @@ jobs: - name: Check Build Script Formatting run: ./mill --meta-level 1 mill.scalalib.scalafmt.ScalafmtModule/checkFormatAll sources - name: Check Source File Format - run: ./mill chisel[].checkFormat + run: ./mill __.checkFormat integration: name: Integration Tests diff --git a/build.sc b/build.sc index a8630e56cd6..03e60430abc 100644 --- a/build.sc +++ b/build.sc @@ -45,6 +45,14 @@ object v extends Module { def isScala3(ver: String): Boolean = ver.startsWith("3.") + def buildUnits(): Seq[ScalaModule] = { + scalaCrossVersions.flatMap { ver => + Seq(chisel(ver), stdlib(ver), unipublish) + } ++ scalaCrossVersions.filterNot(isScala3(_)).flatMap { ver2 => + Seq(chisel(ver2).test) + } + } + val scalaVersion = scalaCrossVersions.head val jmhVersion = "1.37" val osLib = ivy"com.lihaoyi::os-lib:0.10.0" @@ -98,6 +106,10 @@ object v extends Module { ) } +def compileAll() = T.command { + T.traverse(v.buildUnits())(_.compile)() +} + trait ChiselPublishModule extends CiReleaseModule { // Publish information def pomSettings = PomSettings( From e694a6a633bfeb4d6d53b3cde03b15e9f53d2895 Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Tue, 17 Dec 2024 16:05:03 -0800 Subject: [PATCH 24/30] Update Printf.scala Share def format --- core/src/main/scala-3/chisel3/Printf.scala | 24 +--------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/core/src/main/scala-3/chisel3/Printf.scala b/core/src/main/scala-3/chisel3/Printf.scala index 213a460645f..fd765ef356a 100644 --- a/core/src/main/scala-3/chisel3/Printf.scala +++ b/core/src/main/scala-3/chisel3/Printf.scala @@ -13,33 +13,11 @@ import scala.language.experimental.macros * * See apply methods for use */ -object printf { +object printf extends PrintfImpl { /** Named class for [[printf]]s. */ final class Printf private[chisel3] (val pable: Printable) extends VerificationStatement - /** Helper for packing escape characters */ - private[chisel3] def format(formatIn: String): String = { - require(formatIn.forall(c => c.toInt > 0 && c.toInt < 128), "format strings must comprise non-null ASCII values") - def escaped(x: Char) = { - require(x.toInt >= 0, s"char ${x} to Int ${x.toInt} must be >= 0") - if (x == '"' || x == '\\') { - s"\\${x}" - } else if (x == '\n') { - "\\n" - } else if (x == '\t') { - "\\t" - } else { - require( - x.toInt >= 32, - s"char ${x} to Int ${x.toInt} must be >= 32" - ) // TODO \xNN once FIRRTL issue #59 is resolved - x - } - } - formatIn.map(escaped).mkString("") - } - /** Prints a message in simulation * * Prints a message every cycle. If defined within the scope of a [[when]] block, the message From 88cb4d3f05dad85eacfe0abfdfc21320fce4fa32 Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Wed, 18 Dec 2024 01:59:47 -0800 Subject: [PATCH 25/30] Hierarchy updates Refactor cross-compilation logic --- .../chisel3/experimental/hierarchy/IsA.scala | 54 +++++++++++++ .../chisel3/experimental/hierarchy/IsA.scala | 48 +++++++++++ .../hierarchy/core/Hierarchy.scala | 63 --------------- .../hierarchy/core/Hierarchy.scala | 53 ++++++++---- .../hierarchy/core/HierarchyImpl.scala | 80 ------------------- 5 files changed, 141 insertions(+), 157 deletions(-) create mode 100644 core/src/main/scala-2/chisel3/experimental/hierarchy/IsA.scala create mode 100644 core/src/main/scala-3/chisel3/experimental/hierarchy/IsA.scala delete mode 100644 core/src/main/scala-3/chisel3/experimental/hierarchy/core/Hierarchy.scala rename core/src/main/{scala-2 => scala}/chisel3/experimental/hierarchy/core/Hierarchy.scala (56%) delete mode 100644 core/src/main/scala/chisel3/experimental/hierarchy/core/HierarchyImpl.scala diff --git a/core/src/main/scala-2/chisel3/experimental/hierarchy/IsA.scala b/core/src/main/scala-2/chisel3/experimental/hierarchy/IsA.scala new file mode 100644 index 00000000000..24adecbf438 --- /dev/null +++ b/core/src/main/scala-2/chisel3/experimental/hierarchy/IsA.scala @@ -0,0 +1,54 @@ +package chisel3.experimental.hierarchy.core + +import chisel3._ +import scala.reflect.runtime.universe.TypeTag + +trait HierarchyProto[+A] { + private[chisel3] def underlying: Underlying[A] + private[chisel3] def proto: A = underlying match { + case Proto(value) => value + case Clone(i: IsClone[A]) => i.getProto + } +} + +trait HierarchyIsA[+A] extends HierarchyProto[A] { + // This code handles a special-case where, within an mdoc context, the type returned from + // scala reflection (typetag) looks different than when returned from java reflection. + // This function detects this case and reshapes the string to match. + private def modifyReplString(clz: String): String = { + if (clz != null) { + clz.split('.').toList match { + case "repl" :: "MdocSession" :: app :: rest => s"$app.this." + rest.mkString(".") + case other => clz + } + } else clz + } + + private lazy val superClasses = calculateSuperClasses(super.proto.getClass()) + private def calculateSuperClasses(clz: Class[_]): Set[String] = { + if (clz != null) { + Set(modifyReplString(clz.getCanonicalName())) ++ + clz.getInterfaces().flatMap(i => calculateSuperClasses(i)) ++ + calculateSuperClasses(clz.getSuperclass()) + } else { + Set.empty[String] + } + } + private def inBaseClasses(clz: String): Boolean = superClasses.contains(clz) + + /** Determine whether underlying proto is of type provided. + * + * @note IMPORTANT: this function requires summoning a TypeTag[B], which will fail if B is an inner class. + * @note IMPORTANT: this function IGNORES type parameters, akin to normal type erasure. + * @note IMPORTANT: this function relies on Java reflection for underlying proto, but Scala reflection for provided type + * + * E.g. isA[List[Int]] will return true, even if underlying proto is of type List[String] + * @return Whether underlying proto is of provided type (with caveats outlined above) + */ + def isA[B: TypeTag]: Boolean = { + val tptag = implicitly[TypeTag[B]] + // drop any type information for the comparison, because the proto will not have that information. + val name = tptag.tpe.toString.takeWhile(_ != '[') + inBaseClasses(name) + } +} diff --git a/core/src/main/scala-3/chisel3/experimental/hierarchy/IsA.scala b/core/src/main/scala-3/chisel3/experimental/hierarchy/IsA.scala new file mode 100644 index 00000000000..9e31c074cb7 --- /dev/null +++ b/core/src/main/scala-3/chisel3/experimental/hierarchy/IsA.scala @@ -0,0 +1,48 @@ +package chisel3.experimental.hierarchy.core + +import chisel3._ + +trait HierarchyProto[+A] { + private[chisel3] def underlying: Underlying[A] + private[chisel3] def proto: A = underlying match { + case Proto(value) => value + case Clone(i: IsClone[A]) => i.getProto + } +} + +trait HierarchyIsA[+A] extends HierarchyProto[A] { + // This code handles a special-case where, within an mdoc context, the type returned from + // scala reflection (typetag) looks different than when returned from java reflection. + // This function detects this case and reshapes the string to match. + private def modifyReplString(clz: String): String = { + if (clz != null) { + clz.split('.').toList match { + case "repl" :: "MdocSession" :: app :: rest => s"$app.this." + rest.mkString(".") + case other => clz + } + } else clz + } + + private lazy val superClasses = calculateSuperClasses(super.proto.getClass()) + private def calculateSuperClasses(clz: Class[_]): Set[String] = { + if (clz != null) { + Set(modifyReplString(clz.getCanonicalName())) ++ + clz.getInterfaces().flatMap(i => calculateSuperClasses(i)) ++ + calculateSuperClasses(clz.getSuperclass()) + } else { + Set.empty[String] + } + } + private def inBaseClasses(clz: String): Boolean = superClasses.contains(clz) + + /** Determine whether underlying proto is of type provided. + * + * @note IMPORTANT: this function requires summoning a TypeTag[B], which will fail if B is an inner class. + * @note IMPORTANT: this function IGNORES type parameters, akin to normal type erasure. + * @note IMPORTANT: this function relies on Java reflection for underlying proto, but Scala reflection for provided type + * + * E.g. isA[List[Int]] will return true, even if underlying proto is of type List[String] + * @return Whether underlying proto is of provided type (with caveats outlined above) + */ + def isA[B]: Boolean = false // TODO +} diff --git a/core/src/main/scala-3/chisel3/experimental/hierarchy/core/Hierarchy.scala b/core/src/main/scala-3/chisel3/experimental/hierarchy/core/Hierarchy.scala deleted file mode 100644 index 078c2f85428..00000000000 --- a/core/src/main/scala-3/chisel3/experimental/hierarchy/core/Hierarchy.scala +++ /dev/null @@ -1,63 +0,0 @@ -package chisel3.experimental.hierarchy.core - -import chisel3._ -import scala.collection.mutable.{HashMap, HashSet} -import chisel3.experimental.BaseModule -import _root_.firrtl.annotations.IsModule - -trait Hierarchy[+A] extends HierarchyImpl[A] { - - /** Determine whether underlying proto is of type provided. - * - * @note IMPORTANT: this function requires summoning a TypeTag[B], which will fail if B is an inner class. - * @note IMPORTANT: this function IGNORES type parameters, akin to normal type erasure. - * @note IMPORTANT: this function relies on Java reflection for underlying proto, but Scala reflection for provided type - * - * E.g. isA[List[Int]] will return true, even if underlying proto is of type List[String] - * @return Whether underlying proto is of provided type (with caveats outlined above) - */ - def isA[B]: Boolean = false - -} - -object Hierarchy { - implicit class HierarchyBaseModuleExtensions[T <: BaseModule](i: Hierarchy[T]) { - - /** Returns the toTarget of this hierarchy - * @return target of this hierarchy - */ - def toTarget: IsModule = i match { - case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toTarget - case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toTarget - case _ => throw new InternalErrorException("Match error: toTarget i=$i") - } - - /** Returns the toAbsoluteTarget of this hierarchy - * @return absoluteTarget of this Hierarchy - */ - def toAbsoluteTarget: IsModule = i match { - case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toAbsoluteTarget - case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toAbsoluteTarget - case _ => throw new InternalErrorException("Match error: toAbsoluteTarget i=$i") - } - - /** Returns the toRelativeTarget of this hierarchy - * @return relativeTarget of this Hierarchy - */ - def toRelativeTarget(root: Option[BaseModule]): IsModule = i match { - case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toRelativeTarget(root) - case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toRelativeTarget(root) - case _ => throw new InternalErrorException("Match error: toAbsoluteTarget i=$i") - } - - /** Returns the toRelativeTarget of this hierarchy - * @return relativeTarget of this Hierarchy - */ - def toRelativeTargetToHierarchy(root: Option[Hierarchy[BaseModule]]): IsModule = i match { - case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toRelativeTargetToHierarchy(root) - case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toRelativeTargetToHierarchy(root) - case _ => throw new InternalErrorException("Match error: toAbsoluteTarget i=$i") - } - - } -} diff --git a/core/src/main/scala-2/chisel3/experimental/hierarchy/core/Hierarchy.scala b/core/src/main/scala/chisel3/experimental/hierarchy/core/Hierarchy.scala similarity index 56% rename from core/src/main/scala-2/chisel3/experimental/hierarchy/core/Hierarchy.scala rename to core/src/main/scala/chisel3/experimental/hierarchy/core/Hierarchy.scala index 80b004eba1f..242bb027560 100644 --- a/core/src/main/scala-2/chisel3/experimental/hierarchy/core/Hierarchy.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/core/Hierarchy.scala @@ -1,31 +1,56 @@ +// SPDX-License-Identifier: Apache-2.0 + package chisel3.experimental.hierarchy.core import chisel3._ + import scala.collection.mutable.{HashMap, HashSet} import chisel3.experimental.BaseModule import _root_.firrtl.annotations.IsModule -import scala.reflect.runtime.universe.TypeTag -trait Hierarchy[+A] extends HierarchyImpl[A] { +import scala.annotation.implicitNotFound + +/** Super-trait for Instance and Definition + * + * Enables writing functions which are Instance/Definition agnostic + */ +sealed trait Hierarchy[+A] extends HierarchyIsA[A] { - /** Determine whether underlying proto is of type provided. + /** Updated by calls to [[_lookup]], to avoid recloning returned Data's */ + private[chisel3] val cache = HashMap[Data, Data]() + private[chisel3] def getInnerDataContext: Option[BaseModule] + + /** Used by Chisel's internal macros. DO NOT USE in your normal Chisel code!!! + * Instead, mark the field you are accessing with [[public]] + * + * Given a selector function (that) which selects a member from the original, return the + * corresponding member from the hierarchy. * - * @note IMPORTANT: this function requires summoning a TypeTag[B], which will fail if B is an inner class. - * @note IMPORTANT: this function IGNORES type parameters, akin to normal type erasure. - * @note IMPORTANT: this function relies on Java reflection for underlying proto, but Scala reflection for provided type + * Our @instantiable and @public macros generate the calls to this apply method * - * E.g. isA[List[Int]] will return true, even if underlying proto is of type List[String] - * @return Whether underlying proto is of provided type (with caveats outlined above) + * By calling this function, we summon the proper Lookupable typeclass from our implicit scope. + * + * @param that a user-specified lookup function + * @param lookup typeclass which contains the correct lookup function, based on the types of A and B + * @param macroGenerated a value created in the macro, to make it harder for users to use this API */ - def isA[B: TypeTag]: Boolean = { - val tptag = implicitly[TypeTag[B]] - // drop any type information for the comparison, because the proto will not have that information. - val name = tptag.tpe.toString.takeWhile(_ != '[') - inBaseClasses(name) - } + def _lookup[B, C]( + that: A => B + )( + implicit lookup: Lookupable[B], + macroGenerated: chisel3.internal.MacroGenerated + ): lookup.C + /** @return Return the underlying Definition[A] of this Hierarchy[A] */ + def toDefinition: Definition[A] + + /** @return Convert this Hierarchy[A] as a top-level Instance[A] */ + def toInstance: Instance[A] } +// Used to effectively seal Hierarchy, without requiring Definition and Instance to be in this file. +private[chisel3] trait SealedHierarchy[+A] extends Hierarchy[A] + object Hierarchy { implicit class HierarchyBaseModuleExtensions[T <: BaseModule](i: Hierarchy[T]) { diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/core/HierarchyImpl.scala b/core/src/main/scala/chisel3/experimental/hierarchy/core/HierarchyImpl.scala deleted file mode 100644 index ff1e29e9297..00000000000 --- a/core/src/main/scala/chisel3/experimental/hierarchy/core/HierarchyImpl.scala +++ /dev/null @@ -1,80 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -package chisel3.experimental.hierarchy.core - -import chisel3._ - -import scala.collection.mutable.{HashMap, HashSet} -import chisel3.experimental.BaseModule -import _root_.firrtl.annotations.IsModule - -import scala.annotation.implicitNotFound - -/** Super-trait for Instance and Definition - * - * Enables writing functions which are Instance/Definition agnostic - */ -trait HierarchyImpl[+A] { - private[chisel3] def underlying: Underlying[A] - private[chisel3] def proto: A = underlying match { - case Proto(value) => value - case Clone(i: IsClone[A]) => i.getProto - } - - /** Updated by calls to [[_lookup]], to avoid recloning returned Data's */ - private[chisel3] val cache = HashMap[Data, Data]() - private[chisel3] def getInnerDataContext: Option[BaseModule] - - // This code handles a special-case where, within an mdoc context, the type returned from - // scala reflection (typetag) looks different than when returned from java reflection. - // This function detects this case and reshapes the string to match. - private def modifyReplString(clz: String): String = { - if (clz != null) { - clz.split('.').toList match { - case "repl" :: "MdocSession" :: app :: rest => s"$app.this." + rest.mkString(".") - case other => clz - } - } else clz - } - private lazy val superClasses = calculateSuperClasses(proto.getClass()) - private def calculateSuperClasses(clz: Class[_]): Set[String] = { - if (clz != null) { - Set(modifyReplString(clz.getCanonicalName())) ++ - clz.getInterfaces().flatMap(i => calculateSuperClasses(i)) ++ - calculateSuperClasses(clz.getSuperclass()) - } else { - Set.empty[String] - } - } - protected def inBaseClasses(clz: String): Boolean = superClasses.contains(clz) - - /** Used by Chisel's internal macros. DO NOT USE in your normal Chisel code!!! - * Instead, mark the field you are accessing with [[public]] - * - * Given a selector function (that) which selects a member from the original, return the - * corresponding member from the hierarchy. - * - * Our @instantiable and @public macros generate the calls to this apply method - * - * By calling this function, we summon the proper Lookupable typeclass from our implicit scope. - * - * @param that a user-specified lookup function - * @param lookup typeclass which contains the correct lookup function, based on the types of A and B - * @param macroGenerated a value created in the macro, to make it harder for users to use this API - */ - def _lookup[B, C]( - that: A => B - )( - implicit lookup: Lookupable[B], - macroGenerated: chisel3.internal.MacroGenerated - ): lookup.C - - /** @return Return the underlying Definition[A] of this Hierarchy[A] */ - def toDefinition: Definition[A] - - /** @return Convert this Hierarchy[A] as a top-level Instance[A] */ - def toInstance: Instance[A] -} - -// Used to effectively seal Hierarchy, without requiring Definition and Instance to be in this file. -private[chisel3] trait SealedHierarchy[+A] extends Hierarchy[A] From bc6ff61ce3f094493ab82b8760c451e5e0663d80 Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Wed, 18 Dec 2024 02:51:13 -0800 Subject: [PATCH 26/30] Fix Instance.scala --- .../scala/chisel3/experimental/hierarchy/core/Instance.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/core/Instance.scala b/core/src/main/scala/chisel3/experimental/hierarchy/core/Instance.scala index d10a667303b..ebacfee5a95 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/core/Instance.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/core/Instance.scala @@ -166,7 +166,7 @@ object Instance extends SourceInfoDoc { Some(component) } } - Definition(new EmptyExtModule() {}.asInstanceOf[Underlying[_]]) + Definition(new EmptyExtModule() {}) } val ports = experimental.CloneModuleAsRecord(definition.proto) From 9a8b282d25b788e82b09a6f58bd0b62bf3623ac3 Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Wed, 18 Dec 2024 03:39:08 -0800 Subject: [PATCH 27/30] Fix ChiselEnum --- core/src/main/scala/chisel3/ChiselEnumImpl.scala | 14 +++----------- core/src/main/scala/chisel3/DataImpl.scala | 2 +- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/core/src/main/scala/chisel3/ChiselEnumImpl.scala b/core/src/main/scala/chisel3/ChiselEnumImpl.scala index 967a5e39ae4..e6d63509b96 100644 --- a/core/src/main/scala/chisel3/ChiselEnumImpl.scala +++ b/core/src/main/scala/chisel3/ChiselEnumImpl.scala @@ -70,8 +70,8 @@ private[chisel3] abstract class EnumTypeImpl(private[chisel3] val factory: Chise _wire := this.asUInt _wire } - _padded.asTypeOf(that) - case None => super.asTypeOf(that) + _padded._asTypeOfImpl(that) + case None => super._asTypeOfImpl(that) } } @@ -222,15 +222,7 @@ private[chisel3] abstract class EnumTypeImpl(private[chisel3] val factory: Chise for ((name, value) <- allNamesPadded) { when(this === value) { for ((r, c) <- result.zip(name)) { - // todo: this doesn't work in scala3 - // r := c.toChar.U - // ^^^^^^^^^^ - // value U is not a member of Char. - // An extension method was tried, - // but could not be fully constructed: - // - // chisel3.fromLongToLiteral(c.toChar) - // r := c.toChar.U + r := UInt.Lit(BigInt(c.toChar), Width()) } } } diff --git a/core/src/main/scala/chisel3/DataImpl.scala b/core/src/main/scala/chisel3/DataImpl.scala index dc7201ca7fd..062aba1f1fc 100644 --- a/core/src/main/scala/chisel3/DataImpl.scala +++ b/core/src/main/scala/chisel3/DataImpl.scala @@ -861,7 +861,7 @@ private[chisel3] trait DataImpl extends HasId with NamedComponent { self: Data = /** Returns Some(width) if the width is known, else None. */ final def widthOption: Option[Int] = if (isWidthKnown) Some(getWidth) else None - protected def _asTypeOfImpl[T <: Data](that: T)(implicit sourceInfo: SourceInfo): T = { + private[chisel3] def _asTypeOfImpl[T <: Data](that: T)(implicit sourceInfo: SourceInfo): T = { that._fromUInt(this.asUInt).asInstanceOf[T].viewAsReadOnly { _ => "Return values of asTypeOf are now read-only" } From f46d276427ac357669e3780f71832e1cee5e3cee Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Wed, 18 Dec 2024 14:08:54 -0800 Subject: [PATCH 28/30] Add remaining units to buildUnits build.sc --- build.sc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sc b/build.sc index 03e60430abc..ab0240f1c17 100644 --- a/build.sc +++ b/build.sc @@ -49,7 +49,7 @@ object v extends Module { scalaCrossVersions.flatMap { ver => Seq(chisel(ver), stdlib(ver), unipublish) } ++ scalaCrossVersions.filterNot(isScala3(_)).flatMap { ver2 => - Seq(chisel(ver2).test) + Seq(chisel(ver2).test, firrtl(ver2).test, svsim(ver2).test, integrationTests(ver2).test, litutility(ver2), panamaconverter(ver2), panamalib(ver2), panamaom(ver2)) } } From dfd3245548a79ade734537c5ef55b6b326175562 Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Thu, 19 Dec 2024 12:22:01 -0800 Subject: [PATCH 29/30] Code review updates --- build.sc | 11 ++++++++++- core/src/main/scala/chisel3/BitsImpl.scala | 2 +- .../experimental/hierarchy/InstantiateImpl.scala | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/build.sc b/build.sc index ab0240f1c17..bce888a8d5c 100644 --- a/build.sc +++ b/build.sc @@ -49,7 +49,16 @@ object v extends Module { scalaCrossVersions.flatMap { ver => Seq(chisel(ver), stdlib(ver), unipublish) } ++ scalaCrossVersions.filterNot(isScala3(_)).flatMap { ver2 => - Seq(chisel(ver2).test, firrtl(ver2).test, svsim(ver2).test, integrationTests(ver2).test, litutility(ver2), panamaconverter(ver2), panamalib(ver2), panamaom(ver2)) + Seq( + chisel(ver2).test, + firrtl(ver2).test, + svsim(ver2).test, + integrationTests(ver2).test, + litutility(ver2), + panamaconverter(ver2), + panamalib(ver2), + panamaom(ver2) + ) } } diff --git a/core/src/main/scala/chisel3/BitsImpl.scala b/core/src/main/scala/chisel3/BitsImpl.scala index 98c5f2b6f42..f28dcc3ce34 100644 --- a/core/src/main/scala/chisel3/BitsImpl.scala +++ b/core/src/main/scala/chisel3/BitsImpl.scala @@ -99,7 +99,7 @@ private[chisel3] trait BitsImpl extends Element { self: Bits => } protected def _applyImpl(x: UInt)(implicit sourceInfo: SourceInfo): Bool = - extract(x) + _extractImpl(x) protected def _applyImpl(x: Int, y: Int)(implicit sourceInfo: SourceInfo): UInt = { if ((x < y && !(x == -1 && y == 0)) || y < 0) { diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/InstantiateImpl.scala b/core/src/main/scala/chisel3/experimental/hierarchy/InstantiateImpl.scala index b4aea3029a2..f8107ecf117 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/InstantiateImpl.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/InstantiateImpl.scala @@ -92,7 +92,7 @@ private[chisel3] trait InstantiateImpl { val modulePrefix = Module.currentModulePrefix Builder.contextCache .getOrElseUpdate( - CacheKey[A](boxAllData(args), tt, Seq(modulePrefix).toList), { + CacheKey[A](boxAllData(args), tt, List(modulePrefix)), { // The definition needs to have no source locator because otherwise it will be unstably // derived from the first invocation of Instantiate for the particular Module Definition.apply(f(args))(UnlocatableSourceInfo) From d754f9f044b5b56a9af1357bb98a71836d2f15ed Mon Sep 17 00:00:00 2001 From: Aditya Naik Date: Thu, 19 Dec 2024 12:32:39 -0800 Subject: [PATCH 30/30] Code review updates --- core/src/main/scala-3/chisel3/Module.scala | 3 +-- core/src/main/scala/chisel3/ModuleImpl.scala | 2 +- core/src/main/scala/chisel3/internal/package.scala | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/core/src/main/scala-3/chisel3/Module.scala b/core/src/main/scala-3/chisel3/Module.scala index 2cb99c235f6..95559db5b21 100644 --- a/core/src/main/scala-3/chisel3/Module.scala +++ b/core/src/main/scala-3/chisel3/Module.scala @@ -15,8 +15,7 @@ object Module extends ObjectModuleImpl with SourceInfoDoc { */ // TODO(adkian-sifive) the callsite here explicitly passes // sourceInfo so it cannot be a contextual parameter - def apply[T <: BaseModule](bc: => T): T = _applyImpl(bc) - def do_apply[T <: BaseModule](bc: => T)(implicit sourceInfo: SourceInfo): T = apply(bc) + def apply[T <: BaseModule](bc: => T): T = _applyImpl(bc) } /** Abstract base class for Modules, which behave much like Verilog modules. diff --git a/core/src/main/scala/chisel3/ModuleImpl.scala b/core/src/main/scala/chisel3/ModuleImpl.scala index 95cd323b6c6..3127d43882c 100644 --- a/core/src/main/scala/chisel3/ModuleImpl.scala +++ b/core/src/main/scala/chisel3/ModuleImpl.scala @@ -31,7 +31,7 @@ import chisel3.experimental.hierarchy.Hierarchy private[chisel3] trait ObjectModuleImpl { - protected def _applyImpl[T <: BaseModule](bc: => T)(implicit sourceInfo: SourceInfo): T = { + protected[chisel3] def _applyImpl[T <: BaseModule](bc: => T)(implicit sourceInfo: SourceInfo): T = { // Instantiate the module definition. val module: T = evaluate[T](bc) diff --git a/core/src/main/scala/chisel3/internal/package.scala b/core/src/main/scala/chisel3/internal/package.scala index b022a38866b..e55156bb7a4 100644 --- a/core/src/main/scala/chisel3/internal/package.scala +++ b/core/src/main/scala/chisel3/internal/package.scala @@ -130,7 +130,7 @@ package object internal { * @note this is a lazy val so that calling functions in this package object doesn't create it */ private[chisel3] lazy val ViewParent = - Module.do_apply(new ViewParentAPI)(UnlocatableSourceInfo) + Module._applyImpl(new ViewParentAPI)(UnlocatableSourceInfo) private[chisel3] def requireHasProbeTypeModifier( probe: Data,