Skip to content

Commit

Permalink
[sram_ctrl] Add readback feature
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
nasahlpa and GregAC committed May 22, 2024
1 parent 7b4204f commit 72e0d3d
Show file tree
Hide file tree
Showing 48 changed files with 1,413 additions and 473 deletions.
1 change: 1 addition & 0 deletions doc/contributing/hw/comportability/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ The following standardised countermeasures are defined:
| REGREN | A register write enable is used to protect the asset from read access | CONFIG, MEM
| SCRAMBLE | The asset is scrambled | CONFIG, MEM
| INTEGRITY | The asset has integrity protection from a computed value such as a checksum | CONFIG, REG, MEM
| READBACK | A readback check is performed to validate that the asset has been correctly modified or fetched | MEM
| CONSISTENCY | This asset is checked for consistency other than by associating integrity bits | CTRL, RST
| DIGEST | Similar to integrity but more computationally intensive, implying a full hash function | CONFIG, REG, MEM
| LC_GATED | Access to the asset is qualified by life-cycle state | REG, MEM, CONSTANTS, CONFIG
Expand Down
24 changes: 14 additions & 10 deletions hw/dv/sv/sim_sram/sim_sram.sv
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,20 @@ module sim_sram #(
.tl_i(tl_in_i),
.tl_o(tl_in_o),

