Skip to content

Commit 44b03b3

Browse files
authored
Merge branch 'chipsalliance:main' into tywaves-annotations
2 parents a684fde + 255d3d4 commit 44b03b3

40 files changed

+563
-213
lines changed

build.sbt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ lazy val warningSuppression = Seq(
6767
// This is deprecated for external users but not internal use
6868
"cat=deprecation&origin=firrtl\\.options\\.internal\\.WriteableCircuitAnnotation:s",
6969
"cat=deprecation&origin=chisel3\\.util\\.experimental\\.BoringUtils.*:s",
70-
"cat=deprecation&origin=chisel3\\.experimental\\.IntrinsicModule:s"
70+
"cat=deprecation&origin=chisel3\\.experimental\\.IntrinsicModule:s",
71+
"cat=deprecation&origin=chisel3\\.ltl.*:s"
7172
).mkString(",")
7273
)
7374

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

Lines changed: 63 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -114,25 +114,52 @@ sealed abstract class Aggregate extends Data {
114114
}
115115
}
116116

117-
private[chisel3] override def connectFromBits(
118-
that: Bits
119-
)(
120-
implicit sourceInfo: SourceInfo
121-
): Unit = {
122-
var i = 0
123-
val bits = if (that.isLit) that else WireDefault(UInt(this.width), that) // handles width padding
124-
for (x <- flatten) {
125-
val fieldWidth = x.getWidth
126-
if (fieldWidth > 0) {
127-
x.connectFromBits(bits(i + fieldWidth - 1, i))
128-
i += fieldWidth
129-
} else {
130-
// There's a zero-width field in this bundle.
131-
// Zero-width fields can't really be assigned to, but the frontend complains if there are uninitialized fields,
132-
// so we assign it to DontCare. We can't use connectFromBits() on DontCare, so use := instead.
133-
x := DontCare
117+
// Return a literal of the same type from a Seq of literals for each leaf
118+
private[chisel3] final def _makeLitFromLeaves(elems: Seq[Element])(implicit sourceInfo: SourceInfo): Data = {
119+
// We could use virtual methods instead of matching on concrete subtypes,
120+
// but the difference for Record vs Vec is so small, it doesn't seem worth it
121+
val clone: Aggregate = this.cloneTypeFull
122+
val mapping = clone.flatten.view
123+
.zip(elems)
124+
.map {
125+
case (thisElt, litElt) =>
126+
val litArg = litElt.topBindingOpt match {
127+
case Some(ElementLitBinding(value)) => value
128+
case _ => throwException(s"Internal Error! For field $thisElt, given non-literal $litElt!")
129+
}
130+
thisElt -> litArg
131+
}
132+
val binding = clone match {
133+
case r: Record => BundleLitBinding(mapping.to(Map))
134+
case v: Vec[_] => VecLitBinding(mapping.to(VectorMap))
135+
}
136+
clone.bind(binding)
137+
clone
138+
}
139+
140+
override private[chisel3] def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data = {
141+
val _asUInt = _resizeToWidth(that, this.widthOption)(identity)
142+
// If that is a literal and all constituent Elements can be represented as literals, return a literal
143+
val ((_, allLit), rvalues) = {
144+
this.flatten.toList.mapAccumulate((0, _asUInt.isLit)) {
145+
case ((lo, literal), elt) =>
146+
val hi = lo + elt.getWidth
147+
// Chisel only supports zero width extraction if hi = -1 and lo = 0, so do it manually
148+
val _extracted = if (elt.getWidth == 0) 0.U(0.W) else _asUInt(hi - 1, lo)
149+
// _fromUInt returns Data but we know that it is an Element
150+
val rhs = elt._fromUInt(_extracted).asInstanceOf[Element]
151+
((hi, literal && rhs.isLit), rhs)
134152
}
135153
}
154+
if (allLit) {
155+
this._makeLitFromLeaves(rvalues)
156+
} else {
157+
val _wire = Wire(this.cloneTypeFull)
158+
for ((l, r) <- _wire.flatten.zip(rvalues)) {
159+
l := r
160+
}
161+
_wire
162+
}
136163
}
137164
}
138165

@@ -215,8 +242,10 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) extend
215242

216243
val resolvedDirection = SpecifiedDirection.fromParent(parentDirection, specifiedDirection)
217244
sample_element.bind(SampleElementBinding(this), resolvedDirection)
245+
// Share same object for binding of all children.
246+
val childBinding = ChildBinding(this)
218247
for (child <- elementsIterator) { // assume that all children are the same
219-
child.bind(ChildBinding(this), resolvedDirection)
248+
child.bind(childBinding, resolvedDirection)
220249
}
221250

222251
// Since all children are the same, we can just use the sample_element rather than all children
@@ -512,7 +541,7 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) extend
512541
if (m < n) Some(index -> lit) else None
513542
case (KnownWidth(_), _) =>
514543
None
515-
case (UnknownWidth(), _) =>
544+
case (UnknownWidth, _) =>
516545
None
517546
case _ =>
518547
Some(index -> lit)
@@ -632,26 +661,6 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) extend
632661

