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 29, 2025
1 parent 293f57a commit cbafd0f
Show file tree
Hide file tree
Showing 4 changed files with 72 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
36 changes: 29 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 @@ -35,6 +35,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 +88,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,18 +111,26 @@ 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;
if (row_adapter) begin
this.row_adapter = row_adapter;
end else begin
this.row_adapter = new();
end

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.row_adapter.get_num_extra_bits();
this.err_detection_scheme = err_detection_scheme;
this.num_prince_rounds_half = num_prince_rounds_half;

// Check if the inferred path to each tile (or the whole memory) really exist
Expand Down Expand Up @@ -290,6 +305,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 +419,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 +472,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
1 change: 1 addition & 0 deletions hw/dv/sv/mem_bkdr_util/mem_bkdr_util_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ package mem_bkdr_util_pkg;
`include "dv_macros.svh"

// sources
`include "mem_bkdr_util_row_adapter.sv"
`include "mem_bkdr_util.sv"

endpackage
41 changes: 41 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,41 @@
// 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;

// A row might have additional extra bits
protected uint32_t num_extra_bits = 0;

// Return the number of extra bits of this row architecture
function uint32_t get_num_extra_bits();
return num_extra_bits;
endfunction

// 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 cbafd0f

Please sign in to comment.