Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions core/src/main/scala/chisel3/Aggregate.scala
Original file line number Diff line number Diff line change
Expand Up @@ -368,9 +368,7 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) extend
*/
def apply(idx: Int): T = self(idx)

override def cloneType: this.type = {
new Vec(gen.cloneTypeFull, length).asInstanceOf[this.type]
}
override protected def _cloneType: Data = new Vec(gen.cloneTypeFull, length)

override def getElements: Seq[Data] = self

Expand Down Expand Up @@ -457,7 +455,7 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) extend
elementInitializers: (Int, T)*
)(
implicit sourceInfo: SourceInfo
): this.type = {
): Vec[T] = {

def checkLiteralConstruction(): Unit = {
val dupKeys = elementInitializers.map { x => x._1 }.groupBy(x => x).flatMap {
Expand Down Expand Up @@ -510,7 +508,7 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) extend
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
Expand Down Expand Up @@ -979,8 +977,10 @@ abstract class Record extends Aggregate {
}
}

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 protected def _cloneType: Data = {
val clone = _cloneTypeImpl
checkClone(clone)
clone
}
Expand Down Expand Up @@ -1102,10 +1102,10 @@ abstract class Record extends Aggregate {
* )
* }}}
*/
private[chisel3] def _makeLit(elems: (this.type => (Data, Data))*): this.type = {
private[chisel3] def _makeLit(elems: (Data => (Data, Data))*): Record = {

requireIsChiselType(this, "bundle literal constructor model")
val clone = cloneType
val clone = this.cloneType
val cloneFields = getRecursiveFields(clone, "(bundle root)").toMap

// Create the Bundle literal binding from litargs of arguments
Expand Down
39 changes: 22 additions & 17 deletions core/src/main/scala/chisel3/Bits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi
// 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(width)
override protected def _cloneType: Data = cloneTypeWidth(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
Expand Down Expand Up @@ -291,13 +291,10 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi
* @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 = this.width match {
case KnownWidth(w) if w >= that => this
case _ => binop(sourceInfo, cloneTypeWidth(this.width.max(Width(that))), PadOp, that)
}
def do_pad(that: Int)(implicit sourceInfo: SourceInfo): Bits

/** Bitwise inversion operator
*
Expand All @@ -316,8 +313,6 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi
* $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 */
Expand Down Expand Up @@ -450,8 +445,7 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U
}
}

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)

// TODO: refactor to share documentation with Num or add independent scaladoc
/** Unary negation (expanding width)
Expand Down Expand Up @@ -592,6 +586,12 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U
def do_^(that: UInt)(implicit sourceInfo: SourceInfo): UInt =
binop(sourceInfo, UInt(this.width.max(that.width)), BitXorOp, that)

/** @group SourceInfoTransformMacro */
def do_pad(that: Int)(implicit sourceInfo: SourceInfo): UInt = this.width match {
case KnownWidth(w) if w >= that => this
case _ => binop(sourceInfo, cloneTypeWidth(this.width.max(Width(that))), PadOp, that)
}

/** @group SourceInfoTransformMacro */
def do_unary_~(implicit sourceInfo: SourceInfo): UInt =
unop(sourceInfo, UInt(width = width), BitNotOp)
Expand Down Expand Up @@ -793,8 +793,7 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[S
}
}

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)

/** Unary negation (constant width)
*
Expand Down Expand Up @@ -940,6 +939,12 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[S
def do_^(that: SInt)(implicit sourceInfo: SourceInfo): SInt =
binop(sourceInfo, UInt(this.width.max(that.width)), BitXorOp, that).asSInt

/** @group SourceInfoTransformMacro */
def do_pad(that: Int)(implicit sourceInfo: SourceInfo): SInt = this.width match {
case KnownWidth(w) if w >= that => this
case _ => binop(sourceInfo, cloneTypeWidth(this.width.max(Width(that))), PadOp, that)
}

/** @group SourceInfoTransformMacro */
def do_unary_~(implicit sourceInfo: SourceInfo): SInt =
unop(sourceInfo, UInt(width = width), BitNotOp).asSInt
Expand Down Expand Up @@ -1037,7 +1042,7 @@ object Reset {
final class ResetType(private[chisel3] val width: Width = Width(1)) extends Element with Reset {
override def toString: String = stringAccessor("Reset")

def cloneType: this.type = Reset().asInstanceOf[this.type]
override protected def _cloneType: Data = Reset()

override def litOption = None

Expand Down Expand Up @@ -1081,7 +1086,7 @@ object AsyncReset {
sealed class AsyncReset(private[chisel3] val width: Width = Width(1)) extends Element with Reset {
override def toString: String = stringAccessor("AsyncReset")

def cloneType: this.type = AsyncReset().asInstanceOf[this.type]
override protected def _cloneType: Data = AsyncReset()

override def litOption = None

Expand Down Expand Up @@ -1134,9 +1139,9 @@ sealed class Bool() extends UInt(1.W) with Reset {
}
}

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]] */
Expand Down
5 changes: 3 additions & 2 deletions core/src/main/scala/chisel3/ChiselEnum.scala
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ abstract class EnumType(private[chisel3] val factory: ChiselEnum, selfAnnotating
}
}

override def cloneType: this.type = factory().asInstanceOf[this.type]
override protected def _cloneType: Data = factory()

private[chisel3] def compop(sourceInfo: SourceInfo, op: PrimOp, other: EnumType): Bool = {
requireIsHardware(this, "bits operated on")
Expand Down Expand Up @@ -386,7 +386,8 @@ private[chisel3] object EnumMacros {
// 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 protected def _cloneType: Data = new UnsafeEnum(width)
}
private object UnsafeEnum extends ChiselEnum

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/chisel3/Clock.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ object Clock {
sealed class Clock(private[chisel3] val width: Width = Width(1)) extends Element {
override def toString: String = stringAccessor("Clock")

def cloneType: this.type = Clock().asInstanceOf[this.type]
override protected def _cloneType: Data = Clock()

override def connect(that: Data)(implicit sourceInfo: SourceInfo): Unit =
that match {
Expand Down
55 changes: 34 additions & 21 deletions core/src/main/scala/chisel3/Data.scala
Original file line number Diff line number Diff line change
Expand Up @@ -672,28 +672,12 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc {
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
}
protected def _cloneType: Data

/** The "strong connect" operator.
*
Expand Down Expand Up @@ -892,6 +876,7 @@ object Data {
*
* @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]]
Expand Down Expand Up @@ -953,6 +938,33 @@ object Data {
}
}
}

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
}
}
}

trait WireFactory {
Expand Down Expand Up @@ -1124,7 +1136,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 protected def _cloneType: Data = DontCare

override def toString: String = "DontCare()"

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/chisel3/Module.scala
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ package internal {
private[chisel3] class ClonePorts(elts: (String, Data)*) extends Record {
val elements = 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(
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/chisel3/experimental/Analog.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,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 protected 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
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/scala/chisel3/experimental/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,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]
}
}
}
Expand Down
12 changes: 1 addition & 11 deletions core/src/main/scala/chisel3/properties/Property.scala
Original file line number Diff line number Diff line change
Expand Up @@ -264,18 +264,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 protected 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.
Expand Down