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

[otbn, rtl] Fix X-propagation issue in prefetch stage #22116

Merged
merged 1 commit into from
May 24, 2024

Conversation

GregAC
Copy link
Contributor

@GregAC GregAC commented Mar 19, 2024

When executing near Xs in imem it's possible for Xs to be received on the incoming imem data. The prefetcher looks at the incoming data to see if its a branch instruction.

Previous to this change this branch check took priority over a check related to looping which altered the request going to imem. So when the incoming imem data was X, when simulation propagated Xs though ifs we end up with an X on the imem request address.

With this change the check for the branch happens regardless of whether or not the looping related logic activates and the branch logic itself does not alter the imem request so it avoids generating Xs on the external (to OTBN core) imem request interface.

Draft PR for as I don't think this is an essential fix. When running a regression I'm seeing some new failures though I think they were hidden behind previous X check failures (overall pass rate is similar). Further investigation should be done before merging this.

Fixes #21658 along with #22115

Copy link
Contributor

@rswarbrick rswarbrick left a comment

Choose a reason for hiding this comment

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

I'm not sure I properly understand this change, with the exact if/else tree. Are we essentially just reversing the order of the last two cases in the if/else list? I think that would be easier to understand, so I fear I'm missing something...

Comment on lines 337 to 339
if ({1'b0, insn_prefetch_addr} == prefetch_loop_end_addr_i &&
prefetch_loop_active_i &&
prefetch_loop_iterations_i > 32'd1) begin
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Indentation is a bit off here.

@GregAC
Copy link
Contributor Author

GregAC commented Mar 21, 2024

Are we essentially just reversing the order of the last two cases in the if/else list?

Not quite. Previously the first (the insn_is_branch check) of those cases took priority over the second (the loop related one) now they sit inside one else as independent so both their if bodies can run or just one or neither.

@rswarbrick
Copy link
Contributor

rswarbrick commented Mar 21, 2024

Oh, I think I understand now. Before this commit, the logic was something like:

if (!insn_fetch_req_valid_raw_i) A;
else if (insn_prefetch_fail) B;
else if (insn_is_branch(...)) C;
else if (xxxx) D;

With this commit, I think the structure becomes:

if (!insn_fetch_req_valid_raw_i) A;
else if (insn_prefetch_fail) B;
else {
    if (xxxx) D;
    if (insn_is_branch(...)) C;
}

I think the behaviour is now slightly different (even without Xs), because we might have a situation where both xxxx and insn_is_branch(...) are true. Before this patch, we'd get behaviour C. After this patch, we get C; D.

I guess this makes perfect sense so that we properly handle the situation where xxxx is true and insn_is_branch(...) is X.

But the code is getting a bit hard to understand! Can't we pull the stuff that controls imem_rvalid_kill_d and insn_prefetch into its own always_comb? That way, the fact that it won't mess up imem_addr_o becomes obvious.

@GregAC
Copy link
Contributor Author

GregAC commented Mar 22, 2024

But the code is getting a bit hard to understand! Can't we pull the stuff that controls imem_rvalid_kill_d and insn_prefetch into its own always_comb? That way, the fact that it won't mess up imem_addr_o becomes obvious.

I did actually try this and it generated a large number of errors. I think under the first two cases of the big if, these ones:

if (!insn_fetch_req_valid_raw_i) begin
// Keep prefetching the same instruction when a new one isn't being requested. In this
// scenario OTBN is stalled and will eventually want the prefetched instruction.
imem_addr_o = insn_prefetch_addr;
end else if (insn_prefetch_fail) begin
// When prefetching has failed prefetch the requested address
imem_addr_o = insn_fetch_req_addr_i;
end else begin

There's at least some times you don't want to kill an incoming instruction immediately after a branch, though I didn't really investigate the details. So your new always_comb would need to repeat checking these conditions and only do the prefetch kill if they don't occur. So I'd rather have it all in one place so if you alter the top two conditions you don't need to to do it in two separate places.

@rswarbrick
Copy link
Contributor

Oh, I see. In which case, never mind :-) Thanks for explaining carefully.

rswarbrick
rswarbrick previously approved these changes Mar 22, 2024
@rswarbrick rswarbrick dismissed their stale review March 22, 2024 14:07

I just realised that the indentation is still awry and I don't want to accidentally leave a green tick lying around :-)

@GregAC GregAC force-pushed the prefetch_xprop_fix branch 2 times, most recently from 215278a to bbd1ad2 Compare May 23, 2024 09:25
When executing near Xs in imem it's possible for Xs to be received on
the incoming imem data. The prefetcher looks at the incoming data to see
if its a branch instruction.

Previous to this change this branch check took priority over a check
related to looping which altered the request going to imem. So when the
incoming imem data was X, when simulation propagated Xs though ifs we
end up with an X on the imem request address.

With this change the check for the branch happens regardless of whether
or not the looping related logic activates and the branch logic itself
does not alter the imem request so it avoids generating Xs on the
external (to OTBN core) imem request interface.

Signed-off-by: Greg Chadwick <gac@lowrisc.org>
@GregAC GregAC force-pushed the prefetch_xprop_fix branch from bbd1ad2 to eed3b21 Compare May 23, 2024 09:44
@GregAC GregAC marked this pull request as ready for review May 23, 2024 09:54
Copy link
Contributor

@andreaskurth andreaskurth left a comment

Choose a reason for hiding this comment

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

Thanks for the careful explanation, @GregAC, and the discussion, @rswarbrick. LGTM!

@andreaskurth andreaskurth merged commit 96f3dcc into lowRISC:master May 24, 2024
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[otbn] The otbn_multi_err test currently fails with an assertion error
3 participants