Skip to content

Commit

Permalink
[membkdr] Provide a row 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 4c7e9aa
Show file tree
Hide file tree
Showing 14 changed files with 136 additions and 33 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
32 changes: 25 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 @@ -82,6 +88,9 @@ class mem_bkdr_util extends uvm_object;
//
// err_detection_scheme The error detection scheme that is implemented for the memory.
//
// row_adapter Adapter to access the internal row of a memory. Integrators can
// provide a custom adapter for a different memory architecture.
//
// Optional arguments:
//
// num_prince_rounds_half The number of rounds of PRINCE used to scramble the memory. This is
Expand All @@ -104,18 +113,20 @@ 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,
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;

// Check if the inferred path to each tile (or the whole memory) really exist
Expand Down Expand Up @@ -290,6 +301,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 +415,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 +468,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
2 changes: 1 addition & 1 deletion hw/ip/otbn/dv/uvm/env/otbn_env_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ package otbn_env_pkg;
import push_pull_agent_pkg::*;
import otbn_model_agent_pkg::*;
import otbn_memutil_pkg::*;
import mem_bkdr_util_pkg::mem_bkdr_util;
import mem_bkdr_util_pkg::mem_bkdr_util_row_adapter;
import prim_util_pkg::vbits;
import prim_mubi_pkg::*;
import key_sideload_agent_pkg::*;
Expand Down
8 changes: 6 additions & 2 deletions hw/ip/otbn/dv/uvm/tb.sv
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module tb;
import uvm_pkg::*;
import dv_utils_pkg::*;
import mem_bkdr_util_pkg::mem_bkdr_util;
import mem_bkdr_util_pkg::mem_bkdr_util_row_adapter;
import otbn_env_pkg::*;
import otbn_test_pkg::*;
import otbn_pkg::NGpr, otbn_pkg::NWdr;
Expand Down Expand Up @@ -344,20 +345,23 @@ module tb;
// Instantiate mem_bkdr_util objects to allow access to IMEM and DMEM
//
// Note that n_bits is the number of bits in the memory, including ECC check bits.
mem_bkdr_util_row_adapter row_adapter = new();
imem_util = new(.name ("imem_util"),
.path ({"tb.dut.u_imem.u_prim_ram_1p_adv.gen_ram_inst[0].",
"u_mem.gen_generic.u_impl_generic.mem"}),
.depth (ImemSizeByte / 4),
.n_bits (ImemSizeByte / 4 * 39),
.err_detection_scheme (mem_bkdr_util_pkg::EccInv_39_32));
.err_detection_scheme (mem_bkdr_util_pkg::EccInv_39_32),
.row_adapter(row_adapter));

// DMEM is twice as big as the bus-accessible part
dmem_util = new(.name ("dmem_util"),
.path ({"tb.dut.u_dmem.u_prim_ram_1p_adv.gen_ram_inst[0].",
"u_mem.gen_generic.u_impl_generic.mem"}),
.depth (DmemSizeByte / 32),
.n_bits (DmemSizeByte / 32 * 312),
.err_detection_scheme (mem_bkdr_util_pkg::EccInv_39_32));
.err_detection_scheme (mem_bkdr_util_pkg::EccInv_39_32),
.row_adapter(row_adapter));

uvm_config_db#(mem_bkdr_util)::set(null, "*.env", imem_util.get_name(), imem_util);
uvm_config_db#(mem_bkdr_util)::set(null, "*.env", dmem_util.get_name(), dmem_util);
Expand Down
5 changes: 4 additions & 1 deletion hw/ip/rom_ctrl/dv/tb.sv
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module tb;
import rom_ctrl_env_pkg::*;
import rom_ctrl_test_pkg::*;
import mem_bkdr_util_pkg::mem_bkdr_util;
import mem_bkdr_util_pkg::mem_bkdr_util_row_adapter;

