summaryrefslogtreecommitdiff
path: root/core/src/main/scala/chisel3
diff options
context:
space:
mode:
authorJim Lawson2020-07-13 11:26:43 -0700
committerGitHub2020-07-13 11:26:43 -0700
commit417fc2adac01d47bd824d5851bda7baed4d92810 (patch)
treebc220dafb3b0ebe8816506f1afbcecd0bf94478f /core/src/main/scala/chisel3
parentac3ad980dd2e5abd43f3b36ecb1fb95b626aa398 (diff)
Provide an implementation of litOption() for BundleLits (#1280)
Diffstat (limited to 'core/src/main/scala/chisel3')
-rw-r--r--core/src/main/scala/chisel3/Aggregate.scala24
1 files changed, 23 insertions, 1 deletions
diff --git a/core/src/main/scala/chisel3/Aggregate.scala b/core/src/main/scala/chisel3/Aggregate.scala
index 6c1e8dfb..fff7a2d0 100644
--- a/core/src/main/scala/chisel3/Aggregate.scala
+++ b/core/src/main/scala/chisel3/Aggregate.scala
@@ -43,7 +43,29 @@ sealed abstract class Aggregate extends Data {
}
}
- override def litOption: Option[BigInt] = None // TODO implement me
+ /** Return an Aggregate's literal value if it is a literal, None otherwise.
+ * If any element of the aggregate is not a literal with a defined width, the result isn't a literal.
+ *
+ * @return an Aggregate's literal value if it is a literal.
+ */
+ override def litOption: Option[BigInt] = {
+ // Shift the accumulated value by our width and add in our component, masked by our width.
+ def shiftAdd(accumulator: Option[BigInt], elt: Data): Option[BigInt] = (accumulator, elt.litOption()) match {
+ case (Some(accumulator), Some(eltLit)) =>
+ val width = elt.width.get
+ val masked = ((BigInt(1) << width) - 1) & eltLit // also handles the negative case with two's complement
+ Some((accumulator << width) + masked)
+ case (None, _) => None
+ case (_, None) => None
+ }
+ topBindingOpt match {
+ case Some(BundleLitBinding(_)) =>
+ getElements
+ .reverse
+ .foldLeft[Option[BigInt]](Some(BigInt(0)))(shiftAdd)
+ case _ => None
+ }
+ }
/** Returns a Seq of the immediate contents of this Aggregate, in order.
*/