.req_o (sram_req),
.gnt_i (1'b1),
.we_o (sram_we),
.addr_o (sram_addr),
.wdata_o (sram_wdata),
.wmask_o (sram_wmask),
.rdata_i (sram_rdata),
.rvalid_i (sram_rvalid),
.rerror_i (2'b00),
.rmw_in_progress_o()
.req_o (sram_req),
.gnt_i (1'b1),
.we_o (sram_we),
.addr_o (sram_addr),
.wdata_o (sram_wdata),
.wmask_o (sram_wmask),
.rdata_i (sram_rdata),
.rvalid_i (sram_rvalid),
.rerror_i (2'b00),
.compound_txn_in_progress_o (),
.readback_en_i (prim_mubi_pkg::MuBi4False),
.readback_error_o (),
.wr_collision_i (1'b0),
.write_pending_i (1'b0)
);

prim_ram_1p #(
Expand Down
35 changes: 20 additions & 15 deletions hw/ip/hmac/rtl/hmac.sv
Original file line number Diff line number Diff line change
Expand Up @@ -560,21 +560,26 @@ module hmac
) u_tlul_adapter (
.clk_i,
.rst_ni,
.tl_i (tl_win_h2d),
.tl_o (tl_win_d2h),
.en_ifetch_i (prim_mubi_pkg::MuBi4False),
.req_o (msg_fifo_req ),
.req_type_o ( ),
.gnt_i (msg_fifo_gnt ),
.we_o (msg_fifo_we ),
.addr_o ( ), // Doesn't care the address other than sub-word
.wdata_o (msg_fifo_wdata ),
.wmask_o (msg_fifo_wmask ),
.intg_error_o ( ),
.rdata_i (msg_fifo_rdata ),
.rvalid_i (msg_fifo_rvalid),
.rerror_i (msg_fifo_rerror),
.rmw_in_progress_o()
.tl_i (tl_win_h2d),
.tl_o (tl_win_d2h),
.en_ifetch_i (prim_mubi_pkg::MuBi4False),
.req_o (msg_fifo_req ),
.req_type_o ( ),
.gnt_i (msg_fifo_gnt ),
.we_o (msg_fifo_we ),
.addr_o ( ), // Doesn't care the address
// other than sub-word
.wdata_o (msg_fifo_wdata ),
.wmask_o (msg_fifo_wmask ),
.intg_error_o ( ),
.rdata_i (msg_fifo_rdata ),
.rvalid_i (msg_fifo_rvalid),
.rerror_i (msg_fifo_rerror),
.compound_txn_in_progress_o (),
.readback_en_i (prim_mubi_pkg::MuBi4False),
.readback_error_o (),
.wr_collision_i (1'b0),
.write_pending_i (1'b0)
);

// TL-UL to MSG_FIFO byte write handling
Expand Down
36 changes: 20 additions & 16 deletions hw/ip/kmac/rtl/kmac.sv
Original file line number Diff line number Diff line change
Expand Up @@ -1004,22 +1004,26 @@ module kmac
) u_tlul_adapter_msgfifo (
.clk_i,
.rst_ni,
.en_ifetch_i (prim_mubi_pkg::MuBi4False),
.tl_i (tl_win_h2d[WinMsgFifo]),
.tl_o (tl_win_d2h[WinMsgFifo]),

.req_o (tlram_req),
.req_type_o (),
.gnt_i (tlram_gnt),
.we_o (tlram_we ),
.addr_o (tlram_addr),
.wdata_o (tlram_wdata),
.wmask_o (tlram_wmask),
.intg_error_o ( ),
.rdata_i (tlram_rdata),
.rvalid_i (tlram_rvalid),
.rerror_i (tlram_rerror),
.rmw_in_progress_o()
.en_ifetch_i (prim_mubi_pkg::MuBi4False),
.tl_i (tl_win_h2d[WinMsgFifo]),
.tl_o (tl_win_d2h[WinMsgFifo]),

.req_o (tlram_req),
.req_type_o (),
.gnt_i (tlram_gnt),
.we_o (tlram_we ),
.addr_o (tlram_addr),
.wdata_o (tlram_wdata),
.wmask_o (tlram_wmask),
.intg_error_o ( ),
.rdata_i (tlram_rdata),
.rvalid_i (tlram_rvalid),
.rerror_i (tlram_rerror),
.compound_txn_in_progress_o (),
.readback_en_i (prim_mubi_pkg::MuBi4False),
.readback_error_o (),
.wr_collision_i (1'b0),
.write_pending_i (1'b0)
);

assign sw_msg_valid = tlram_req & tlram_we ;
Expand Down
30 changes: 17 additions & 13 deletions hw/ip/kmac/rtl/kmac_staterd.sv
Original file line number Diff line number Diff line change
Expand Up @@ -64,19 +64,23 @@ module kmac_staterd

.tl_i,
.tl_o,
.en_ifetch_i (prim_mubi_pkg::MuBi4False),
.req_o (tlram_req),
.req_type_o (),
.gnt_i (tlram_gnt),
.we_o (tlram_we ),
.addr_o (tlram_addr),
.wdata_o (unused_tlram_wdata),
.wmask_o (unused_tlram_wmask),
.intg_error_o (),
.rdata_i (tlram_rdata),
.rvalid_i (tlram_rvalid),
.rerror_i (tlram_rerror),
.rmw_in_progress_o()
.en_ifetch_i (prim_mubi_pkg::MuBi4False),
.req_o (tlram_req),
.req_type_o (),
.gnt_i (tlram_gnt),
.we_o (tlram_we ),
.addr_o (tlram_addr),
.wdata_o (unused_tlram_wdata),
.wmask_o (unused_tlram_wmask),
.intg_error_o (),
.rdata_i (tlram_rdata),
.rvalid_i (tlram_rvalid),
.rerror_i (tlram_rerror),
.compound_txn_in_progress_o (),
.readback_en_i (prim_mubi_pkg::MuBi4False),
.readback_error_o (),
.wr_collision_i (1'b0),
.write_pending_i (1'b0)
);

always_ff @(posedge clk_i or negedge rst_ni) begin
Expand Down
86 changes: 46 additions & 40 deletions hw/ip/otbn/dv/verilator/otbn_top_sim.sv
Original file line number Diff line number Diff line change
Expand Up @@ -256,26 +256,29 @@ module otbn_top_sim (
.EnableParity ( 0 ),
.ReplicateKeyStream ( 1 )
) u_dmem (
.clk_i ( IO_CLK ),
.rst_ni ( IO_RST_N ),

.key_valid_i ( 1'b1 ),
.key_i ( TestScrambleKey ),
.nonce_i ( TestScrambleNonce ),

.req_i ( dmem_req ),
.gnt_o ( ),
.write_i ( dmem_write ),
.addr_i ( dmem_index ),
.wdata_i ( dmem_wdata ),
.wmask_i ( dmem_wmask ),
.intg_error_i ( 1'b0 ),

.rdata_o ( dmem_rdata ),
.rvalid_o ( dmem_rvalid ),
.raddr_o ( ),
.rerror_o ( ),
.cfg_i ( '0 )
.clk_i ( IO_CLK ),
.rst_ni ( IO_RST_N ),

.key_valid_i ( 1'b1 ),
.key_i ( TestScrambleKey ),
.nonce_i ( TestScrambleNonce ),

.req_i ( dmem_req ),
.gnt_o ( ),
.write_i ( dmem_write ),
.addr_i ( dmem_index ),
.wdata_i ( dmem_wdata ),
.wmask_i ( dmem_wmask ),
.intg_error_i ( 1'b0 ),

.rdata_o ( dmem_rdata ),
.rvalid_o ( dmem_rvalid ),
.raddr_o ( ),
.rerror_o ( ),
.cfg_i ( '0 ),

.wr_collision_o ( ),
.write_pending_o ( )
);

// No integrity errors in Verilator testbench
Expand All @@ -296,26 +299,29 @@ module otbn_top_sim (
.DataBitsPerMask ( 39 ),
.EnableParity ( 0 )
) u_imem (
.clk_i ( IO_CLK ),
.rst_ni ( IO_RST_N ),

.key_valid_i ( 1'b1 ),
.key_i ( TestScrambleKey ),
.nonce_i ( TestScrambleNonce ),

.req_i ( imem_req ),
.gnt_o ( ),
.write_i ( 1'b0 ),
.addr_i ( imem_index ),
.wdata_i ( '0 ),
.wmask_i ( '0 ),
.intg_error_i ( 1'b0 ),

.rdata_o ( imem_rdata ),
.rvalid_o ( imem_rvalid ),
.raddr_o ( ),
.rerror_o ( ),
.cfg_i ( '0 )
.clk_i ( IO_CLK ),
.rst_ni ( IO_RST_N ),

.key_valid_i ( 1'b1 ),
.key_i ( TestScrambleKey ),
.nonce_i ( TestScrambleNonce ),

.req_i ( imem_req ),
.gnt_o ( ),
.write_i ( 1'b0 ),
.addr_i ( imem_index ),
.wdata_i ( '0 ),
.wmask_i ( '0 ),
.intg_error_i ( 1'b0 ),

.rdata_o ( imem_rdata ),
.rvalid_o ( imem_rvalid ),
.raddr_o ( ),
.rerror_o ( ),
.cfg_i ( '0 ),

.wr_collision_o ( ),
.write_pending_o ( )
);

// When OTBN is done let a few more cycles run then finish simulation
Expand Down
86 changes: 52 additions & 34 deletions hw/ip/otbn/rtl/otbn.sv
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ module otbn
logic imem_req;
logic imem_gnt;
logic imem_write;
logic imem_wr_collision;
logic imem_wpending;
logic [ImemIndexWidth-1:0] imem_index;
logic [38:0] imem_wdata;
logic [38:0] imem_wmask;
Expand Down Expand Up @@ -353,7 +355,10 @@ module otbn
.rvalid_o(imem_rvalid),
.raddr_o (),
.rerror_o(),
.cfg_i (ram_cfg_i)
.cfg_i (ram_cfg_i),

.wr_collision_o (imem_wr_collision),
.write_pending_o (imem_wpending)
);

// We should never see a request that doesn't get granted. A fatal error is raised if this occurs.
Expand All @@ -374,22 +379,26 @@ module otbn
.SecFifoPtr (1) // SEC_CM: TLUL_FIFO.CTR.REDUN
) u_tlul_adapter_sram_imem (
.clk_i,
.rst_ni (rst_n),
.tl_i (tl_win_h2d[TlWinImem]),
.tl_o (tl_win_d2h[TlWinImem]),
.en_ifetch_i (MuBi4False),
.req_o (imem_req_bus),
.req_type_o (),
.gnt_i (imem_gnt_bus),
.we_o (imem_write_bus),
.addr_o (imem_index_bus),
.wdata_o (imem_wdata_bus),
.wmask_o (imem_wmask_bus),
.intg_error_o (imem_bus_intg_violation),
.rdata_i (imem_rdata_bus),
.rvalid_i (imem_rvalid_bus),
.rerror_i (imem_rerror_bus),
.rmw_in_progress_o()
.rst_ni (rst_n),
.tl_i (tl_win_h2d[TlWinImem]),
.tl_o (tl_win_d2h[TlWinImem]),
.en_ifetch_i (MuBi4False),
.req_o (imem_req_bus),
.req_type_o (),
.gnt_i (imem_gnt_bus),
.we_o (imem_write_bus),
.addr_o (imem_index_bus),
.wdata_o (imem_wdata_bus),
.wmask_o (imem_wmask_bus),
.intg_error_o (imem_bus_intg_violation),
.rdata_i (imem_rdata_bus),
.rvalid_i (imem_rvalid_bus),
.rerror_i (imem_rerror_bus),
.compound_txn_in_progress_o (),
.readback_en_i (prim_mubi_pkg::MuBi4False),
.readback_error_o (),
.wr_collision_i (imem_wr_collision),
.write_pending_i (imem_wpending)
);


Expand Down Expand Up @@ -519,6 +528,8 @@ module otbn
logic [31:0] dmem_wdata_narrow_bus;
logic [top_pkg::TL_DBW-1:0] dmem_byte_mask_bus;
logic dmem_rvalid_bus;
logic dmem_wr_collision;
logic dmem_wpending;
logic [1:0] dmem_rerror_bus;

logic dmem_bus_intg_violation;
Expand Down Expand Up @@ -556,7 +567,10 @@ module otbn
.rvalid_o(dmem_rvalid),
.raddr_o (),
.rerror_o(),
.cfg_i (ram_cfg_i)
.cfg_i (ram_cfg_i),

.wr_collision_o (dmem_wr_collision),
.write_pending_o (dmem_wpending)
);

// We should never see a request that doesn't get granted. A fatal error is raised if this occurs.
Expand Down Expand Up @@ -613,22 +627,26 @@ module otbn
.SecFifoPtr (1) // SEC_CM: TLUL_FIFO.CTR.REDUN
) u_tlul_adapter_sram_dmem (
.clk_i,
.rst_ni (rst_n),
.tl_i (tl_win_h2d[TlWinDmem]),
.tl_o (tl_win_d2h[TlWinDmem]),
.en_ifetch_i (MuBi4False),
.req_o (dmem_req_bus),
.req_type_o (),
.gnt_i (dmem_gnt_bus),
.we_o (dmem_write_bus),
.addr_o (dmem_index_bus),
.wdata_o (dmem_wdata_bus),
.wmask_o (dmem_wmask_bus),
.intg_error_o (dmem_bus_intg_violation),
.rdata_i (dmem_rdata_bus),
.rvalid_i (dmem_rvalid_bus),
.rerror_i (dmem_rerror_bus),
.rmw_in_progress_o()
.rst_ni (rst_n),
.tl_i (tl_win_h2d[TlWinDmem]),
.tl_o (tl_win_d2h[TlWinDmem]),
.en_ifetch_i (MuBi4False),
.req_o (dmem_req_bus),
.req_type_o (),
.gnt_i (dmem_gnt_bus),
.we_o (dmem_write_bus),
.addr_o (dmem_index_bus),
.wdata_o (dmem_wdata_bus),
.wmask_o (dmem_wmask_bus),
.intg_error_o (dmem_bus_intg_violation),
.rdata_i (dmem_rdata_bus),
.rvalid_i (dmem_rvalid_bus),
.rerror_i (dmem_rerror_bus),
.compound_txn_in_progress_o (),
.readback_en_i (prim_mubi_pkg::MuBi4False),
.readback_error_o (),
.wr_collision_i (dmem_wr_collision),
.write_pending_i (dmem_wpending)
);

// Mux core and bus access into dmem
Expand Down
Loading

0 comments on commit 72e0d3d

Please sign in to comment.