Skip to content

Commit 5f2e70c

Browse files
authored
Change Data._fromUInt to protected (#4782)
* Update RecordSpec to use FileCheck * Change Data._fromUInt to protected This enables external libraries like FixedPoint to override it. This is not an ideal API, but it works until we have a better way to do this.
1 parent 0c2c05c commit 5f2e70c

File tree

8 files changed

+60
-23
lines changed

8 files changed

+60
-23
lines changed

core/src/main/scala/chisel3/AggregateImpl.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ private[chisel3] trait AggregateImpl extends Data { thiz: Aggregate =>
138138
clone
139139
}
140140

141-
override private[chisel3] def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data = {
141+
override protected def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data = {
142142
val _asUInt = _resizeToWidth(that, this.widthOption, true)(identity)
143143
// If that is a literal and all constituent Elements can be represented as literals, return a literal
144144
val ((_, allLit), rvalues) = {
@@ -147,7 +147,7 @@ private[chisel3] trait AggregateImpl extends Data { thiz: Aggregate =>
147147
// Chisel only supports zero width extraction if hi = -1 and lo = 0, so do it manually
148148
val _extracted = if (elt.getWidth == 0) 0.U(0.W) else _asUInt(hi - 1, lo)
149149
// _fromUInt returns Data but we know that it is an Element
150-
val rhs = elt._fromUInt(_extracted).asInstanceOf[Element]
150+
val rhs = elt._fromUIntPrivate(_extracted).asInstanceOf[Element]
151151
((hi, literal && rhs.isLit), rhs)
152152
}
153153
}

core/src/main/scala/chisel3/BitsImpl.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ private[chisel3] trait UIntImpl extends BitsImpl with Num[UInt] { self: UInt =>
392392

393393
override private[chisel3] def _asUIntImpl(first: Boolean)(implicit sourceInfo: SourceInfo): UInt = this
394394

395-
override private[chisel3] def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): this.type = {
395+
override protected def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): this.type = {
396396
_resizeToWidth(that, this.widthOption, true)(identity).asInstanceOf[this.type]
397397
}
398398

@@ -518,7 +518,7 @@ private[chisel3] trait SIntImpl extends BitsImpl with Num[SInt] { self: SInt =>
518518

519519
override def _asSIntImpl(implicit sourceInfo: SourceInfo): SInt = this
520520

521-
override private[chisel3] def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): this.type =
521+
override protected def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): this.type =
522522
_resizeToWidth(that.asSInt, this.widthOption, false)(_.asSInt).asInstanceOf[this.type]
523523
}
524524

@@ -545,7 +545,7 @@ private[chisel3] trait ResetTypeImpl extends Element { self: Reset =>
545545
DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref)
546546
)
547547

548-
override private[chisel3] def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data = {
548+
override protected def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data = {
549549
val _wire = Wire(this.cloneTypeFull)
550550
_wire := that
551551
_wire
@@ -574,7 +574,7 @@ private[chisel3] trait AsyncResetImpl extends Element { self: AsyncReset =>
574574
DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref)
575575
)
576576

577-
override private[chisel3] def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data = that.asBool.asAsyncReset
577+
override protected def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data = that.asBool.asAsyncReset
578578

579579
protected def _asAsyncResetImpl(implicit sourceInfo: SourceInfo): AsyncReset = this
580580

@@ -644,7 +644,7 @@ private[chisel3] trait BoolImpl extends UIntImpl { self: Bool =>
644644
protected def _asAsyncResetImpl(implicit sourceInfo: SourceInfo): AsyncReset =
645645
pushOp(DefPrim(sourceInfo, AsyncReset(), AsAsyncResetOp, ref))
646646

647-
override private[chisel3] def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): this.type = {
647+
override protected def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): this.type = {
648648
_resizeToWidth(that, this.widthOption, true)(identity).asBool.asInstanceOf[this.type]
649649
}
650650
}

core/src/main/scala/chisel3/ChiselEnumImpl.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ private[chisel3] abstract class EnumTypeImpl(private[chisel3] val factory: Chise
4141
pushOp(DefPrim(sourceInfo, Bool(), op, this.ref, other.ref))
4242
}
4343

44-
override private[chisel3] def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data =
44+
override protected def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data =
4545
factory.apply(that.asUInt)
4646

4747
protected def _impl_===(that: EnumType)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, EqualOp, that)

core/src/main/scala/chisel3/ClockImpl.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@ private[chisel3] trait ClockImpl extends Element {
3232
DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref)
3333
)
3434

35-
override private[chisel3] def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data = that.asBool.asClock
35+
override protected def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data = that.asBool.asClock
3636
}

core/src/main/scala/chisel3/DataImpl.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -861,8 +861,13 @@ private[chisel3] trait DataImpl extends HasId with NamedComponent { self: Data =
861861
}
862862

863863
/** Return a value of this type from a UInt type. Internal implementation for asTypeOf.
864+
*
865+
* Protected so that it can be implemented by the external FixedPoint library
864866
*/
865-
private[chisel3] def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data
867+
protected def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data
868+
869+
// Package private alias for _fromUInt so we can call it elsewhere in chisel3
870+
private[chisel3] final def _fromUIntPrivate(that: UInt)(implicit sourceInfo: SourceInfo): Data = _fromUInt(that)
866871

