Skip to content
This repository has been archived by the owner on Aug 20, 2024. It is now read-only.

Fix optimization of register with reset but invalid connection #2520

Merged
merged 2 commits into from
Apr 22, 2022

Conversation

jackkoenig
Copy link
Contributor

Fixes #2516

Previously,

reg r : UInt<8>, clock with :
  reset => (p, UInt<8>(3))
r is invalid

would compile to:

reg r : UInt<8>, clock
r <= UInt<8>(0)

now it compiles to:

reg r : UInt<8>, clock
r <= UInt<8>(3)

Contributor Checklist

  • [NA] Did you add Scaladoc to every public function/method?
  • [NA] Did you update the FIRRTL spec to include every new feature/behavior?
  • Did you add at least one test demonstrating the PR?
  • Did you delete any extraneous printlns/debugging code?
  • Did you specify the type of improvement?
  • Did you state the API impact?
  • Did you specify the code generation impact?
  • Did you request a desired merge strategy?
  • Did you add text to be included in the Release Notes for this change?

Type of Improvement

  • bug fix

API Impact

This is a

Backend Code Generation Impact

No impact

Desired Merge Strategy

  • Squash

Release Notes

Fix lowering of synchronously reset registers that have an invalid connection.

Reviewer Checklist (only modified by reviewer)

  • Did you add the appropriate labels?
  • Did you mark the proper milestone (1.2.x, 1.3.0, 1.4.0) ?
  • Did you review?
  • Did you check whether all relevant Contributor checkboxes have been checked?
  • Did you mark as Please Merge?

Fixes #2516

Previously,

reg r : UInt<8>, clock with :
  reset => (p, UInt<8>(3))
r is invalid

would compile to:

reg r : UInt<8>, clock
r <= UInt<8>(0)

now it compiles to:

reg r : UInt<8>, clock
r <= UInt<8>(3)
@jackkoenig jackkoenig added this to the 1.3.x milestone Apr 21, 2022
Copy link
Contributor

@ekiwi ekiwi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@ekiwi
Copy link
Contributor

ekiwi commented Apr 21, 2022

Needs some scalafmtAll though

Copy link
Member

@seldridge seldridge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I spoke to Jack about this separately.)

I don't think the additional invalid interpretation here is correct or self-consistent with existing SFC behavior. The end-to-end compile of this should result in a mux with zero, not optimization to the reset value. My reasoning is that this pass is narrowly responsible for moving the reset mux in front of the register. Any further optimization should not happen and is introducing yet-another-interpretation of invalid that has to be special cased.

Put differently, this creates a reset mux not a reset when. I would expect the pass to generate or be equivalent to the following:

reg r : UInt<8>, clock
wire inv: UInt<8>
inv is invalid
r <= mux(p, UInt<8>(3), inv)

reg r : UInt<8>, clock with :
  reset => (p, UInt<8>(3))
r is invalid

now compiles to:

reg r : UInt<8>, clock
r <= mux(reset, UInt<8>(3), UInt<8>(0))

This is consistent with the behavior for a reset with an asynchronous
reset.
@jackkoenig
Copy link
Contributor Author

Changed it to what @seldridge said. The implementation is a bit uglier, but it is consistent with the behavior when the register has an async reset.

Copy link
Member

@seldridge seldridge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Weakening my previous statements: I would like to revisit the mux(cond, _, invalid) canonicalization in the future. It's annoying that this is not unified with when or validif formulations. Keeping clean separation of lowering (this pass) from optimization/folding will help us better tackle this fully in the future.

@jackkoenig jackkoenig merged commit 5093da0 into master Apr 22, 2022
@jackkoenig jackkoenig deleted the fix-2516 branch April 22, 2022 03:20
mergify bot pushed a commit that referenced this pull request Apr 22, 2022
Fixes #2516

Previously,

reg r : UInt<8>, clock with :
  reset => (p, UInt<8>(3))
r is invalid

would compile to:

reg r : UInt<8>, clock
r <= UInt<8>(0)

now it compiles to:

reg r : UInt<8>, clock
wire r_1 : UInt<8>
r_1 is invalid
r <= mux(reset, UInt<8>(3), r_1)

This is consistent with the behavior for a reset with an asynchronous
reset.

(cherry picked from commit 5093da0)

# Conflicts:
#	src/main/scala/firrtl/transforms/RemoveReset.scala
#	src/test/scala/firrtlTests/transforms/RemoveResetSpec.scala
mergify bot pushed a commit that referenced this pull request Apr 22, 2022
Fixes #2516

Previously,

reg r : UInt<8>, clock with :
  reset => (p, UInt<8>(3))
r is invalid

would compile to:

reg r : UInt<8>, clock
r <= UInt<8>(0)

now it compiles to:

reg r : UInt<8>, clock
wire r_1 : UInt<8>
r_1 is invalid
r <= mux(reset, UInt<8>(3), r_1)

This is consistent with the behavior for a reset with an asynchronous
reset.

(cherry picked from commit 5093da0)
mergify bot pushed a commit that referenced this pull request Apr 22, 2022
Fixes #2516

Previously,

reg r : UInt<8>, clock with :
  reset => (p, UInt<8>(3))
r is invalid

would compile to:

reg r : UInt<8>, clock
r <= UInt<8>(0)

now it compiles to:

reg r : UInt<8>, clock
wire r_1 : UInt<8>
r_1 is invalid
r <= mux(reset, UInt<8>(3), r_1)

This is consistent with the behavior for a reset with an asynchronous
reset.

(cherry picked from commit 5093da0)
@mergify mergify bot added the Backported This PR has been backported to marked stable branch label Apr 22, 2022
mergify bot added a commit that referenced this pull request Apr 22, 2022
#2523)

Fixes #2516

Previously,

reg r : UInt<8>, clock with :
  reset => (p, UInt<8>(3))
r is invalid

would compile to:

reg r : UInt<8>, clock
r <= UInt<8>(0)

now it compiles to:

reg r : UInt<8>, clock
wire r_1 : UInt<8>
r_1 is invalid
r <= mux(reset, UInt<8>(3), r_1)

This is consistent with the behavior for a reset with an asynchronous
reset.

(cherry picked from commit 5093da0)

Co-authored-by: Jack Koenig <koenig@sifive.com>
mergify bot added a commit that referenced this pull request Apr 22, 2022
#2522)

Fixes #2516

Previously,

reg r : UInt<8>, clock with :
  reset => (p, UInt<8>(3))
r is invalid

would compile to:

reg r : UInt<8>, clock
r <= UInt<8>(0)

now it compiles to:

reg r : UInt<8>, clock
wire r_1 : UInt<8>
r_1 is invalid
r <= mux(reset, UInt<8>(3), r_1)

This is consistent with the behavior for a reset with an asynchronous
reset.

(cherry picked from commit 5093da0)

Co-authored-by: Jack Koenig <koenig@sifive.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Backported This PR has been backported to marked stable branch
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Incorrect optimization of a register with a reset
3 participants