// macro includes
`include "uvm_macros.svh"
Expand Down Expand Up @@ -78,12 +79,14 @@ module tb;
tb.dut.gen_rom_scramble_enabled.u_rom.u_rom.u_prim_rom.gen_generic.u_impl_generic.mem

initial begin
mem_bkdr_util_row_adapter row_adapter = new();
mem_bkdr_util m_mem_bkdr_util;
m_mem_bkdr_util = new(.name ("mem_bkdr_util"),
.path (`DV_STRINGIFY(`ROM_CTRL_MEM_HIER)),
.depth ($size(`ROM_CTRL_MEM_HIER)),
.n_bits($bits(`ROM_CTRL_MEM_HIER)),
.err_detection_scheme(mem_bkdr_util_pkg::EccInv_39_32));
.err_detection_scheme(mem_bkdr_util_pkg::EccInv_39_32),
.row_adapter(row_adapter));

// drive clk and rst_n from clk_if
clk_rst_if.set_active();
Expand Down
5 changes: 4 additions & 1 deletion hw/ip/sram_ctrl/dv/tb.sv
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module tb;
import sram_ctrl_env_pkg::*;
import sram_ctrl_test_pkg::*;
import mem_bkdr_util_pkg::mem_bkdr_util;
import mem_bkdr_util_pkg::mem_bkdr_util_row_adapter;

// macro includes
`include "uvm_macros.svh"
Expand Down Expand Up @@ -107,6 +108,7 @@ module tb;
tb.dut.u_prim_ram_1p_scr.u_prim_ram_1p_adv.gen_ram_inst[0].u_mem.gen_generic.u_impl_generic.mem

initial begin
mem_bkdr_util_row_adapter row_adapter = new();
mem_bkdr_util m_mem_bkdr_util;
m_mem_bkdr_util = new(.name ("mem_bkdr_util"),
.path (`DV_STRINGIFY(`SRAM_CTRL_MEM_HIER)),
Expand All @@ -115,7 +117,8 @@ module tb;
// Due to the end-to-end bus integrity scheme, the memory primitive itself
// does not encode and decode the redundancy information.
.err_detection_scheme(mem_bkdr_util_pkg::ErrDetectionNone),
.num_prince_rounds_half(`NUM_PRINCE_ROUNDS_HALF));
.num_prince_rounds_half(`NUM_PRINCE_ROUNDS_HALF),
.row_adapter(row_adapter));

// drive clk and rst_n from clk_if
clk_rst_if.set_active();
Expand Down
7 changes: 6 additions & 1 deletion hw/ip_templates/flash_ctrl/dv/tb/tb.sv
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module tb;
import flash_ctrl_env_pkg::*;
import flash_ctrl_test_pkg::*;
import mem_bkdr_util_pkg::mem_bkdr_util;
import mem_bkdr_util_pkg::mem_bkdr_util_row_adapter;

// macro includes
`include "uvm_macros.svh"
Expand Down Expand Up @@ -262,13 +263,15 @@ module tb;
flash_dv_part_e part = part.first();

initial begin
mem_bkdr_util_row_adapter row_adapter = new();
flash_mem_bkdr_util m_mem_bkdr_util;
m_mem_bkdr_util = new(
.name($sformatf("mem_bkdr_util[%0s][%0d]", part.name(), i)),
.path(`FLASH_DATA_MEM_HIER_STR(i)),
.depth($size(`FLASH_DATA_MEM_HIER(i))),
.n_bits($bits(`FLASH_DATA_MEM_HIER(i))),
.err_detection_scheme(mem_bkdr_util_pkg::EccHamming_76_68)
.row_adapter(row_adapter)
);
uvm_config_db#(mem_bkdr_util)::set(null, "*.env", m_mem_bkdr_util.get_name(),
m_mem_bkdr_util);
Expand All @@ -277,13 +280,15 @@ module tb;

