[prim] Increase maximum width for prim_util_memload to 312
Signed-off-by: Greg Chadwick <gac@lowrisc.org>
diff --git a/hw/dv/verilator/cpp/dpi_memutil.cc b/hw/dv/verilator/cpp/dpi_memutil.cc
index 7e348af..0b6e2a2 100644
--- a/hw/dv/verilator/cpp/dpi_memutil.cc
+++ b/hw/dv/verilator/cpp/dpi_memutil.cc
@@ -245,12 +245,13 @@
// be caught at this function's callsite.
SVScoped scoped(m.location.data());
- // This "mini buffer" is used to transfer each write to SystemVerilog. It's
- // not massively efficient, but doing so ensures that we pass 256 bits (32
- // bytes) of initialised data each time. This is for simutil_set_mem (defined
- // in prim_util_memload.svh), whose "val" argument has SystemVerilog type bit
- // [255:0].
- uint8_t minibuf[32];
+ // This "mini buffer" is used to transfer each write to SystemVerilog.
+ // `simutil_set_mem` takes a fixed 312 bit vector but it will only use the
+ // bits required for the RAM width. For example for a 32-bit wide RAM only
+ // elements 3 - 0 of `minibuf` will be written to memory. The simulator may
+ // still read bits from minibuf it does not use so we must use a fixed
+ // allocation of the full bit vector size to avoid out of bounds access.
+ uint8_t minibuf[39];
memset(minibuf, 0, sizeof minibuf);
assert(m.width_byte <= sizeof minibuf);
diff --git a/hw/ip/otbn/dv/model/otbn_model.cc b/hw/ip/otbn/dv/model/otbn_model.cc
index 0cc4b5f..351a704 100644
--- a/hw/ip/otbn/dv/model/otbn_model.cc
+++ b/hw/ip/otbn/dv/model/otbn_model.cc
@@ -104,10 +104,10 @@
SVScoped scoped(scope);
// simutil_get_mem passes data as a packed array of svBitVecVal words. It
- // only works for memories of size at most 256 bits, so we can just allocate
- // 256/8 = 32 bytes as 32/sizeof(svBitVecVal) words on the stack.
- assert(word_size <= 256 / 8);
- svBitVecVal buf[256 / 8 / sizeof(svBitVecVal)];
+ // only works for memories of size at most 312 bits, so we can just allocate
+ // 312/8 = 39 bytes as 39/sizeof(svBitVecVal) words on the stack.
+ assert(word_size <= 312 / 8);
+ svBitVecVal buf[312 / 8 / sizeof(svBitVecVal)];
std::vector<uint8_t> ret;
@@ -135,8 +135,8 @@
assert(num_words * word_size == data.size());
// See get_sim_memory for why this array is sized like this.
- assert(word_size <= 256 / 8);
- svBitVecVal buf[256 / 8 / sizeof(svBitVecVal)];
+ assert(word_size <= 312 / 8);
+ svBitVecVal buf[312 / 8 / sizeof(svBitVecVal)];
for (size_t w = 0; w < num_words; w++) {
const uint8_t *p = &data[w * word_size];
diff --git a/hw/ip/prim/rtl/prim_util_memload.svh b/hw/ip/prim/rtl/prim_util_memload.svh
index 2141c7c..d4537e4 100644
--- a/hw/ip/prim/rtl/prim_util_memload.svh
+++ b/hw/ip/prim/rtl/prim_util_memload.svh
@@ -13,7 +13,11 @@
* - A parameter `Width` giving the memory width (word size) in bit.
* - A parameter `Depth` giving the memory depth in words.
* - A parameter `MemInitFile` with a file path of a VMEM file to be loaded into
-* the memory if not empty.
+ * the memory if not empty.
+ *
+ * Note this works with memories up to a maximum width of 312 bits. Should this maximum width be
+ * increased all of the `simutil_set_mem` and `simutil_get_mem` call sites must be found (e.g. using
+ * git grep) and adjusted appropriately.
*/
`ifndef SYNTHESIS
@@ -29,10 +33,10 @@
// Returns 1 (true) for success, 0 (false) for errors.
export "DPI-C" function simutil_set_mem;
- function int simutil_set_mem(input int index, input bit [255:0] val);
+ function int simutil_set_mem(input int index, input bit [311:0] val);
- // Function will only work for memories <= 256 bits
- if (Width > 256) begin
+ // Function will only work for memories <= 312 bits
+ if (Width > 312) begin
return 0;
end
@@ -47,10 +51,10 @@
// Function for getting a specific element in |mem|
export "DPI-C" function simutil_get_mem;
- function int simutil_get_mem(input int index, output bit [255:0] val);
+ function int simutil_get_mem(input int index, output bit [311:0] val);
- // Function will only work for memories <= 256 bits
- if (Width > 256) begin
+ // Function will only work for memories <= 312 bits
+ if (Width > 312) begin
return 0;
end