Skip to content

Refactor: Adopt AXI5 reset pattern for OBI memory driver - #2741

Open
TheMonkeyG wants to merge 3 commits into
openhwfoundation:masterfrom
TheMonkeyG:fix_2734
Open

TheMonkeyG wants to merge 3 commits into
openhwfoundation:masterfrom
TheMonkeyG:fix_2734

Conversation

@TheMonkeyG

Copy link
Copy Markdown

Resolves #2734

The OBI memory driver previously dispatched on cntxt.reset_state
inside per-task loops (drv_pre_reset/drv_in_reset/drv_post_reset).
Because drv_post_reset() called multi-cycle tasks (drv_mstr_req,
drv_slv_read_req, drv_slv_write_req), reset_state was only
re-checked between transactions, not during one — a reset asserted
mid-transaction would not abort it. That's the root cause of #2734.

This PR moves reset handling entirely into run_phase, using the
same disable fork pattern already used in uvma_axi5. Rationale
and an alternative approach that was considered (per-task
fork/join_any escapes) are written up in this comment:
#2734 (comment)

Reset architecture changes

  • run_phase now spawns the gnt loop (drv_slv_gnt, chan_a) and
    the transaction loop (drv_mstr_loop/drv_slv_loop, chan_r)
    via fork...join_none, racing against a wait(reset_n !== 1) in
    the same scope. When reset asserts, join_any returns and
    disable fork kills both loops immediately, wherever they were
    in execution — including mid multi-cycle wait inside a
    transaction task.
  • drv_mstr_loop/drv_slv_loop (formerly the MSTR/SLV branches of
    drv_post_reset) are now self-contained forever loops with no
    reset awareness of their own; they rely entirely on the outer
    disable fork to stop them.
  • If the loop is killed between get_next_item/try_next_item and
    item_done(), the sequencer would otherwise deadlock. run_phase
    now checks req != null after disable fork and calls
    item_done() itself to release the sequencer.
  • Added force_idle_nets/release_nets on uvma_obi_memory_if,
    operating on the bare signal names (force must target the
    physical net, not a clocking-block alias). This gives a hard
    guarantee the bus is idle while in reset, on top of the existing
    soft <= idle drive in drv_idle().
  • drv_slv_gnt() no longer dispatches on cntxt.reset_state — it's
    only ever invoked from inside the active-window fork now.

Bundled protocol fixes

Signed-off-by: Daniel monkeyg400@gmail.com

Resolves openhwfoundation#2734

* Migrated reset handling to a centralized disable fork pattern inside run_phase
* Added force_idle_nets and release_nets to handle asynchronous resets safely
* Restored reactive slave behavior by using try_next_item in drv_slv_loop
* Fixed shared state race condition by removing cntxt.reset_state assignment from driver

Signed-off-by: Daniel  <monkeyg400@gmail.com>
@datum-dpoulin

Copy link
Copy Markdown
Contributor

I would recommend keeping reset monitoring logic in the monitor and using a uvm_event in the context to share state with the driver.

@TheMonkeyG

Copy link
Copy Markdown
Author

Hi datum-dpoulin,
Thanks for the feedback! I've updated the driver to use the uvm_events just like you suggested.
Since I was already digging into mon, I went ahead and applied a similar fix to the monitor to address #2735 as well.
Let me know if this looks good to you!

@MikeOpenHWGroup

Copy link
Copy Markdown
Contributor

Hi @TheMonkeyG, thanks for the update. This is a significant change that will impact multiple projects, so I am being very careful with it. The OBI Agent is used by two active projects (CVE2 and CVA6) am actively working to test these changes in the CVE2 environment. I'll let you know if I encounter any issues.

@MikeOpenHWGroup MikeOpenHWGroup self-assigned this Jun 22, 2026
@MikeOpenHWGroup MikeOpenHWGroup added the enhancement New feature or request label Jun 22, 2026
@TheMonkeyG

Copy link
Copy Markdown
Author

Hi @MikeOpenHWGroup,

I reviewed the reset handling and realized that using a fake item_done() to clean up aborted transactions in the driver was not the best idea :)

I've just pushed an update to fix this: I removed the manual item_done() call from the driver's reset cleanup. Instead, I added reset monitoring directly to the sequencer using stop_sequences().

To check this, I wrote a quick smoke test that fires reset at different points during idle, right before item_done(), and mid-transaction. The approach mostly held up under reset, but the smoke test also found one narrow case: if item_done() happens to fire in the exact same delta cycle as reset asserting, it can slip through before the sequencer reacts — so the sequence sees a false "completed". Not sure yet if real OBI timing can actually land in that window, or if it's just an artifact of how the mock drives reset. Still looking into it.

Please let me know how it behaves in your CVE2 testing !

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

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

uvma_obi_memory_drv (SLV mode) may still drive rvalid after reset asserted (cannot abort pending response)

3 participants