for (genvar j = 0; j < flash_ctrl_pkg::InfoTypes; j++) begin : gen_each_info_type
initial begin
mem_bkdr_util_row_adapter row_adapter = new();
flash_mem_bkdr_util m_mem_bkdr_util;
m_mem_bkdr_util = new(
.name($sformatf("mem_bkdr_util[%0s][%0d]", part.name(), i)),
.path(`FLASH_INFO_MEM_HIER_STR(i, j)),
.depth($size(`FLASH_INFO_MEM_HIER(i, j))),
.n_bits($bits(`FLASH_INFO_MEM_HIER(i, j))),
.err_detection_scheme(mem_bkdr_util_pkg::EccHamming_76_68)
.err_detection_scheme(mem_bkdr_util_pkg::EccHamming_76_68),
.row_adapter(row_adapter)
);
uvm_config_db#(mem_bkdr_util)::set(null, "*.env", m_mem_bkdr_util.get_name(),
m_mem_bkdr_util);
Expand Down
5 changes: 4 additions & 1 deletion hw/ip_templates/otp_ctrl/dv/tb.sv
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module tb;
import otp_ctrl_test_pkg::*;
import otp_ctrl_reg_pkg::*;
import mem_bkdr_util_pkg::mem_bkdr_util;
import mem_bkdr_util_pkg::mem_bkdr_util_row_adapter;

// macro includes
`include "uvm_macros.svh"
Expand Down Expand Up @@ -186,12 +187,14 @@ module tb;
`MEM_MODULE_PATH.u_mem.gen_generic.u_impl_generic.mem

initial begin : mem_bkdr_util_gen
mem_bkdr_util_row_adapter row_adapter = new();
mem_bkdr_util m_mem_bkdr_util;
m_mem_bkdr_util = new(.name("mem_bkdr_util"),
.path(`DV_STRINGIFY(`MEM_ARRAY_PATH)),
.depth($size(`MEM_ARRAY_PATH)),
.n_bits($bits(`MEM_ARRAY_PATH)),
.err_detection_scheme(mem_bkdr_util_pkg::EccHamming_22_16));
.err_detection_scheme(mem_bkdr_util_pkg::EccHamming_22_16),
.row_adapter(row_adapter));

uvm_config_db#(mem_bkdr_util)::set(null, "*.env", "mem_bkdr_util", m_mem_bkdr_util);
end : mem_bkdr_util_gen
Expand Down
5 changes: 4 additions & 1 deletion hw/top_darjeeling/ip_autogen/otp_ctrl/dv/tb.sv
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module tb;
import otp_ctrl_test_pkg::*;
import otp_ctrl_reg_pkg::*;
import mem_bkdr_util_pkg::mem_bkdr_util;
import mem_bkdr_util_pkg::mem_bkdr_util_row_adapter;

// macro includes
`include "uvm_macros.svh"
Expand Down Expand Up @@ -186,12 +187,14 @@ module tb;
`MEM_MODULE_PATH.u_mem.gen_generic.u_impl_generic.mem

initial begin : mem_bkdr_util_gen
mem_bkdr_util_row_adapter row_adapter = new();
mem_bkdr_util m_mem_bkdr_util;
m_mem_bkdr_util = new(.name("mem_bkdr_util"),
.path(`DV_STRINGIFY(`MEM_ARRAY_PATH)),
.depth($size(`MEM_ARRAY_PATH)),
.n_bits($bits(`MEM_ARRAY_PATH)),
.err_detection_scheme(mem_bkdr_util_pkg::EccHamming_22_16));
.err_detection_scheme(mem_bkdr_util_pkg::EccHamming_22_16),
.row_adapter(row_adapter));

uvm_config_db#(mem_bkdr_util)::set(null, "*.env", "mem_bkdr_util", m_mem_bkdr_util);
end : mem_bkdr_util_gen
Expand Down
Loading

0 comments on commit 4c7e9aa

Please sign in to comment.