From 080f5bab34f9d97cda06a22724bb538e2d7ca6c6 Mon Sep 17 00:00:00 2001 From: ducky Date: Wed, 26 Jul 2017 16:07:56 -0700 Subject: [PATCH 1/5] introduce chisel3.chiselTypeOf, make cloneType return Data --- .../src/main/scala/chisel3/core/Data.scala | 30 ++++++++++++++----- src/main/scala/chisel3/package.scala | 1 + src/main/scala/chisel3/util/Decoupled.scala | 2 +- src/test/scala/chiselTests/Vec.scala | 2 +- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala index 74e41895a05..1b80f840866 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala @@ -137,6 +137,15 @@ private[core] object cloneSupertype { } } +/** Returns the chisel type of a hardware object, allowing other hardware to be constructed from it. + */ +object chiselTypeOf { + def apply[T <: Data](target: T): T = { + requireIsHardware(target) + target.chiselCloneType.asInstanceOf[T] + } +} + /** * Input, Output, and Flipped are used to define the directions of Module IOs. * @@ -146,21 +155,24 @@ private[core] object cloneSupertype { */ object Input { def apply[T<:Data](source: T): T = { - val out = source.cloneType + requireIsChiselType(source) + val out = source.cloneType.asInstanceOf[T] out.userDirection = UserDirection.Input out } } object Output { def apply[T<:Data](source: T): T = { - val out = source.cloneType + requireIsChiselType(source) + val out = source.cloneType.asInstanceOf[T] out.userDirection = UserDirection.Output out } } object Flipped { def apply[T<:Data](source: T): T = { - val out = source.cloneType + requireIsChiselType(source) + val out = source.cloneType.asInstanceOf[T] out.userDirection = UserDirection.flip(source.userDirection) out } @@ -304,19 +316,23 @@ abstract class Data extends HasId { /** cloneType must be defined for any Chisel object extending Data. * It is responsible for constructing a basic copy of the object being cloned. - * If cloneType needs to recursively clone elements of an object, it should call - * the cloneType methods on those elements. + * + * Internal API, users should look at chisel3.chiselTypeOf(...). + * * @return a copy of the object. */ - def cloneType: this.type + def cloneType: Data /** chiselCloneType is called at the top-level of a clone chain. * It calls the client's cloneType() method to construct a basic copy of the object being cloned, * then performs any fixups required to reconstruct the appropriate core state of the cloned object. + * + * Internal API, users should look at chisel3.chiselTypeOf(...). + * * @return a copy of the object with appropriate core state. */ def chiselCloneType: this.type = { - val clone = this.cloneType // get a fresh object, without bindings + val clone = this.cloneType.asInstanceOf[this.type] // get a fresh object, without bindings // Only the top-level direction needs to be fixed up, cloneType should do the rest clone.userDirection = userDirection clone diff --git a/src/main/scala/chisel3/package.scala b/src/main/scala/chisel3/package.scala index d2f11f3db86..8ad0c715f80 100644 --- a/src/main/scala/chisel3/package.scala +++ b/src/main/scala/chisel3/package.scala @@ -17,6 +17,7 @@ package object chisel3 { // scalastyle:ignore package.object.name val Input = chisel3.core.Input val Output = chisel3.core.Output val Flipped = chisel3.core.Flipped + val chiselTypeOf = chisel3.core.chiselTypeOf type Data = chisel3.core.Data val Wire = chisel3.core.Wire diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index b9e1e7ede1b..8ff424f5ae5 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -269,7 +269,7 @@ object Queue entries: Int = 2, pipe: Boolean = false, flow: Boolean = false): DecoupledIO[T] = { - val q = Module(new Queue(enq.bits.cloneType, entries, pipe, flow)) + val q = Module(new Queue(chiselTypeOf(enq.bits), entries, pipe, flow)) q.io.enq.valid := enq.valid // not using <> so that override is allowed q.io.enq.bits := enq.bits enq.ready := q.io.enq.ready diff --git a/src/test/scala/chiselTests/Vec.scala b/src/test/scala/chiselTests/Vec.scala index df2d6ec009a..f214d958b49 100644 --- a/src/test/scala/chiselTests/Vec.scala +++ b/src/test/scala/chiselTests/Vec.scala @@ -145,7 +145,7 @@ class ZeroEntryVecTester extends BasicTester { require(bundleWithZeroEntryVec.asUInt.getWidth == 1) val m = Module(new Module { - val io = IO(Output(bundleWithZeroEntryVec.cloneType)) + val io = IO(Output(bundleWithZeroEntryVec)) }) Wire(init = m.io.bar) From c4299b14342c3b976f66df5ba4a0f55c1eea3b04 Mon Sep 17 00:00:00 2001 From: ducky Date: Thu, 27 Jul 2017 17:28:30 -0700 Subject: [PATCH 2/5] chiselCloneType & friends now an internal API --- .../main/scala/chisel3/core/Aggregate.scala | 10 +--- .../src/main/scala/chisel3/core/Data.scala | 54 ++++++++++--------- .../src/main/scala/chisel3/core/Mem.scala | 6 +-- .../src/main/scala/chisel3/core/Reg.scala | 12 ++--- src/main/scala/chisel3/compatibility.scala | 5 ++ src/main/scala/chisel3/package.scala | 7 +++ src/test/scala/chiselTests/Module.scala | 2 +- 7 files changed, 53 insertions(+), 43 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 701cf892bb2..a788a6b30eb 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -89,10 +89,10 @@ object Vec { * * @note elements are NOT assigned by default and have no value */ - def apply[T <: Data](n: Int, gen: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = new Vec(gen.chiselCloneType, n) + def apply[T <: Data](n: Int, gen: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = new Vec(gen.cloneTypeFull, n) @deprecated("Vec argument order should be size, t; this will be removed by the official release", "chisel3") - def apply[T <: Data](gen: T, n: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = new Vec(gen.chiselCloneType, n) + def apply[T <: Data](gen: T, n: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = new Vec(gen.cloneTypeFull, n) /** Creates a new [[Vec]] composed of elements of the input Seq of [[Data]] * nodes. @@ -588,9 +588,3 @@ class Bundle(implicit compileOptions: CompileOptions) extends Record { */ override def toPrintable: Printable = toPrintableHelper(elements.toList.reverse) } - -private[core] object Bundle { - val keywords = List("flip", "asInput", "asOutput", "cloneType", "chiselCloneType", "toBits", - "widthOption", "signalName", "signalPathName", "signalParent", "signalComponent") -} - diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala index 1b80f840866..3ff2fd69849 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala @@ -123,7 +123,7 @@ private[core] object cloneSupertype { throw new AssertionError( s"can't create $createdType with heterogeneous Bits types ${elt1.getClass} and ${elt2.getClass}") }).asInstanceOf[T] } - model.chiselCloneType + model.cloneTypeFull } else { for (elt <- elts.tail) { @@ -132,7 +132,7 @@ private[core] object cloneSupertype { require(elt typeEquivalent elts.head, s"can't create $createdType with non-equivalent types ${elts.head} and ${elt}") } - elts.head.chiselCloneType + elts.head.cloneTypeFull } } } @@ -142,7 +142,7 @@ private[core] object cloneSupertype { object chiselTypeOf { def apply[T <: Data](target: T): T = { requireIsHardware(target) - target.chiselCloneType.asInstanceOf[T] + target.cloneTypeFull.asInstanceOf[T] } } @@ -154,24 +154,30 @@ object chiselTypeOf { * Thus, an error will be thrown if these are used on bound Data */ object Input { - def apply[T<:Data](source: T): T = { - requireIsChiselType(source) + def apply[T<:Data](source: T)(implicit compileOptions: CompileOptions): T = { + if (compileOptions.checkSynthesizable) { + requireIsChiselType(source) + } val out = source.cloneType.asInstanceOf[T] out.userDirection = UserDirection.Input out } } object Output { - def apply[T<:Data](source: T): T = { - requireIsChiselType(source) + def apply[T<:Data](source: T)(implicit compileOptions: CompileOptions): T = { + if (compileOptions.checkSynthesizable) { + requireIsChiselType(source) + } val out = source.cloneType.asInstanceOf[T] out.userDirection = UserDirection.Output out } } object Flipped { - def apply[T<:Data](source: T): T = { - requireIsChiselType(source) + def apply[T<:Data](source: T)(implicit compileOptions: CompileOptions): T = { + if (compileOptions.checkSynthesizable) { + requireIsChiselType(source) + } val out = source.cloneType.asInstanceOf[T] out.userDirection = UserDirection.flip(source.userDirection) out @@ -314,29 +320,27 @@ abstract class Data extends HasId { private[chisel3] def width: Width private[core] def legacyConnect(that: Data)(implicit sourceInfo: SourceInfo): Unit - /** cloneType must be defined for any Chisel object extending Data. - * It is responsible for constructing a basic copy of the object being cloned. + /** Internal API; Chisel users should look at chisel3.chiselTypeOf(...). * - * Internal API, 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: Data + def cloneType: this.type - /** chiselCloneType is called at the top-level of a clone chain. - * It calls the client's cloneType() method to construct a basic copy of the object being cloned, - * then performs any fixups required to reconstruct the appropriate core state of the cloned object. - * - * Internal API, users should look at chisel3.chiselTypeOf(...). + /** Internal API; Chisel users should look at chisel3.chiselTypeOf(...). * - * @return a copy of the object with appropriate core state. + * Returns a copy of this data type, with hardware bindings (if any) removed. + * Directionality data is still preserved. */ - def chiselCloneType: this.type = { + def cloneTypeFull: this.type = { val clone = this.cloneType.asInstanceOf[this.type] // get a fresh object, without bindings // Only the top-level direction needs to be fixed up, cloneType should do the rest clone.userDirection = userDirection clone } + final def := (that: Data)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Unit = this.connect(that)(sourceInfo, connectionCompileOptions) final def <> (that: Data)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Unit = this.bulkConnect(that)(sourceInfo, connectionCompileOptions) def litArg(): Option[LitArg] = None @@ -361,7 +365,7 @@ abstract class Data extends HasId { /** 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. + * 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 @@ -369,7 +373,7 @@ abstract class Data extends HasId { def asTypeOf[T <: Data](that: T): T = macro SourceInfoTransform.thatArg def do_asTypeOf[T <: Data](that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { - val thatCloned = Wire(that.chiselCloneType) + val thatCloned = Wire(that.cloneTypeFull) thatCloned.connectFromBits(this.asUInt()) thatCloned } @@ -399,10 +403,10 @@ object Wire { def apply[T <: Data](dummy: Int = 0, init: T)(implicit compileOptions: CompileOptions): T = { val model = (init.litArg match { // For e.g. Wire(init=0.U(k.W)), fix the Reg's width to k - case Some(lit) if lit.forcedWidth => init.chiselCloneType + case Some(lit) if lit.forcedWidth => init.cloneTypeFull case _ => init match { case init: Bits => init.cloneTypeWidth(Width()) - case init => init.chiselCloneType + case init => init.cloneTypeFull } }).asInstanceOf[T] apply(model, init) @@ -418,7 +422,7 @@ object Wire { } def apply[T <: Data](t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { - val x = t.chiselCloneType + val x = t.cloneTypeFull // Bind each element of x to being a Wire x.bind(WireBinding(Builder.forcedUserModule)) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Mem.scala b/chiselFrontend/src/main/scala/chisel3/core/Mem.scala index 47d48061a0e..cc14c9e79f2 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Mem.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Mem.scala @@ -20,7 +20,7 @@ object Mem { */ def apply[T <: Data](size: Int, t: T): Mem[T] = macro MemTransform.apply[T] def do_apply[T <: Data](size: Int, t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Mem[T] = { - val mt = t.chiselCloneType + val mt = t.cloneTypeFull val mem = new Mem(mt, size) pushCommand(DefMemory(sourceInfo, mem, mt, size)) @@ -90,7 +90,7 @@ sealed abstract class MemBase[T <: Data](t: T, val length: Int) extends HasId { val port = pushCommand( DefMemPort(sourceInfo, - t.chiselCloneType, Node(this), dir, i.ref, Node(Builder.forcedClock)) + t.cloneTypeFull, Node(this), dir, i.ref, Node(Builder.forcedClock)) ).id // Bind each element of port to being a MemoryPort port.bind(MemoryPortBinding(Builder.forcedUserModule)) @@ -121,7 +121,7 @@ object SyncReadMem { def apply[T <: Data](size: Int, t: T): SyncReadMem[T] = macro MemTransform.apply[T] def do_apply[T <: Data](size: Int, t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SyncReadMem[T] = { - val mt = t.chiselCloneType + val mt = t.cloneTypeFull val mem = new SyncReadMem(mt, size) pushCommand(DefSeqMemory(sourceInfo, mem, mt, size)) mem diff --git a/chiselFrontend/src/main/scala/chisel3/core/Reg.scala b/chiselFrontend/src/main/scala/chisel3/core/Reg.scala index 3fdb3398a03..a48fbdf1193 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Reg.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Reg.scala @@ -19,7 +19,7 @@ object Reg { if (compileOptions.declaredTypeMustBeUnbound) { requireIsChiselType(t, "reg type") } - val reg = t.chiselCloneType + val reg = t.cloneTypeFull val clock = Node(Builder.forcedClock) reg.bind(RegBinding(Builder.forcedUserModule)) @@ -36,7 +36,7 @@ object RegNext { def apply[T <: Data](next: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { val model = (next match { case next: Bits => next.cloneTypeWidth(Width()) - case next => next.chiselCloneType + case next => next.cloneTypeFull }).asInstanceOf[T] val reg = Reg(model) @@ -52,7 +52,7 @@ object RegNext { def apply[T <: Data](next: T, init: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { val model = (next match { case next: Bits => next.cloneTypeWidth(Width()) - case next => next.chiselCloneType + case next => next.cloneTypeFull }).asInstanceOf[T] val reg = RegInit(model, init) // TODO: this makes NO sense @@ -69,10 +69,10 @@ object RegInit { def apply[T <: Data](init: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { val model = (init.litArg match { // For e.g. Reg(init=UInt(0, k)), fix the Reg's width to k - case Some(lit) if lit.forcedWidth => init.chiselCloneType + case Some(lit) if lit.forcedWidth => init.cloneTypeFull case _ => init match { case init: Bits => init.cloneTypeWidth(Width()) - case init => init.chiselCloneType + case init => init.cloneTypeFull } }).asInstanceOf[T] RegInit(model, init) @@ -84,7 +84,7 @@ object RegInit { if (compileOptions.declaredTypeMustBeUnbound) { requireIsChiselType(t, "reg type") } - val reg = t.chiselCloneType + val reg = t.cloneTypeFull val clock = Node(Builder.forcedClock) val reset = Node(Builder.forcedReset) diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala index 4223d63b7db..92341e6fa84 100644 --- a/src/main/scala/chisel3/compatibility.scala +++ b/src/main/scala/chisel3/compatibility.scala @@ -51,6 +51,11 @@ package object Chisel { // scalastyle:ignore package.object.name } } + implicit class cloneTypeable[T<:Data](val target: T) extends AnyVal { + def chiselCloneType: target.type = { + target.cloneTypeFull.asInstanceOf[target.type] + } + } type ChiselException = chisel3.internal.ChiselException diff --git a/src/main/scala/chisel3/package.scala b/src/main/scala/chisel3/package.scala index 8ad0c715f80..918c586ce25 100644 --- a/src/main/scala/chisel3/package.scala +++ b/src/main/scala/chisel3/package.scala @@ -43,6 +43,13 @@ package object chisel3 { // scalastyle:ignore package.object.name } } + implicit class cloneTypeable[T<:Data](val target: T) extends AnyVal { + @deprecated("chiselCloneType is deprecated, use chiselTypeOf(...) to get the Chisel Type of a hardware object", "chisel3") + def chiselCloneType: target.type = { + target.cloneTypeFull.asInstanceOf[target.type] + } + } + type Aggregate = chisel3.core.Aggregate val Vec = chisel3.core.Vec type Vec[T <: Data] = chisel3.core.Vec[T] diff --git a/src/test/scala/chiselTests/Module.scala b/src/test/scala/chiselTests/Module.scala index 2ae8fa5edab..f3a7335cc3d 100644 --- a/src/test/scala/chiselTests/Module.scala +++ b/src/test/scala/chiselTests/Module.scala @@ -41,7 +41,7 @@ class ModuleVecTester(c: ModuleVec) extends Tester(c) { class ModuleWire extends Module { val io = IO(new SimpleIO) - val inc = Wire(Module(new PlusOne).io.chiselCloneType) + val inc = Wire(chiselTypeOf(Module(new PlusOne).io)) inc.in := io.in io.out := inc.out } From f4ca70bde1a51ff6740b28402b494542d27ca5b9 Mon Sep 17 00:00:00 2001 From: ducky Date: Mon, 31 Jul 2017 14:55:38 -0700 Subject: [PATCH 3/5] Make cloneTypeFull package-private --- chiselFrontend/src/main/scala/chisel3/core/Data.scala | 9 ++++++++- src/main/scala/chisel3/compatibility.scala | 3 ++- src/main/scala/chisel3/util/Reg.scala | 3 +-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala index 3ff2fd69849..aa2ba533e57 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala @@ -85,6 +85,13 @@ object DataMirror { } // TODO: really not a reflection-style API, but a workaround for dir in the compatibility package def isSynthesizable(target: Data) = target.hasBinding + + object internal { + // For those odd cases where you need to care about object reference and uniqueness + def chiselTypeClone[T<:Data](target: Data): T = { + target.cloneTypeFull.asInstanceOf[T] + } + } } /** Creates a clone of the super-type of the input elements. Super-type is defined as: @@ -334,7 +341,7 @@ abstract class Data extends HasId { * Returns a copy of this data type, with hardware bindings (if any) removed. * Directionality data is still preserved. */ - def cloneTypeFull: this.type = { + private[chisel3] def cloneTypeFull: this.type = { val clone = this.cloneType.asInstanceOf[this.type] // get a fresh object, without bindings // Only the top-level direction needs to be fixed up, cloneType should do the rest clone.userDirection = userDirection diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala index 92341e6fa84..b2dd0816fd4 100644 --- a/src/main/scala/chisel3/compatibility.scala +++ b/src/main/scala/chisel3/compatibility.scala @@ -52,8 +52,9 @@ package object Chisel { // scalastyle:ignore package.object.name } } implicit class cloneTypeable[T<:Data](val target: T) extends AnyVal { + import chisel3.core.DataMirror def chiselCloneType: target.type = { - target.cloneTypeFull.asInstanceOf[target.type] + DataMirror.internal.chiselTypeClone(target).asInstanceOf[target.type] } } diff --git a/src/main/scala/chisel3/util/Reg.scala b/src/main/scala/chisel3/util/Reg.scala index 34c4d6d8c04..34d22a07edb 100644 --- a/src/main/scala/chisel3/util/Reg.scala +++ b/src/main/scala/chisel3/util/Reg.scala @@ -8,8 +8,7 @@ object RegEnable { /** Returns a register with the specified next, update enable gate, and no reset initialization. */ def apply[T <: Data](next: T, enable: Bool): T = { - val clonedNext = next.chiselCloneType - val r = Reg(clonedNext) + val r = Reg(chiselTypeOf(next)) when (enable) { r := next } r } From edd11b0bd156c5a1c59ab100c89837b419d27885 Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Wed, 4 Oct 2017 15:02:54 -0700 Subject: [PATCH 4/5] Change chiselCloneType and IO(...) to return parameterized type --- chiselFrontend/src/main/scala/chisel3/core/Module.scala | 2 +- src/main/scala/chisel3/compatibility.scala | 6 +++--- src/main/scala/chisel3/package.scala | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Module.scala b/chiselFrontend/src/main/scala/chisel3/core/Module.scala index 0e919d3c776..1b25963f56d 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Module.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Module.scala @@ -217,7 +217,7 @@ abstract class BaseModule extends HasId { * TODO(twigg): Specifically walk the Data definition to call out which nodes * are problematic. */ - protected def IO[T<:Data](iodef: T): iodef.type = { + protected def IO[T<:Data](iodef: T): T = { require(!_closed, "Can't add more ports after module close") requireIsChiselType(iodef, "io type") diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala index 0a7749c9a14..d65196d97e7 100644 --- a/src/main/scala/chisel3/compatibility.scala +++ b/src/main/scala/chisel3/compatibility.scala @@ -42,10 +42,10 @@ package object Chisel { // scalastyle:ignore package.object.name } } } - implicit class cloneTypeable[T<:Data](val target: T) extends AnyVal { + implicit class cloneTypeable[T <: Data](val target: T) extends AnyVal { import chisel3.core.DataMirror - def chiselCloneType: target.type = { - DataMirror.internal.chiselTypeClone(target).asInstanceOf[target.type] + def chiselCloneType: T = { + DataMirror.internal.chiselTypeClone(target).asInstanceOf[T] } } diff --git a/src/main/scala/chisel3/package.scala b/src/main/scala/chisel3/package.scala index 7193917c301..d335f1f101a 100644 --- a/src/main/scala/chisel3/package.scala +++ b/src/main/scala/chisel3/package.scala @@ -57,10 +57,10 @@ package object chisel3 { // scalastyle:ignore package.object.name } } - implicit class cloneTypeable[T<:Data](val target: T) extends AnyVal { + implicit class cloneTypeable[T <: Data](val target: T) extends AnyVal { @deprecated("chiselCloneType is deprecated, use chiselTypeOf(...) to get the Chisel Type of a hardware object", "chisel3") - def chiselCloneType: target.type = { - target.cloneTypeFull.asInstanceOf[target.type] + def chiselCloneType: T = { + target.cloneTypeFull.asInstanceOf[T] } } From e74b35ce4072b8537065f3b767aef4a1ee3227c5 Mon Sep 17 00:00:00 2001 From: ducky Date: Thu, 5 Oct 2017 11:59:17 -0700 Subject: [PATCH 5/5] Revert iodef change --- chiselFrontend/src/main/scala/chisel3/core/Module.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Module.scala b/chiselFrontend/src/main/scala/chisel3/core/Module.scala index 1b25963f56d..0e919d3c776 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Module.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Module.scala @@ -217,7 +217,7 @@ abstract class BaseModule extends HasId { * TODO(twigg): Specifically walk the Data definition to call out which nodes * are problematic. */ - protected def IO[T<:Data](iodef: T): T = { + protected def IO[T<:Data](iodef: T): iodef.type = { require(!_closed, "Can't add more ports after module close") requireIsChiselType(iodef, "io type")