867872
// The actual implementation of do_asUInt
868873
// @param first exists because of awkward behavior in Aggregate that requires changing 0.U to be zero-width to fix
@@ -1242,7 +1247,7 @@ final case object DontCare extends Element with connectable.ConnectableDocs {
12421247

12431248
def toPrintable: Printable = PString("DONTCARE")
12441249

1245-
private[chisel3] def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data = {
1250+
override protected def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data = {
12461251
Builder.error("DontCare cannot be a connection sink (LHS)")
12471252
this
12481253
}

core/src/main/scala/chisel3/experimental/Analog.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ final class Analog private (private[chisel3] val width: Width) extends Element {
7070
override private[chisel3] def _asUIntImpl(first: Boolean)(implicit sourceInfo: SourceInfo): UInt =
7171
throwException("Analog does not support asUInt")
7272

73-
override private[chisel3] def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data = {
73+
override protected def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data = {
7474
Builder.error("Analog does not support fromUInt")
7575
Wire(Analog(that.width))
7676
}

core/src/main/scala/chisel3/properties/Property.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ sealed trait Property[T] extends Element { self =>
235235
Builder.error(s"${this._localErrorContext} does not support .asUInt.")
236236
0.U
237237
}
238-
override private[chisel3] def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data = {
238+
override protected def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data = {
239239
Builder.exception(s"${this._localErrorContext} cannot be driven by UInt")
240240
}
241241

src/test/scala-2/chiselTests/RecordSpec.scala

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
package chiselTests
44

55
import chisel3._
6-
import chisel3.experimental.OpaqueType
6+
import chisel3.experimental.{OpaqueType, SourceInfo}
77
import chisel3.reflect.DataMirror
88
import chisel3.simulator.scalatest.ChiselSim
99
import chisel3.simulator.stimulus.RunUntilFinished
10+
import chisel3.testing.scalatest.FileCheck
1011
import chisel3.util.{Counter, Queue}
1112
import circt.stage.ChiselStage
1213
import org.scalatest.flatspec.AnyFlatSpec
@@ -113,7 +114,7 @@ object RecordSpec {
113114
}
114115
}
115116

116-
class RecordSpec extends AnyFlatSpec with Matchers with ChiselSim {
117+
class RecordSpec extends AnyFlatSpec with Matchers with ChiselSim with FileCheck {
117118
import RecordSpec._
118119

119120
behavior.of("Records")
@@ -127,11 +128,12 @@ class RecordSpec extends AnyFlatSpec with Matchers with ChiselSim {
127128
}
128129

129130
they should "emit FIRRTL bulk connects when possible" in {
130-
val chirrtl = ChiselStage.emitCHIRRTL(
131-
gen = new ConnectionTestModule(fooBarType, fooBarType)
131+
val chirrtl = ChiselStage.emitCHIRRTL(new ConnectionTestModule(fooBarType, fooBarType))
132+
chirrtl.fileCheck()(
133+
"""| CHECK: connect io.outMono, io.inMono
134+
| CHECK: connect io.outBi, io.inBi
135+
|""".stripMargin
132136
)
133-
chirrtl should include("connect io.outMono, io.inMono @")
134-
chirrtl should include("connect io.outBi, io.inBi @")
135137
}
136138

137139
they should "not allow aliased fields" in {
@@ -170,10 +172,40 @@ class RecordSpec extends AnyFlatSpec with Matchers with ChiselSim {
170172
class MyRecord extends Record {
171173
lazy val elements = VectorMap("sanitize me" -> UInt(8.W))
172174
}
173-
val chirrtl = ChiselStage.emitCHIRRTL(new RawModule {
174-
val out = IO(Output(new MyRecord))
175-
})
176-
chirrtl should include("output out : { sanitizeme : UInt<8>}")
175+
ChiselStage
176+
.emitCHIRRTL(new RawModule {
177+
val out = IO(Output(new MyRecord))
178+
})
179+
.fileCheck()(
180+
"""|CHECK: output out : { sanitizeme : UInt<8>}
181+
|""".stripMargin
182+
)
183+
}
184+
185+
// This is not a great API but it enables the external FixedPoint library
186+
they should "support overriding _fromUInt" in {
187+
class MyRecord extends Record {
188+
val foo = UInt(8.W)
189+
val elements = SeqMap("foo" -> foo)
190+
override protected def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data = {
191+
val _w = Wire(this.cloneType)
192+
_w.foo := that ^ 0x55.U(8.W)
193+
_w
194+
}
195+
}
196+
ChiselStage
197+
.emitCHIRRTL(new RawModule {
198+
val in = IO(Input(UInt(8.W)))
199+
val out = IO(Output(new MyRecord))
200+
out := in.asTypeOf(new MyRecord)
201+
})
202+
.fileCheck()(
203+
"""|CHECK: wire [[wire:.*]] : { foo : UInt<8>}
204+
|CHECK: node [[node:.*]] = xor(in, UInt<8>(0h55))
205+
|CHECK: connect [[wire]].foo, [[node]]
206+
|CHECK: connect out, [[wire]]
207+
|""".stripMargin
208+
)
177209
}
178210

179211
"Bulk connect on Record" should "check that the fields match" in {

0 commit comments

Comments
 (0)