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

[sram_ctrl] Add readback feature #23212

Merged
merged 1 commit into from
May 26, 2024
Merged

Conversation

nasahlpa
Copy link
Member

When enabled with the SRAM_CTRL.READBACK CSR, the SRAM readback mode checks each read and write to the SRAM.

On a read, the readback mode issues a second read to the same address to check, whether the correct data was fetched from memory. On a write, the readback mode issues a read to check, whether the data was actually written into the memory. To avoid that the holding register is read, the readback is delayed by one cycle.

On a mismatch, a fatal error is triggered and the STATUS.READBACK_ERROR register is set.

To avoid RTL changes as much as possible, the readback mode is implemented in the tlul_sram_byte module. In this module, after the initial read or write was executed, the bus interface to the host is stalled and the readback is performed. Due to the bus stalling, a performance impact is expected.

@nasahlpa nasahlpa requested review from mundaym, a team and msfschaffner as code owners May 21, 2024 05:29
@nasahlpa nasahlpa force-pushed the sram_readback branch 11 times, most recently from 6270e58 to 72e0d3d Compare May 22, 2024 08:04
Copy link
Contributor

@vogelpi vogelpi left a comment

Choose a reason for hiding this comment

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

Thanks @nasahlpa for porting this change over. I've done another pass and it looks mostly good as expected.

However, I spotted a few things that should be cleaned up before we merge this. It might be these things were introduced to pass lint checks or that I simply overlooked them during the previous review. Sorry for the inconvenience.

