@@ -87,6 +87,10 @@ object DataMirror {
87
87
// Internal reflection-style APIs, subject to change and removal whenever.
88
88
object internal {
89
89
def isSynthesizable (target : Data ) = target.hasBinding
90
+ // For those odd cases where you need to care about object reference and uniqueness
91
+ def chiselTypeClone [T <: Data ](target : Data ): T = {
92
+ target.cloneTypeFull.asInstanceOf [T ]
93
+ }
90
94
}
91
95
}
92
96
@@ -126,7 +130,7 @@ private[core] object cloneSupertype {
126
130
throw new AssertionError (
127
131
s " can't create $createdType with heterogeneous Bits types ${elt1.getClass} and ${elt2.getClass}" )
128
132
}).asInstanceOf [T ] }
129
- model.chiselCloneType
133
+ model.cloneTypeFull
130
134
}
131
135
else {
132
136
for (elt <- elts.tail) {
@@ -135,11 +139,20 @@ private[core] object cloneSupertype {
135
139
require(elt typeEquivalent elts.head,
136
140
s " can't create $createdType with non-equivalent types ${elts.head} and ${elt}" )
137
141
}
138
- elts.head.chiselCloneType
142
+ elts.head.cloneTypeFull
139
143
}
140
144
}
141
145
}
142
146
147
+ /** Returns the chisel type of a hardware object, allowing other hardware to be constructed from it.
148
+ */
149
+ object chiselTypeOf {
150
+ def apply [T <: Data ](target : T ): T = {
151
+ requireIsHardware(target)
152
+ target.cloneTypeFull.asInstanceOf [T ]
153
+ }
154
+ }
155
+
143
156
/**
144
157
* Input, Output, and Flipped are used to define the directions of Module IOs.
145
158
*
@@ -148,22 +161,31 @@ private[core] object cloneSupertype {
148
161
* Thus, an error will be thrown if these are used on bound Data
149
162
*/
150
163
object Input {
151
- def apply [T <: Data ](source : T ): T = {
152
- val out = source.cloneType
164
+ def apply [T <: Data ](source : T )(implicit compileOptions : CompileOptions ): T = {
165
+ if (compileOptions.checkSynthesizable) {
166
+ requireIsChiselType(source)
167
+ }
168
+ val out = source.cloneType.asInstanceOf [T ]
153
169
out.specifiedDirection = SpecifiedDirection .Input
154
170
out
155
171
}
156
172
}
157
173
object Output {
158
- def apply [T <: Data ](source : T ): T = {
159
- val out = source.cloneType
174
+ def apply [T <: Data ](source : T )(implicit compileOptions : CompileOptions ): T = {
175
+ if (compileOptions.checkSynthesizable) {
176
+ requireIsChiselType(source)
177
+ }
178
+ val out = source.cloneType.asInstanceOf [T ]
160
179
out.specifiedDirection = SpecifiedDirection .Output
161
180
out
162
181
}
163
182
}
164
183
object Flipped {
165
- def apply [T <: Data ](source : T ): T = {
166
- val out = source.cloneType
184
+ def apply [T <: Data ](source : T )(implicit compileOptions : CompileOptions ): T = {
185
+ if (compileOptions.checkSynthesizable) {
186
+ requireIsChiselType(source)
187
+ }
188
+ val out = source.cloneType.asInstanceOf [T ]
167
189
out.specifiedDirection = SpecifiedDirection .flip(source.specifiedDirection)
168
190
out
169
191
}
@@ -314,25 +336,27 @@ abstract class Data extends HasId {
314
336
private [chisel3] def width : Width
315
337
private [core] def legacyConnect (that : Data )(implicit sourceInfo : SourceInfo ): Unit
316
338
317
- /** cloneType must be defined for any Chisel object extending Data.
339
+ /** Internal API; Chisel users should look at chisel3.chiselTypeOf(...).
340
+ *
341
+ * cloneType must be defined for any Chisel object extending Data.
318
342
* It is responsible for constructing a basic copy of the object being cloned.
319
- * If cloneType needs to recursively clone elements of an object, it should call
320
- * the cloneType methods on those elements.
343
+ *
321
344
* @return a copy of the object.
322
345
*/
323
346
def cloneType : this .type
324
347
325
- /** chiselCloneType is called at the top-level of a clone chain .
326
- * It calls the client's cloneType() method to construct a basic copy of the object being cloned,
327
- * then performs any fixups required to reconstruct the appropriate core state of the cloned object .
328
- * @return a copy of the object with appropriate core state .
348
+ /** Internal API; Chisel users should look at chisel3.chiselTypeOf(...) .
349
+ *
350
+ * Returns a copy of this data type, with hardware bindings (if any) removed .
351
+ * Directionality data is still preserved .
329
352
*/
330
- def chiselCloneType : this .type = {
331
- val clone = this .cloneType // get a fresh object, without bindings
353
+ private [chisel3] def cloneTypeFull : this .type = {
354
+ val clone = this .cloneType. asInstanceOf [ this . type ] // get a fresh object, without bindings
332
355
// Only the top-level direction needs to be fixed up, cloneType should do the rest
333
356
clone.specifiedDirection = specifiedDirection
334
357
clone
335
358
}
359
+
336
360
final def := (that : Data )(implicit sourceInfo : SourceInfo , connectionCompileOptions : CompileOptions ): Unit = this .connect(that)(sourceInfo, connectionCompileOptions)
337
361
final def <> (that : Data )(implicit sourceInfo : SourceInfo , connectionCompileOptions : CompileOptions ): Unit = this .bulkConnect(that)(sourceInfo, connectionCompileOptions)
338
362
def litArg (): Option [LitArg ] = None
@@ -357,15 +381,15 @@ abstract class Data extends HasId {
357
381
/** Does a reinterpret cast of the bits in this node into the format that provides.
358
382
* Returns a new Wire of that type. Does not modify existing nodes.
359
383
*
360
- * x.asTypeOf(that) performs the inverse operation of x = that.toBits.
384
+ * x.asTypeOf(that) performs the inverse operation of x : = that.toBits.
361
385
*
362
386
* @note bit widths are NOT checked, may pad or drop bits from input
363
387
* @note that should have known widths
364
388
*/
365
389
def asTypeOf [T <: Data ](that : T ): T = macro SourceInfoTransform .thatArg
366
390
367
391
def do_asTypeOf [T <: Data ](that : T )(implicit sourceInfo : SourceInfo , compileOptions : CompileOptions ): T = {
368
- val thatCloned = Wire (that.chiselCloneType )
392
+ val thatCloned = Wire (that.cloneTypeFull )
369
393
thatCloned.connectFromBits(this .asUInt())
370
394
thatCloned
371
395
}
@@ -395,7 +419,7 @@ trait WireFactory {
395
419
if (compileOptions.declaredTypeMustBeUnbound) {
396
420
requireIsChiselType(t, " wire type" )
397
421
}
398
- val x = t.chiselCloneType
422
+ val x = t.cloneTypeFull
399
423
400
424
// Bind each element of x to being a Wire
401
425
x.bind(WireBinding (Builder .forcedUserModule))
@@ -413,10 +437,10 @@ object WireInit {
413
437
def apply [T <: Data ](init : T )(implicit sourceInfo : SourceInfo , compileOptions : CompileOptions ): T = {
414
438
val model = (init.litArg match {
415
439
// For e.g. Wire(init=0.U(k.W)), fix the Reg's width to k
416
- case Some (lit) if lit.forcedWidth => init.chiselCloneType
440
+ case Some (lit) if lit.forcedWidth => init.cloneTypeFull
417
441
case _ => init match {
418
442
case init : Bits => init.cloneTypeWidth(Width ())
419
- case init => init.chiselCloneType
443
+ case init => init.cloneTypeFull
420
444
}
421
445
}).asInstanceOf [T ]
422
446
apply(model, init)
0 commit comments