633662
object VecInit extends SourceInfoDoc {
634663

635-
/** Gets the correct connect operation (directed hardware assign or bulk connect) for element in Vec.
636-
*/
637-
private def getConnectOpFromDirectionality[T <: Data](
638-
proto: T
639-
)(
640-
implicit sourceInfo: SourceInfo
641-
): (T, T) => Unit = proto.direction match {
642-
case ActualDirection.Input | ActualDirection.Output | ActualDirection.Unspecified =>
643-
// When internal wires are involved, driver / sink must be specified explicitly, otherwise
644-
// the system is unable to infer which is driver / sink
645-
(x, y) => x := y
646-
case ActualDirection.Bidirectional(_) =>
647-
// For bidirectional, must issue a bulk connect so subelements are resolved correctly.
648-
// Bulk connecting two wires may not succeed because Chisel frontend does not infer
649-
// directions.
650-
(x, y) => x <> y
651-
case ActualDirection.Empty =>
652-
(x, y) => x <> y
653-
}
654-
655664
/** Creates a new [[Vec]] composed of elements of the input Seq of [[Data]]
656665
* nodes.
657666
*
@@ -677,10 +686,9 @@ object VecInit extends SourceInfoDoc {
677686
elts.foreach(requireIsHardware(_, "vec element"))
678687

679688
val vec = Wire(Vec(elts.length, cloneSupertype(elts, "Vec")))
680-
val op = getConnectOpFromDirectionality(vec.head)
681689

682-
(vec.zip(elts)).foreach { x =>
683-
op(x._1, x._2)
690+
for ((lhs, rhs) <- vec.zip(elts)) {
691+
lhs :<>= rhs
684692
}
685693
vec
686694
}
@@ -746,12 +754,11 @@ object VecInit extends SourceInfoDoc {
746754

747755
val tpe = cloneSupertype(flatElts, "Vec.tabulate")
748756
val myVec = Wire(Vec(n, Vec(m, tpe)))
749-
val op = getConnectOpFromDirectionality(myVec.head.head)
750757
for {
751758
(xs1D, ys1D) <- myVec.zip(elts)
752-
(x, y) <- xs1D.zip(ys1D)
759+
(lhs, rhs) <- xs1D.zip(ys1D)
753760
} {
754-
op(x, y)
761+
lhs :<>= rhs
755762
}
756763
myVec
757764
}
@@ -786,14 +793,13 @@ object VecInit extends SourceInfoDoc {
786793

787794
val tpe = cloneSupertype(flatElts, "Vec.tabulate")
788795
val myVec = Wire(Vec(n, Vec(m, Vec(p, tpe))))
789-
val op = getConnectOpFromDirectionality(myVec.head.head.head)
790796

791797
for {
792798
(xs2D, ys2D) <- myVec.zip(elts)
793799
(xs1D, ys1D) <- xs2D.zip(ys2D)
794-
(x, y) <- xs1D.zip(ys1D)
800+
(lhs, rhs) <- xs1D.zip(ys1D)
795801
} {
796-
op(x, y)
802+
lhs :<>= rhs
797803
}
798804

799805
myVec
@@ -1066,18 +1072,20 @@ abstract class Record extends Aggregate {
10661072

10671073
checkForAndReportDuplicates()
10681074

1069-
// This check is for making sure that elements always returns the
1070-
// same object, which will not be the case if the user makes it a
1071-
// def inside the Record. Checking elementsIterator against itself
1072-
// is not useful for this check because it's a lazy val which will
1073-
// always return the same thing.
1075+
// Share same object for binding of all children.
1076+
val childBinding = ChildBinding(this)
10741077
for (((_, child), sameChild) <- this.elements.iterator.zip(this.elementsIterator)) {
1078+
// This check is for making sure that elements always returns the
1079+
// same object, which will not be the case if the user makes it a
1080+
// def inside the Record. Checking elementsIterator against itself
1081+
// is not useful for this check because it's a lazy val which will
1082+
// always return the same thing.
10751083
if (child != sameChild) {
10761084
throwException(
10771085
s"${this.className} does not return the same objects when calling .elements multiple times. Did you make it a def by mistake?"
10781086
)
10791087
}
1080-
child.bind(ChildBinding(this), resolvedDirection)
1088+
child.bind(childBinding, resolvedDirection)
10811089

10821090
// Update the flipped tracker based on the flipped-ness of this specific child element
10831091
_containsAFlipped |= child.containsAFlipped
@@ -1222,7 +1230,7 @@ abstract class Record extends Aggregate {
12221230
case (field, value) =>
12231231
field.width match {
12241232
// If width is unknown, then it is set by the literal value.
1225-
case UnknownWidth() => field -> value
1233+
case UnknownWidth => field -> value
12261234
case width @ KnownWidth(widthValue) =>
12271235
val valuex = if (widthValue < value.width.get) {
12281236
// For legacy reasons, 0.U is 1-bit, don't warn when it comes up as a literal value for 0-bit Bundle lit field.

core/src/main/scala/chisel3/Bits.scala

Lines changed: 20 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ package chisel3
44

55
import scala.language.experimental.macros
66
import chisel3.experimental.{requireIsHardware, SourceInfo}
7-
import chisel3.internal.{throwException, BaseModule}
7+
import chisel3.internal.{_resizeToWidth, throwException, BaseModule}
88
import chisel3.internal.Builder.pushOp
99
import chisel3.internal.firrtl.ir._
1010
import chisel3.internal.sourceinfo.{
@@ -80,16 +80,16 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi
8080
case KnownWidth(x) =>
8181
require(x >= n, s"Can't tail($n) for width $x < $n")
8282
Width(x - n)
83-
case UnknownWidth() => Width()
83+
case UnknownWidth => Width()
8484
}
8585
binop(sourceInfo, UInt(width = w), TailOp, n)
8686
}
8787

8888
/** @group SourceInfoTransformMacro */
8989
def do_head(n: Int)(implicit sourceInfo: SourceInfo): UInt = {
9090
width match {
91-
case KnownWidth(x) => require(x >= n, s"Can't head($n) for width $x < $n")
92-
case UnknownWidth() =>
91+
case KnownWidth(x) => require(x >= n, s"Can't head($n) for width $x < $n")
92+
case UnknownWidth => ()
9393
}
9494
binop(sourceInfo, UInt(Width(n)), HeadOp, n)
9595
}
@@ -695,7 +695,7 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U
695695
resultWidth match {
696696
// To emulate old FIRRTL behavior where minimum width is 1, we need to insert pad(_, 1) whenever
697697
// the width is or could be 0. Thus we check if it is known to be 0 or is unknown.
698-
case w @ (KnownWidth(0) | UnknownWidth()) =>
698+
case w @ (KnownWidth(0) | UnknownWidth) =>
699699
// Because we are inserting an extra op but we want stable emission (so the user can diff the output),
700700
// we need to seed a name to avoid name collisions.
701701
op.autoSeed("_shrLegacyWidthFixup")
@@ -705,7 +705,7 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U
705705
}
706706

707707
override def do_>>(that: Int)(implicit sourceInfo: SourceInfo): UInt = {
708-
if (Builder.legacyShiftRightWidth) legacyShiftRight(that)
708+
if (Builder.useLegacyWidth) legacyShiftRight(that)
709709
else binop(sourceInfo, UInt(this.width.unsignedShiftRight(that)), ShiftRightOp, validateShiftAmount(that))
710710
}
711711
override def do_>>(that: BigInt)(implicit sourceInfo: SourceInfo): UInt =
@@ -811,12 +811,8 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U
811811

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

814-
private[chisel3] override def connectFromBits(
815-
that: Bits
816-
)(
817-
implicit sourceInfo: SourceInfo
818-
): Unit = {
819-
this := that.asUInt
814+
override private[chisel3] def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): this.type = {
815+
_resizeToWidth(that, this.widthOption)(identity).asInstanceOf[this.type]
820816
}
821817

822818
private def subtractAsSInt(that: UInt)(implicit sourceInfo: SourceInfo): SInt =
@@ -1045,7 +1041,7 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[S
10451041
override def do_>>(that: Int)(implicit sourceInfo: SourceInfo): SInt = {
10461042
// We don't need to pad to emulate old behavior for SInt, just emulate old Chisel behavior with reported width.
10471043
// FIRRTL will give a minimum of 1 bit for SInt.
1048-
val newWidth = if (Builder.legacyShiftRightWidth) this.width.shiftRight(that) else this.width.signedShiftRight(that)
1044+
val newWidth = if (Builder.useLegacyWidth) this.width.shiftRight(that) else this.width.signedShiftRight(that)
10491045
binop(sourceInfo, SInt(newWidth), ShiftRightOp, validateShiftAmount(that))
10501046
}
10511047
override def do_>>(that: BigInt)(implicit sourceInfo: SourceInfo): SInt =
@@ -1071,13 +1067,8 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[S
10711067

10721068
override def do_asSInt(implicit sourceInfo: SourceInfo): SInt = this
10731069

1074-
private[chisel3] override def connectFromBits(
1075-
that: Bits
1076-
)(
1077-
implicit sourceInfo: SourceInfo
1078-
): Unit = {
1079-
this := that.asSInt
1080-
}
1070+
override private[chisel3] def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): this.type =
1071+
_resizeToWidth(that.asSInt, this.widthOption)(_.asSInt).asInstanceOf[this.type]
10811072
}
10821073

10831074
sealed trait Reset extends Element with ToBoolable {
@@ -1118,12 +1109,10 @@ final class ResetType(private[chisel3] val width: Width = Width(1)) extends Elem
11181109
DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref)
11191110
)
11201111

