Skip to content
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

lib.fifo: fix reset handling of asynchronous FIFOs. #591

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

jfng
Copy link
Member

@jfng jfng commented Feb 9, 2021

Asynchronous FIFOs do not properly handle a write domain reset (i.e. w_level is not reset to 0). This PR attempts to fix their behaviour.

@codecov
Copy link

codecov bot commented Feb 9, 2021

Codecov Report

Merging #591 (0dcf329) into master (f7c2b94) will increase coverage by 0.07%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #591      +/-   ##
==========================================
+ Coverage   81.50%   81.58%   +0.07%     
==========================================
  Files          49       49              
  Lines        6461     6467       +6     
  Branches     1287     1288       +1     
==========================================
+ Hits         5266     5276      +10     
+ Misses       1007     1005       -2     
+ Partials      188      186       -2     
Impacted Files Coverage Δ
nmigen/lib/fifo.py 94.25% <100.00%> (+0.16%) ⬆️
nmigen/build/run.py 22.05% <0.00%> (ø)
nmigen/sim/_pyrtl.py 97.00% <0.00%> (+1.19%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f7c2b94...0dcf329. Read the comment docs.

Copy link
Member

@whitequark whitequark left a comment

Choose a reason for hiding this comment

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

Looks good and passes tests; I'm going to merge this after checking how it works with Glasgow Interface Explorer (where this issue is readily observed with the QSPI gateware).

@whitequark whitequark added this to the 0.6 milestone Jul 18, 2024
Copy link
Member Author

@jfng jfng left a comment

Choose a reason for hiding this comment

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

After discussing with @whitequark, it is no longer clear whether the current approach of propagating write domain resets to the read side is correct; doing so empties the FIFO, which can violate the invariant of a stream interface (valid must not be deasserted on it own).

Ideally, there would be a configurable "primary" and "secondary" side, where the primary side controls the reset of the secondary side.

In any case, further iterations of this change will require thorough testing and would benefit from (multi-clock) BMC or fuzzing.

# write domain.
with m.If(w_rst):
m.d[self._w_domain] += produce_w_gry.eq(consume_w_gry)
m.d[self._w_domain] += produce_w_bin.eq(_gray_decode(consume_w_gry))
Copy link
Member Author

Choose a reason for hiding this comment

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

This does not work: if a write domain reset happens one clock cycle after a read, then the next value of consume_w_gry is still inside an FFSynchronizer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants