Skip to content

Commit

Permalink
[membkdr] Provide a tile adapter to access internal rows
Browse files Browse the repository at this point in the history
Signed-off-by: Robert Schilling <[email protected]>
  • Loading branch information
Razer6 committed Jan 28, 2025
1 parent 293f57a commit 036b6a6
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 7 deletions.
1 change: 1 addition & 0 deletions hw/dv/sv/mem_bkdr_util/mem_bkdr_util.core
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ filesets:
files:
- sram_scrambler_pkg.sv
- mem_bkdr_util_pkg.sv
- mem_bkdr_util_row_adapter.sv: {is_include_file: true}
- mem_bkdr_util.sv: {is_include_file: true}
- mem_bkdr_util__rom.sv: {is_include_file: true}
- mem_bkdr_util__sram.sv: {is_include_file: true}
Expand Down
38 changes: 31 additions & 7 deletions hw/dv/sv/mem_bkdr_util/mem_bkdr_util.sv
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

`include "mem_bkdr_util_row_adapter.sv"

// Provides a mechanism to manipulate and access a memory instance in the design via backdoor.
//
// This is a class based implementation, which on initialization (`new()`) takes the path to the
Expand Down Expand Up @@ -35,6 +37,10 @@ class mem_bkdr_util extends uvm_object;
// Indicates the error detection scheme implemented for this memory.
protected err_detection_e err_detection_scheme = ErrDetectionNone;

// Adapter to access the underlying memory organization
// Integrators can provide a custom row adapter for their SRAM primitives
protected mem_bkdr_util_row_adapter row_adapter;

// Convenience macro to check if ECC / parity is enabled.
`define HAS_ECC (!(err_detection_scheme inside {ErrDetectionNone, ParityEven, ParityOdd}))
`define HAS_PARITY (err_detection_scheme inside {ParityEven, ParityOdd})
Expand Down Expand Up @@ -84,6 +90,9 @@ class mem_bkdr_util extends uvm_object;
//
// Optional arguments:
//
// row_adapter Adapter to access the internal row of a memory. Integrators can
// provide a custom adapter for a different memory architecture.
//
// num_prince_rounds_half The number of rounds of PRINCE used to scramble the memory. This is
// used for scrambled memories. This defaults to 3.
//
Expand All @@ -104,20 +113,28 @@ class mem_bkdr_util extends uvm_object;
// memory.
function new(string name = "", string path, int unsigned depth,
longint unsigned n_bits, err_detection_e err_detection_scheme,
mem_bkdr_util_row_adapter row_adapter = null,
uint32_t num_prince_rounds_half = 3,
uint32_t extra_bits_per_subword = 0, uint32_t system_base_addr = 0,
string tiling_path = "", uint32_t tile_depth = depth);
super.new(name);
`DV_CHECK_FATAL(!(n_bits % depth), "n_bits must be divisible by depth.")

this.path = path;
this.tiling_path = tiling_path;
this.depth = depth;
this.tile_depth = tile_depth;
this.width = n_bits / depth;
this.err_detection_scheme = err_detection_scheme;
this.path = path;
this.tiling_path = tiling_path;
this.row_adapter = row_adapter;
this.depth = depth;
this.tile_depth = tile_depth;
this.width = n_bits / depth;
this.err_detection_scheme = err_detection_scheme;
this.num_prince_rounds_half = num_prince_rounds_half;

if (row_adapter) begin
this.row_adapter = row_adapter;
end else begin
this.row_adapter = new();
end

// Check if the inferred path to each tile (or the whole memory) really exist
for (int i = 0; i < (depth + tile_depth - 1) / tile_depth; i++) begin
string full_path = get_full_path(i);
Expand Down Expand Up @@ -290,6 +307,7 @@ class mem_bkdr_util extends uvm_object;
index = addr >> addr_lsb;
ram_tile = index / tile_depth;
res = uvm_hdl_read($sformatf("%0s[%0d]", get_full_path(ram_tile), index), data);
data = row_adapter.read_row(data);
`DV_CHECK_EQ(res, 1, $sformatf("uvm_hdl_read failed at index %0d", index))
return data;
endfunction
Expand Down Expand Up @@ -403,6 +421,7 @@ class mem_bkdr_util extends uvm_object;
if (!check_addr_valid(addr)) return;
index = addr >> addr_lsb;
ram_tile = index / tile_depth;
data = row_adapter.write_row(data);
res = uvm_hdl_deposit($sformatf("%0s[%0d]", get_full_path(ram_tile), index), data);
`DV_CHECK_EQ(res, 1, $sformatf("uvm_hdl_deposit failed at index %0d", index))
endfunction
Expand Down Expand Up @@ -455,9 +474,14 @@ class mem_bkdr_util extends uvm_object;

// this is used to write 32bit of data plus 7 raw integrity bits.
virtual function void write39integ(bit [bus_params_pkg::BUS_AW-1:0] addr, logic [38:0] data);
uvm_hdl_data_t rw_data;
`_ACCESS_CHECKS(addr, 32) // this is essentially an aligned 32bit access.
if (!check_addr_valid(addr)) return;
write(addr, data);
// Perform a read-modify-write to access the underlying memory architecture
rw_data = read(addr);
rw_data = row_adapter.access_row_data39(addr, data, rw_data);
// Note the write function takes care of interleaving, if used.
write(addr, rw_data);
endfunction

virtual function void write64(bit [bus_params_pkg::BUS_AW-1:0] addr, logic [63:0] data);
Expand Down
32 changes: 32 additions & 0 deletions hw/dv/sv/mem_bkdr_util/mem_bkdr_util_row_adapter.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

// Provide an abstract way to access the memory rows
//
// Integrators can subclass this to privide a specfic way of accessing a memory row
// and incorporate the phyical architecture.
//
class mem_bkdr_util_row_adapter;
// Translates a raw read UVM data raw from the memory in a contigious
// row of memory.
//
virtual function uvm_hdl_data_t read_row(uvm_hdl_data_t read_data);
return read_data;
endfunction

// Translates a contigious UVM data row to the internal organzation of a row
// that can be written to the memory.
//
virtual function uvm_hdl_data_t write_row(uvm_hdl_data_t write_data);
return write_data;
endfunction

// Writes a 39 bit word into the row data depending on the memory architecture
virtual function uvm_hdl_data_t access_row_data39(bit [bus_params_pkg::BUS_AW-1:0] addr,
logic [38:0] data,
uvm_hdl_data_t row_data);
row_data[38:0] = data;
return row_data;
endfunction
endclass

0 comments on commit 036b6a6

Please sign in to comment.