[dv] Allow using memutil_dpi_scrambled even without prim_ram_1p_scr
This is not going to be very useful at runtime, but we want to be able
to build things that may or may not use prim_ram_1p_scr, depending on
a parameter. If we're using it, we'll want to use this library.
Since fusesoc can't do things like "include this file iff parameter P
has value V", we'll need to include the library unconditionally.
Unfortunately, that then means Verilator simulations don't
link (because prim_ram_1p_scr and its DPI helper functions get
discarded from the design). Making the symbol weak moves the
resolution check to runtime, fixing things.
Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
diff --git a/hw/dv/verilator/cpp/scrambled_ecc32_mem_area.cc b/hw/dv/verilator/cpp/scrambled_ecc32_mem_area.cc
index 37ea6b1..4f7fc71 100644
--- a/hw/dv/verilator/cpp/scrambled_ecc32_mem_area.cc
+++ b/hw/dv/verilator/cpp/scrambled_ecc32_mem_area.cc
@@ -81,12 +81,27 @@
return width;
}
+// These functions come from SV code, exposed over DPI. They are defined inside
+// a module (prim_ram1p_scr) and, awkwardly, if a design doesn't happen to use
+// that module then some simulators (Verilator!) will discard it, together with
+// the DPI functions.
+//
+// We'd like to be able to use the memutil_dpi_scrambled.core whether or not we
+// actually instantiated prim_ram1p_scr: we'll just spit out an error if we
+// call GetScrambleKey() or GetScrambleNonce() if we didn't instantiate it. To
+// make this work, we mark both symbols weak.
extern "C" {
-int simutil_get_scramble_key(svBitVecVal *key);
-int simutil_get_scramble_nonce(svBitVecVal *nonce);
+int __attribute__((weak)) simutil_get_scramble_key(svBitVecVal *key);
+int __attribute__((weak)) simutil_get_scramble_nonce(svBitVecVal *nonce);
}
std::vector<uint8_t> ScrambledEcc32MemArea::GetScrambleKey() const {
+ if (!simutil_get_scramble_key) {
+ throw std::runtime_error(
+ "No definition of simutil_get_scramble_key. "
+ "Does the design actually use prim_ram1p_scr?");
+ }
+
SVScoped scoped(scr_scope_);
svBitVecVal key_minibuf[((kPrinceWidthByte * 2) + 3) / 4];
@@ -102,6 +117,12 @@
std::vector<uint8_t> ScrambledEcc32MemArea::GetScrambleNonce() const {
assert(GetNonceWidthByte() <= kScrMaxNonceWidthByte);
+ if (!simutil_get_scramble_nonce) {
+ throw std::runtime_error(
+ "No definition of simutil_get_scramble_nonce. "
+ "Does the design actually use prim_ram1p_scr?");
+ }
+
SVScoped scoped(scr_scope_);
svBitVecVal nonce_minibuf[(kScrMaxNonceWidthByte + 3) / 4];