[otbn,dv] Check expected end address in UVM simulations
Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
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 7903a6f..fbaafae 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
@@ -101,6 +101,7 @@
// Start OTBN and then wait until done
protected task run_otbn();
+ int exp_end_addr;
uvm_reg_data_t cmd_val;
// Set the "start" bit in cmd_val and write it to the "cmd" register to start OTBN.
@@ -115,6 +116,14 @@
csr_utils_pkg::csr_spinwait(.ptr(ral.status.busy), .exp_data(1'b0));
`uvm_info(`gfn, $sformatf("\n\t ----| OTBN finished"), UVM_MEDIUM)
+
+ // If there was an expected end address, compare it with the model. This isn't really a test of
+ // the RTL, but it's handy to make sure that the RIG really is generating the control flow that
+ // it expects.
+ exp_end_addr = OtbnMemUtilGetExpEndAddr(cfg.mem_util);
+ if (exp_end_addr >= 0) begin
+ `DV_CHECK_EQ_FATAL(exp_end_addr, cfg.model_agent_cfg.vif.stop_pc)
+ end
endtask
virtual protected function string pick_elf_path();
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 9facfd5..2d579cc 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
@@ -12,11 +12,14 @@
input logic rst_ni
);
+ // Inputs to DUT
logic start; // Start the operation
logic [ImemAddrWidth-1:0] start_addr; // Start byte address in IMEM
+ // Outputs from DUT
bit done; // Operation done
bit err; // Something went wrong
+ bit [31:0] stop_pc; // PC at end of operation
// Wait until done goes high. Stops early on reset
task automatic wait_done();
diff --git a/hw/ip/otbn/dv/uvm/tb.sv b/hw/ip/otbn/dv/uvm/tb.sv
index 89a063f..191b1a8 100644
--- a/hw/ip/otbn/dv/uvm/tb.sv
+++ b/hw/ip/otbn/dv/uvm/tb.sv
@@ -139,6 +139,9 @@
.edn_urnd_data_valid_i (edn_urnd_data_valid)
);
+ // Pull the final PC out of the DUT
+ assign model_if.stop_pc = u_model.stop_pc_q;
+
initial begin
// drive clk and rst_n from clk_if
clk_rst_if.set_active();