name: sec_cm_mem_readback
desc: '''Verify the countermeasure(s) MEM.READBACK.

Test needs to be implemented, see lowRISC/opentitan-embargoed#97.
Copy link
Contributor

Choose a reason for hiding this comment

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

Please create an issue in the public repo for this and link it here.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done (#23322).

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks, I've now added the corresponding labels to take care of this for M5 hopefully.

endtask

// Enable readback feature only for non-throughput and non-sec_cm tests. The
Copy link
Contributor

Choose a reason for hiding this comment

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

Enabling it for the throughput tests is probably also something that should be tracked in a public issue.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done (#23321).

Comment on lines 97 to 105
// permanently latch readback error until reset
logic readback_error_q;
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
readback_error_q <= '0;
end else if (readback_error) begin
readback_error_q <= 1'b1;
end
end
Copy link
Contributor

Choose a reason for hiding this comment

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

This should probably be moved up into the if (EnableReadback) begin statement. Because if EnableReadback is false, we have a flop that is never updated / holds a constant value. Some tools complain about this, some optimize the flop away but it's not a clean way of doing this. Sorry for not noting that in the previous review.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done, thanks.

module tlul_sram_byte import tlul_pkg::*; #(
parameter bit EnableIntg = 0, // Enable integrity handling at byte level
parameter int Outstanding = 1
module tlul_sram_byte import tlul_pkg::*,prim_mubi_pkg::*; #(
Copy link
Contributor

Choose a reason for hiding this comment

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

Please don't do import prim_mubi_pkg::* as a whole. It's against our design style guide. Instead,

  • Import only those constants you really need, and
  • Import them inside the body of the module (not the parameter list).

I quickly checked the repo. Most cases where prim_mubi_pkg is imported as a whole using the wildcard import is in DV files (we do have different style guide rules for those). There are very few RTL files doing wildcard imports of packages from different IPs / prims but it's not good practice. We should clean this up after the tapeout.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, the majority of modules only import the needed constant but some modules (e.g., KMAC) do prim_mubi_pkg::*. Accidentally, I've used one of these modules as a template.

I've corrected the import based on your suggestion, thanks!

logic [top_pkg::TL_DBW-1:0] a_mask;
logic [top_pkg::TL_DW-1:0] a_data;
tl_a_user_t a_user;
} tl_txn_data_t;
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not your fault (you just moved this code) but according to line 618, some of these signals are flopped (in the FIFO) but not used:

    logic unused_held_data;
    assign unused_held_data = ^{held_data.a_address[AccessSize-1:0],
                                held_data.a_user.data_intg,
                                held_data.a_size};

This PR would be a good opportunity to remove these unnecessary flops and save some area.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for the comment. Actually, we need all the data stored inside held_data (a_address, a_user and a_size) in the readback mode. So unused_held_data is not needed, hence, I removed it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for taking a look at this. Removing the unused signals is then what should be done indeed :-)

stall_host = 1'b1;

// Wait until there is a single ongoing transaction.
if (pending_txn_cnt == $bits(pending_txn_cnt)'(1)) begin
Copy link
Contributor

Choose a reason for hiding this comment

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

$bits(pending_txn_cnt)'(1)) may be problematic. We mostly use $bits in parameter definitions in our code base. Instead, I suggest to define a local parameter where you use this function and then you use that parameter in the code to perform the width extension, i.e.,

localparam int unsigned PendingTxnCntW = prim_util_pkg::vbits(Outstanding+1);
logic [PendingTxnCntW-1:0] pending_txn_cnt;
...

if (pending_txn_cnt == PendingTxnCntW'(1)) begin

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for the comment, I've changed the RTL based on your suggestion.

When enabled with the SRAM_CTRL.READBACK CSR, the SRAM readback mode
checks each read and write to the SRAM.

On a read, the readback mode issues a second read to the same address
to check, whether the correct data was fetched from memory. On a write,
the readback mode issues a read to check, whether the data was actually
written into the memory. To avoid that the holding register is read,
the readback is delayed by one cycle.

On a mismatch, a fatal error is triggered and the STATUS.READBACK_ERROR
register is set.

To avoid RTL changes as much as possible, the readback mode is
implemented in the tlul_sram_byte module. In this module, after the
initial read or write was executed, the bus interface to the host is
stalled and the readback is performed. Due to the bus stalling, a
performance impact is expected.

Signed-off-by: Pascal Nasahl <[email protected]>
Co-authored-by: Greg Chadwick <[email protected]>
Copy link
Contributor

@vogelpi vogelpi 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 addressing the additional feedback. This looks great!

@andreaskurth
Copy link
Contributor

The one failing CI check (CW310 Test ROM) seems to be unrelated to this PR; all other checks passed --> merging

@andreaskurth andreaskurth merged commit ee5f4a1 into lowRISC:master May 26, 2024
30 of 32 checks passed
@nasahlpa nasahlpa deleted the sram_readback branch May 26, 2024 15:56
nasahlpa added a commit to nasahlpa/ibex that referenced this pull request May 28, 2024
This commit updates the RAM ports inside ibex_top to reflect recent
changes introduced with lowRISC/opentitan#23212 (SRAM readback mode).

Signed-off-by: Pascal Nasahl <[email protected]>
nasahlpa added a commit to nasahlpa/opentitan that referenced this pull request May 30, 2024
This commit adds the DIF functions for the readback mode (c.f.
lowRISC#23212)and a basic test.

Closes lowRISC#23365

Signed-off-by: Pascal Nasahl <[email protected]>
nasahlpa added a commit to nasahlpa/opentitan that referenced this pull request May 30, 2024
This commit adds the DIF functions for the readback mode (c.f.
lowRISC#23212) and a basic test.

Closes lowRISC#23365

Signed-off-by: Pascal Nasahl <[email protected]>
nasahlpa added a commit to nasahlpa/opentitan that referenced this pull request May 30, 2024
This commit adds the DIF functions for the readback mode (c.f.
lowRISC#23212) and a basic test.

Closes lowRISC#23365

Signed-off-by: Pascal Nasahl <[email protected]>
nasahlpa added a commit to nasahlpa/ibex that referenced this pull request Jun 4, 2024
This commit updates the RAM ports inside ibex_top to reflect recent
changes introduced with lowRISC/opentitan#23212 (SRAM readback mode).

Signed-off-by: Pascal Nasahl <[email protected]>
GregAC pushed a commit to lowRISC/ibex that referenced this pull request Jun 6, 2024
This commit updates the RAM ports inside ibex_top to reflect recent
changes introduced with lowRISC/opentitan#23212 (SRAM readback mode).

Signed-off-by: Pascal Nasahl <[email protected]>
vogelpi pushed a commit that referenced this pull request Jul 8, 2024
This commit adds the DIF functions for the readback mode (c.f.
#23212) and a basic test.

Closes #23365

Signed-off-by: Pascal Nasahl <[email protected]>
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.

3 participants