[otbn,dv] Declare model DPI imports in otbn_core_model module The IEEE 1800 spec says the following about svGetScope: ...this is the scope of the function's declaration site, not call site. but it seems that VCS feels differently :-) With VCS, calling the imported DPI function otbn_model_step() from otbn_core_model gave a scope pointing at the model. I suspect that the rule is "a package doesn't have any scope, so use the call site instead". Xcelium quite reasonably gives a scope of "otbn_model_pkg::". Unfortunately, this breaks the tests! Include the declarations into otbn_core_model directly to get things working properly with both simulators. Also, get rid of the otbn_model_pkg package entirely and update how we call the DPI functions from the model interface and UVM code. Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
diff --git a/hw/ip/otbn/dv/model/otbn_core_model.sv b/hw/ip/otbn/dv/model/otbn_core_model.sv index 1eae2e0..c69649f 100644 --- a/hw/ip/otbn/dv/model/otbn_core_model.sv +++ b/hw/ip/otbn/dv/model/otbn_core_model.sv
@@ -13,7 +13,6 @@ module otbn_core_model import otbn_pkg::*; - import otbn_model_pkg::*; import edn_pkg::*; import keymgr_pkg::otbn_key_req_t; #( @@ -57,6 +56,8 @@ output bit err_o // something went wrong ); +`include "otbn_model_dpi.svh" + // Create and destroy an object through which we can talk to the ISS. chandle model_handle; initial begin
diff --git a/hw/ip/otbn/dv/model/otbn_model.core b/hw/ip/otbn/dv/model/otbn_model.core index 5c8d723..7da76ec 100644 --- a/hw/ip/otbn/dv/model/otbn_model.core +++ b/hw/ip/otbn/dv/model/otbn_model.core
@@ -16,13 +16,13 @@ - otbn_model.cc: { file_type: cppSource } - otbn_model.h: { file_type: cppSource, is_include_file: true } - otbn_model_dpi.h: { file_type: cppSource, is_include_file: true } + - otbn_model_dpi.svh: { is_include_file: true } - iss_wrapper.cc: { file_type: cppSource } - iss_wrapper.h: { file_type: cppSource, is_include_file: true } - otbn_trace_checker.h: { file_type: cppSource, is_include_file: true } - otbn_trace_checker.cc: { file_type: cppSource } - otbn_trace_entry.h: { file_type: cppSource, is_include_file: true } - otbn_trace_entry.cc: { file_type: cppSource } - - otbn_model_pkg.sv - otbn_core_model.sv - otbn_rf_snooper_if.sv - otbn_stack_snooper_if.sv
diff --git a/hw/ip/otbn/dv/model/otbn_model_dpi.h b/hw/ip/otbn/dv/model/otbn_model_dpi.h index 2d140f6..af9d472 100644 --- a/hw/ip/otbn/dv/model/otbn_model_dpi.h +++ b/hw/ip/otbn/dv/model/otbn_model_dpi.h
@@ -4,8 +4,8 @@ #ifndef OPENTITAN_HW_IP_OTBN_DV_MODEL_OTBN_MODEL_DPI_H_ #define OPENTITAN_HW_IP_OTBN_DV_MODEL_OTBN_MODEL_DPI_H_ -// The DPI exports for OtbnModel. See also otbn_model_pkg.sv, where they are -// declared for the SystemVerilog side. +// The DPI exports for OtbnModel. See also otbn_model_dpi.svh, where +// they are declared for the SystemVerilog side. // // These are defined in a separate file from otbn_model.h because otherwise // something like otbn_top_sim.cc will see both these defines and the
diff --git a/hw/ip/otbn/dv/model/otbn_model_dpi.svh b/hw/ip/otbn/dv/model/otbn_model_dpi.svh new file mode 100644 index 0000000..8043945 --- /dev/null +++ b/hw/ip/otbn/dv/model/otbn_model_dpi.svh
@@ -0,0 +1,59 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Imports for the functions defined in otbn_model.h. There are documentation comments explaining +// what the functions do there. This needs to be included into otbn_core_model (because we need +// svGetScope() to point at the model instance). + +`ifndef SYNTHESIS +import "DPI-C" context function chandle otbn_model_init(string mem_scope, + string design_scope, + bit enable_secure_wipe); + +import "DPI-C" function void otbn_model_destroy(chandle model); + +import "DPI-C" function void edn_model_flush(chandle model); + +import "DPI-C" function void edn_model_rnd_step(chandle model, + logic [31:0] edn_rnd_data); + +import "DPI-C" function void edn_model_urnd_step(chandle model, + logic [31:0] edn_urnd_data); + +import "DPI-C" function + void edn_model_urnd_cdc_done(chandle model); + +import "DPI-C" function + void otbn_model_set_keymgr_value(chandle model, logic [383:0] key0, + logic [383:0] key1, bit valid); + +import "DPI-C" function + void edn_model_rnd_cdc_done(chandle model); + +import "DPI-C" context function + int unsigned otbn_model_step(chandle model, + logic start, + int unsigned model_state, + inout bit [7:0] status, + inout bit [31:0] insn_cnt, + inout bit rnd_req, + inout bit [31:0] err_bits, + inout bit [31:0] stop_pc); + +import "DPI-C" context function int otbn_model_check(chandle model, inout bit mismatch); + +import "DPI-C" function int otbn_model_invalidate_imem(chandle model); + +import "DPI-C" function int otbn_model_step_crc(chandle model, + bit [47:0] item, + inout bit [31:0] state); + +import "DPI-C" context function int otbn_model_invalidate_dmem(chandle model); + +import "DPI-C" function void otbn_model_reset(chandle model); + +import "DPI-C" function void otbn_take_loop_warps(chandle model, chandle memutil); + +import "DPI-C" function int otbn_model_send_lc_escalation(chandle model); +`endif // SYNTHESIS
diff --git a/hw/ip/otbn/dv/model/otbn_model_pkg.sv b/hw/ip/otbn/dv/model/otbn_model_pkg.sv deleted file mode 100644 index df412e2..0000000 --- a/hw/ip/otbn/dv/model/otbn_model_pkg.sv +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// Imports for the functions defined in otbn_model.h. There are documentation comments explaining -// what the functions do there. -`ifndef SYNTHESIS -package otbn_model_pkg; - - import otbn_pkg::WLEN; - - import "DPI-C" context function chandle otbn_model_init(string mem_scope, - string design_scope, - bit enable_secure_wipe); - - import "DPI-C" function void otbn_model_destroy(chandle model); - - import "DPI-C" function void edn_model_flush(chandle model); - - import "DPI-C" function void edn_model_rnd_step(chandle model, - logic [31:0] edn_rnd_data); - - import "DPI-C" function void edn_model_urnd_step(chandle model, - logic [31:0] edn_urnd_data); - - import "DPI-C" function - void edn_model_urnd_cdc_done(chandle model); - - import "DPI-C" function - void otbn_model_set_keymgr_value(chandle model, logic [383:0] key0, - logic [383:0] key1, bit valid); - - import "DPI-C" function - void edn_model_rnd_cdc_done(chandle model); - - import "DPI-C" context function - int unsigned otbn_model_step(chandle model, - logic start, - int unsigned model_state, - inout bit [7:0] status, - inout bit [31:0] insn_cnt, - inout bit rnd_req, - inout bit [31:0] err_bits, - inout bit [31:0] stop_pc); - - import "DPI-C" context function int otbn_model_check(chandle model, inout bit mismatch); - - import "DPI-C" function int otbn_model_invalidate_imem(chandle model); - - import "DPI-C" function int otbn_model_step_crc(chandle model, - bit [47:0] item, - inout bit [31:0] state); - - import "DPI-C" context function int otbn_model_invalidate_dmem(chandle model); - - import "DPI-C" function void otbn_model_reset(chandle model); - - import "DPI-C" function void otbn_take_loop_warps(chandle model, chandle memutil); - - import "DPI-C" function int otbn_model_send_lc_escalation(chandle model); - -endpackage -`endif // SYNTHESIS
diff --git a/hw/ip/otbn/dv/uvm/env/otbn_env_pkg.sv b/hw/ip/otbn/dv/uvm/env/otbn_env_pkg.sv index 60b96c7..53c5e5e 100644 --- a/hw/ip/otbn/dv/uvm/env/otbn_env_pkg.sv +++ b/hw/ip/otbn/dv/uvm/env/otbn_env_pkg.sv
@@ -12,7 +12,6 @@ import tl_agent_pkg::*; import cip_base_pkg::*; import push_pull_agent_pkg::*; - import otbn_model_pkg::*; import otbn_model_agent_pkg::*; import otbn_memutil_pkg::*; import mem_bkdr_util_pkg::mem_bkdr_util;
diff --git a/hw/ip/otbn/dv/uvm/env/seq_lib/otbn_base_vseq.sv b/hw/ip/otbn/dv/uvm/env/seq_lib/otbn_base_vseq.sv index def8b4f..87ea9b7 100644 --- a/hw/ip/otbn/dv/uvm/env/seq_lib/otbn_base_vseq.sv +++ b/hw/ip/otbn/dv/uvm/env/seq_lib/otbn_base_vseq.sv
@@ -53,7 +53,7 @@ end // Pass loop warp rules that we've just loaded into otbn_memutil into the model. - otbn_take_loop_warps(cfg.model_agent_cfg.vif.handle, cfg.mem_util); + cfg.model_agent_cfg.vif.take_loop_warps(cfg.mem_util); // We're loading a new program, so the tracking that we've been doing for how long runs take is // no longer valid.
diff --git a/hw/ip/otbn/dv/uvm/otbn_model_agent/otbn_model_if.sv b/hw/ip/otbn/dv/uvm/otbn_model_agent/otbn_model_if.sv index 4fe3017..7e0052b 100644 --- a/hw/ip/otbn/dv/uvm/otbn_model_agent/otbn_model_if.sv +++ b/hw/ip/otbn/dv/uvm/otbn_model_agent/otbn_model_if.sv
@@ -2,6 +2,11 @@ // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 +// If using this, instantiate it somewhere that "u_model" will resolve to the corresponding instance +// of the otbn_core_model module. For example, you might instantiate it in your testbench next to +// your model. In that case, SystemVerilog's symbol resolution rules ("go up until it works") should +// do the right thing. + interface otbn_model_if import keymgr_pkg::otbn_key_req_t; #( @@ -45,7 +50,7 @@ // posedge. function automatic void invalidate_imem(); `uvm_info("otbn_model_if", "Invalidating IMEM", UVM_HIGH) - `DV_CHECK_FATAL(otbn_model_pkg::otbn_model_invalidate_imem(handle) == 0, + `DV_CHECK_FATAL(u_model.otbn_model_invalidate_imem(handle) == 0, "Failed to invalidate IMEM", "otbn_model_if") endfunction @@ -55,7 +60,7 @@ // posedge. function automatic void invalidate_dmem(); `uvm_info("otbn_model_if", "Invalidating DMEM", UVM_HIGH) - `DV_CHECK_FATAL(otbn_model_pkg::otbn_model_invalidate_dmem(handle) == 0, + `DV_CHECK_FATAL(u_model.otbn_model_invalidate_dmem(handle) == 0, "Failed to invalidate DMEM", "otbn_model_if") endfunction @@ -66,11 +71,16 @@ // to write our own CRC function and ensures that the RTL matches the standardised CRC-32-IEEE // checksum. function automatic bit [31:0] step_crc(bit [47:0] item, bit [31:0] crc_state); - `DV_CHECK_FATAL(otbn_model_pkg::otbn_model_step_crc(handle, item, crc_state) == 0, + `DV_CHECK_FATAL(u_model.otbn_model_step_crc(handle, item, crc_state) == 0, "Failed to update CRC", "otbn_model_if") return crc_state; endfunction + // Pass loop warp rules to the model + function automatic void take_loop_warps(chandle memutil); + u_model.otbn_take_loop_warps(handle, memutil); + endfunction + // The err signal is asserted by the model if it fails to find the DUT or if it finds a mismatch // in results. It should never go high. `ASSERT(NoModelErrs, !err)