Skip to content

Commit 51b4acd

Browse files
committed
Merge branch 'master' into release
2 parents 10e42a4 + 8168a8e commit 51b4acd

File tree

11 files changed

+76
-46
lines changed

11 files changed

+76
-46
lines changed

build.sbt

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def javacOptionsVersion(scalaVersion: String): Seq[String] = {
3232

3333
lazy val commonSettings = Seq (
3434
organization := "edu.berkeley.cs",
35-
version := "3.0-SNAPSHOT_2017-09-27",
35+
version := "3.0-SNAPSHOT_2017-10-06",
3636
git.remoteRepo := "[email protected]:freechipsproject/chisel3.git",
3737
autoAPIMappings := true,
3838
scalaVersion := "2.11.11",
@@ -92,7 +92,7 @@ lazy val publishSettings = Seq (
9292
}
9393
)
9494

95-
val defaultVersions = Map("firrtl" -> "1.0-SNAPSHOT_2017-09-27")
95+
val defaultVersions = Map("firrtl" -> "1.0-SNAPSHOT_2017-10-06")
9696

9797
lazy val chiselSettings = Seq (
9898
name := "chisel3",

chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala

+1-7
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ trait VecFactory {
9393
if (compileOptions.declaredTypeMustBeUnbound) {
9494
requireIsChiselType(gen, "vec type")
9595
}
96-
new Vec(gen.chiselCloneType, n)
96+
new Vec(gen.cloneTypeFull, n)
9797
}
9898

9999
/** Truncate an index to implement modulo-power-of-2 addressing. */
@@ -580,9 +580,3 @@ class Bundle(implicit compileOptions: CompileOptions) extends Record {
580580
*/
581581
override def toPrintable: Printable = toPrintableHelper(elements.toList.reverse)
582582
}
583-
584-
private[core] object Bundle {
585-
val keywords = List("flip", "asInput", "asOutput", "cloneType", "chiselCloneType", "toBits",
586-
"widthOption", "signalName", "signalPathName", "signalParent", "signalComponent")
587-
}
588-

chiselFrontend/src/main/scala/chisel3/core/Data.scala

+46-22
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ object DataMirror {
8787
// Internal reflection-style APIs, subject to change and removal whenever.
8888
object internal {
8989
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+
}
9094
}
9195
}
9296

@@ -126,7 +130,7 @@ private[core] object cloneSupertype {
126130
throw new AssertionError(
127131
s"can't create $createdType with heterogeneous Bits types ${elt1.getClass} and ${elt2.getClass}")
128132
}).asInstanceOf[T] }
129-
model.chiselCloneType
133+
model.cloneTypeFull
130134
}
131135
else {
132136
for (elt <- elts.tail) {
@@ -135,11 +139,20 @@ private[core] object cloneSupertype {
135139
require(elt typeEquivalent elts.head,
136140
s"can't create $createdType with non-equivalent types ${elts.head} and ${elt}")
137141
}
138-
elts.head.chiselCloneType
142+
elts.head.cloneTypeFull
139143
}
140144
}
141145
}
142146

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+
143156
/**
144157
* Input, Output, and Flipped are used to define the directions of Module IOs.
145158
*
@@ -148,22 +161,31 @@ private[core] object cloneSupertype {
148161
* Thus, an error will be thrown if these are used on bound Data
149162
*/
150163
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]
153169
out.specifiedDirection = SpecifiedDirection.Input
154170
out
155171
}
156172
}
157173
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]
160179
out.specifiedDirection = SpecifiedDirection.Output
161180
out
162181
}
163182
}
164183
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]
167189
out.specifiedDirection = SpecifiedDirection.flip(source.specifiedDirection)
168190
out
169191
}
@@ -314,25 +336,27 @@ abstract class Data extends HasId {
314336
private[chisel3] def width: Width
315337
private[core] def legacyConnect(that: Data)(implicit sourceInfo: SourceInfo): Unit
316338

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.
318342
* 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+
*
321344
* @return a copy of the object.
322345
*/
323346
def cloneType: this.type
324347

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.
329352
*/
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
332355
// Only the top-level direction needs to be fixed up, cloneType should do the rest
333356
clone.specifiedDirection = specifiedDirection
334357
clone
335358
}
359+
336360
final def := (that: Data)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Unit = this.connect(that)(sourceInfo, connectionCompileOptions)
337361
final def <> (that: Data)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Unit = this.bulkConnect(that)(sourceInfo, connectionCompileOptions)
338362
def litArg(): Option[LitArg] = None
@@ -357,15 +381,15 @@ abstract class Data extends HasId {
357381
/** Does a reinterpret cast of the bits in this node into the format that provides.
358382
* Returns a new Wire of that type. Does not modify existing nodes.
359383
*
360-
* x.asTypeOf(that) performs the inverse operation of x = that.toBits.
384+
* x.asTypeOf(that) performs the inverse operation of x := that.toBits.
361385
*
362386
* @note bit widths are NOT checked, may pad or drop bits from input
363387
* @note that should have known widths
364388
*/
365389
def asTypeOf[T <: Data](that: T): T = macro SourceInfoTransform.thatArg
366390

367391
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)
369393
thatCloned.connectFromBits(this.asUInt())
370394
thatCloned
371395
}
@@ -395,7 +419,7 @@ trait WireFactory {
395419
if (compileOptions.declaredTypeMustBeUnbound) {
396420
requireIsChiselType(t, "wire type")
397421
}
398-
val x = t.chiselCloneType
422+
val x = t.cloneTypeFull
399423

400424
// Bind each element of x to being a Wire
401425
x.bind(WireBinding(Builder.forcedUserModule))
@@ -413,10 +437,10 @@ object WireInit {
413437
def apply[T <: Data](init: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
414438
val model = (init.litArg match {
415439
// 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
417441
case _ => init match {
418442
case init: Bits => init.cloneTypeWidth(Width())
419-
case init => init.chiselCloneType
443+
case init => init.cloneTypeFull
420444
}
421445
}).asInstanceOf[T]
422446
apply(model, init)

chiselFrontend/src/main/scala/chisel3/core/Mem.scala

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ object Mem {
2323
if (compileOptions.declaredTypeMustBeUnbound) {
2424
requireIsChiselType(t, "memory type")
2525
}
26-
val mt = t.chiselCloneType
26+
val mt = t.cloneTypeFull
2727
val mem = new Mem(mt, size)
2828
pushCommand(DefMemory(sourceInfo, mem, mt, size))
2929
mem
@@ -92,7 +92,7 @@ sealed abstract class MemBase[T <: Data](t: T, val length: Int) extends HasId {
9292

9393
val port = pushCommand(
9494
DefMemPort(sourceInfo,
95-
t.chiselCloneType, Node(this), dir, i.ref, Node(Builder.forcedClock))
95+
t.cloneTypeFull, Node(this), dir, i.ref, Node(Builder.forcedClock))
9696
).id
9797
// Bind each element of port to being a MemoryPort
9898
port.bind(MemoryPortBinding(Builder.forcedUserModule))
@@ -126,7 +126,7 @@ object SyncReadMem {
126126
if (compileOptions.declaredTypeMustBeUnbound) {
127127
requireIsChiselType(t, "memory type")
128128
}
129-
val mt = t.chiselCloneType
129+
val mt = t.cloneTypeFull
130130
val mem = new SyncReadMem(mt, size)
131131
pushCommand(DefSeqMemory(sourceInfo, mem, mt, size))
132132
mem

chiselFrontend/src/main/scala/chisel3/core/Reg.scala

+6-6
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ object Reg {
1919
if (compileOptions.declaredTypeMustBeUnbound) {
2020
requireIsChiselType(t, "reg type")
2121
}
22-
val reg = t.chiselCloneType
22+
val reg = t.cloneTypeFull
2323
val clock = Node(Builder.forcedClock)
2424

2525
reg.bind(RegBinding(Builder.forcedUserModule))
@@ -36,7 +36,7 @@ object RegNext {
3636
def apply[T <: Data](next: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
3737
val model = (next match {
3838
case next: Bits => next.cloneTypeWidth(Width())
39-
case next => next.chiselCloneType
39+
case next => next.cloneTypeFull
4040
}).asInstanceOf[T]
4141
val reg = Reg(model)
4242

@@ -53,7 +53,7 @@ object RegNext {
5353
def apply[T <: Data](next: T, init: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
5454
val model = (next match {
5555
case next: Bits => next.cloneTypeWidth(Width())
56-
case next => next.chiselCloneType
56+
case next => next.cloneTypeFull
5757
}).asInstanceOf[T]
5858
val reg = RegInit(model, init) // TODO: this makes NO sense
5959

@@ -71,10 +71,10 @@ object RegInit {
7171
def apply[T <: Data](init: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
7272
val model = (init.litArg match {
7373
// For e.g. Reg(init=UInt(0, k)), fix the Reg's width to k
74-
case Some(lit) if lit.forcedWidth => init.chiselCloneType
74+
case Some(lit) if lit.forcedWidth => init.cloneTypeFull
7575
case _ => init match {
7676
case init: Bits => init.cloneTypeWidth(Width())
77-
case init => init.chiselCloneType
77+
case init => init.cloneTypeFull
7878
}
7979
}).asInstanceOf[T]
8080
RegInit(model, init)
@@ -86,7 +86,7 @@ object RegInit {
8686
if (compileOptions.declaredTypeMustBeUnbound) {
8787
requireIsChiselType(t, "reg type")
8888
}
89-
val reg = t.chiselCloneType
89+
val reg = t.cloneTypeFull
9090
val clock = Node(Builder.forcedClock)
9191
val reset = Node(Builder.forcedReset)
9292

src/main/scala/chisel3/compatibility.scala

+6
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ package object Chisel { // scalastyle:ignore package.object.name
4242
}
4343
}
4444
}
45+
implicit class cloneTypeable[T <: Data](val target: T) extends AnyVal {
46+
import chisel3.core.DataMirror
47+
def chiselCloneType: T = {
48+
DataMirror.internal.chiselTypeClone(target).asInstanceOf[T]
49+
}
50+
}
4551

4652
type ChiselException = chisel3.internal.ChiselException
4753

src/main/scala/chisel3/package.scala

+8
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package object chisel3 { // scalastyle:ignore package.object.name
1919
val Input = chisel3.core.Input
2020
val Output = chisel3.core.Output
2121
val Flipped = chisel3.core.Flipped
22+
val chiselTypeOf = chisel3.core.chiselTypeOf
2223

2324
type Data = chisel3.core.Data
2425
object Wire extends chisel3.core.WireFactory {
@@ -56,6 +57,13 @@ package object chisel3 { // scalastyle:ignore package.object.name
5657
}
5758
}
5859

60+
implicit class cloneTypeable[T <: Data](val target: T) extends AnyVal {
61+
@deprecated("chiselCloneType is deprecated, use chiselTypeOf(...) to get the Chisel Type of a hardware object", "chisel3")
62+
def chiselCloneType: T = {
63+
target.cloneTypeFull.asInstanceOf[T]
64+
}
65+
}
66+
5967
type Aggregate = chisel3.core.Aggregate
6068
object Vec extends chisel3.core.VecFactory {
6169
import scala.language.experimental.macros

src/main/scala/chisel3/util/Decoupled.scala

+1-2
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,6 @@ class Queue[T <: Data](gen: T,
202202
gen
203203
} else {
204204
if (DataMirror.internal.isSynthesizable(gen)) {
205-
println("WARNING: gen in new Queue(gen, ...) must be a Chisel type, not hardware")
206205
gen.chiselCloneType
207206
} else {
208207
gen
@@ -282,7 +281,7 @@ object Queue
282281
entries: Int = 2,
283282
pipe: Boolean = false,
284283
flow: Boolean = false): DecoupledIO[T] = {
285-
val q = Module(new Queue(enq.bits.cloneType, entries, pipe, flow))
284+
val q = Module(new Queue(chiselTypeOf(enq.bits), entries, pipe, flow))
286285
q.io.enq.valid := enq.valid // not using <> so that override is allowed
287286
q.io.enq.bits := enq.bits
288287
enq.ready := q.io.enq.ready

src/main/scala/chisel3/util/Reg.scala

+1-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ object RegEnable {
88
/** Returns a register with the specified next, update enable gate, and no reset initialization.
99
*/
1010
def apply[T <: Data](next: T, enable: Bool): T = {
11-
val clonedNext = next.chiselCloneType
12-
val r = Reg(clonedNext)
11+
val r = Reg(chiselTypeOf(next))
1312
when (enable) { r := next }
1413
r
1514
}

src/test/scala/chiselTests/Module.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class ModuleVecTester(c: ModuleVec) extends Tester(c) {
4141

4242
class ModuleWire extends Module {
4343
val io = IO(new SimpleIO)
44-
val inc = Wire(Module(new PlusOne).io.chiselCloneType)
44+
val inc = Wire(chiselTypeOf(Module(new PlusOne).io))
4545
inc.in := io.in
4646
io.out := inc.out
4747
}

src/test/scala/chiselTests/Vec.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ class ZeroEntryVecTester extends BasicTester {
145145
require(bundleWithZeroEntryVec.asUInt.getWidth == 1)
146146

147147
val m = Module(new Module {
148-
val io = IO(Output(bundleWithZeroEntryVec.cloneType))
148+
val io = IO(Output(bundleWithZeroEntryVec))
149149
})
150150
WireInit(m.io.bar)
151151

0 commit comments

Comments
 (0)