-
Notifications
You must be signed in to change notification settings - Fork 597
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide an implementation of litOption() for BundleLits #1280
Conversation
This is just a band aid until an Aggregate `isLit()` method (for which work has begun) is implemented.
# Conflicts: # chiselFrontend/src/main/scala/chisel3/Aggregate.scala
Probably want to rebase/cherry-pick on master since bandaid |
We should add some tests to verify this works with Vec literals as well. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some style concerns, a question, and a possible overflow, but otherwise looks sane.
Also consider adding a test for a literal with a >64 bit element.
val value = shiftadd._2 & mask | ||
(accumulator << width) + value | ||
} | ||
try { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The need for a try-catch seems like a red flag. What is this meant to catch that isn't handled by an Option? And can we fix that instead?
try { | ||
topBindingOpt match { | ||
case Some(BundleLitBinding(_)) => | ||
Some(getElements.reverse.map{ case e => (e.width.get, e.litOption().get)}.foldLeft(BigInt(0))(shiftAdd(_, _))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the map and fold should be broken into multiple lines for readability. Took a while to parse this...
// Shift the accumulated value by our width and add in our component, masked by our width. | ||
def shiftAdd(accumulator: BigInt, shiftadd: (Int, BigInt)): BigInt = { | ||
val width = shiftadd._1 | ||
val mask = (1 << width) - 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a Int or BigInt type? Will this work for >32 bits?
def shiftAdd(accumulator: BigInt, shiftadd: (Int, BigInt)): BigInt = { | ||
val width = shiftadd._1 | ||
val mask = (1 << width) - 1 | ||
val value = shiftadd._2 & mask |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the mask ever necessary? I'd be tempted to assert out of the mask actually did anything, since that means a literal is overflowing its allotted width?
@@ -28,7 +28,8 @@ class BundleLiteralSpec extends ChiselFlatSpec { | |||
chisel3.assert(outsideBundleLit.a === 42.U) | |||
chisel3.assert(outsideBundleLit.b === true.B) | |||
chisel3.assert(outsideBundleLit.c === MyEnum.sB) | |||
|
|||
chisel3.assert(outsideBundleLit.isLit()) | |||
chisel3.assert(outsideBundleLit.litValue().U === outsideBundleLit.asUInt()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a literal packing test anywhere? Do we want to test that too, by equivalence with a "magic number" in the test case, instead of solely equivalence with the .asUInt behavior?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think LiteralExtractorSpec
provides Lit
test for Element
type, and tests for Lit
.
But in my understanding, Lit
and LitOption
are two different thing:
Lit
will return a Option[BigInt]
, while LitOption
will return T
itself.
As for this case:
I think the result of outsideBundleLit.litValue().U === outsideBundleLit.asUInt()
is only a necessary condition to this test.
If we wanna fully test this, I think the we should test the behavior of firrtl behavior of chisel3.internal.firrtl.PrimOp.AsUIntOp
is equal to the (accumulator << width) + masked)
behavior. At my first glance to firrtl.PrimOps.AsUInt
, this behavior is correct. I think this is good enough here.
Updated PR:
It seems to work. But one more general concerning point: in the LongBundle literal specifier, if I don't have explicit widths for the components (not in the most-significant position, at least), it seems .asUInt will return a different value in simulation. So it seems the structural width of the bundle is being ignored for the widths of literal elements in the simulation bundle packing, which seems wrong? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally, lgtm expect some small nitpicking.
@@ -28,7 +28,8 @@ class BundleLiteralSpec extends ChiselFlatSpec { | |||
chisel3.assert(outsideBundleLit.a === 42.U) | |||
chisel3.assert(outsideBundleLit.b === true.B) | |||
chisel3.assert(outsideBundleLit.c === MyEnum.sB) | |||
|
|||
chisel3.assert(outsideBundleLit.isLit()) | |||
chisel3.assert(outsideBundleLit.litValue().U === outsideBundleLit.asUInt()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think LiteralExtractorSpec
provides Lit
test for Element
type, and tests for Lit
.
But in my understanding, Lit
and LitOption
are two different thing:
Lit
will return a Option[BigInt]
, while LitOption
will return T
itself.
As for this case:
I think the result of outsideBundleLit.litValue().U === outsideBundleLit.asUInt()
is only a necessary condition to this test.
If we wanna fully test this, I think the we should test the behavior of firrtl behavior of chisel3.internal.firrtl.PrimOp.AsUIntOp
is equal to the (accumulator << width) + masked)
behavior. At my first glance to firrtl.PrimOps.AsUInt
, this behavior is correct. I think this is good enough here.
Fixed stylistic issues mentioned in review comments. Not sure why GitHub isn't allowing a response to the last comment but:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As Jack mentioned in dev meeting, chisel3.assert
will invoke FIRRTL to test, so generally lgtm. Thanks @ducky64
Related issue: #1277, ucb-bar/dsptools#184
Type of change: bug report
Impact: API addition (no impact on existing code)
Development Phase: implementation
Release Notes
Provide an implementation of
litOption
for Aggregates (Bundles).