1121-
private[chisel3] override def connectFromBits(
1122-
that: Bits
1123-
)(
1124-
implicit sourceInfo: SourceInfo
1125-
): Unit = {
1126-
this := that
1112+
override private[chisel3] def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data = {
1113+
val _wire = Wire(this.cloneTypeFull)
1114+
_wire := that
1115+
_wire
11271116
}
11281117

11291118
/** @group SourceInfoTransformMacro */
@@ -1162,14 +1151,7 @@ sealed class AsyncReset(private[chisel3] val width: Width = Width(1)) extends El
11621151
DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref)
11631152
)
11641153

1165-
// TODO Is this right?
1166-
private[chisel3] override def connectFromBits(
1167-
that: Bits
1168-
)(
1169-
implicit sourceInfo: SourceInfo
1170-
): Unit = {
1171-
this := that.asBool.asAsyncReset
1172-
}
1154+
override private[chisel3] def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): Data = that.asBool.asAsyncReset
11731155

11741156
/** @group SourceInfoTransformMacro */
11751157
def do_asAsyncReset(implicit sourceInfo: SourceInfo): AsyncReset = this
@@ -1299,4 +1281,8 @@ sealed class Bool() extends UInt(1.W) with Reset {
12991281
/** @group SourceInfoTransformMacro */
13001282
def do_asAsyncReset(implicit sourceInfo: SourceInfo): AsyncReset =
13011283
pushOp(DefPrim(sourceInfo, AsyncReset(), AsAsyncResetOp, ref))
1284+
1285+
override private[chisel3] def _fromUInt(that: UInt)(implicit sourceInfo: SourceInfo): this.type = {
1286+
_resizeToWidth(that, this.widthOption)(identity).asBool.asInstanceOf[this.type]
1287+
}
13021288
}

0 commit comments

Comments
 (0)