diff options
| author | Jim Lawson | 2020-07-13 11:26:43 -0700 |
|---|---|---|
| committer | GitHub | 2020-07-13 11:26:43 -0700 |
| commit | 417fc2adac01d47bd824d5851bda7baed4d92810 (patch) | |
| tree | bc220dafb3b0ebe8816506f1afbcecd0bf94478f /core/src/main/scala | |
| parent | ac3ad980dd2e5abd43f3b36ecb1fb95b626aa398 (diff) | |
Provide an implementation of litOption() for BundleLits (#1280)
Diffstat (limited to 'core/src/main/scala')
| -rw-r--r-- | core/src/main/scala/chisel3/Aggregate.scala | 24 |
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. */ |
