Skip to content

Commit e3f1468

Browse files
committed
[dv] Correctly set minstret in cosim
1 parent ea2ad1d commit e3f1468

15 files changed

Lines changed: 62 additions & 0 deletions

dv/cosim/cosim.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,17 @@ class Cosim {
128128
// A full 64-bit value is provided setting both the mcycle and mcycleh CSRs.
129129
virtual void set_mcycle(uint64_t mcycle) = 0;
130130

131+
// Set the value of minstret.
132+
//
133+
// The co-simulation model doesn't alter the value of minstret itself (other
134+
// than instructions that do a direct CSR write). minstret should be set to
135+
// the correct value before any `step` call that may execute an instruction
136+
// that observes the value of minstret.
137+
//
138+
// A full 64-bit value is provided setting both the minstret and minstreth
139+
// CSRs.
140+
virtual void set_minstret(uint64_t minstret) = 0;
141+
131142
// Set the value of a CSR. This is used when it is needed to have direct
132143
// communication between DUT and Spike (e.g. Performance counters).
133144
virtual void set_csr(const int csr_num, const uint32_t new_val) = 0;

dv/cosim/cosim_dpi.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ void riscv_cosim_set_mcycle(Cosim *cosim, svBitVecVal *mcycle) {
5252
cosim->set_mcycle(mcycle_full);
5353
}
5454

55+
void riscv_cosim_set_minstret(Cosim *cosim, svBitVecVal *minstret) {
56+
assert(cosim);
57+
58+
uint64_t minstret_full = minstret[0] | (uint64_t)minstret[1] << 32;
59+
cosim->set_minstret(minstret_full);
60+
}
61+
5562
void riscv_cosim_set_csr(Cosim *cosim, const int csr_id,
5663
const svBitVecVal *csr_val) {
5764
assert(cosim);

dv/cosim/cosim_dpi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ void riscv_cosim_set_nmi(Cosim *cosim, svBit nmi);
2323
void riscv_cosim_set_nmi_int(Cosim *cosim, svBit nmi_int);
2424
void riscv_cosim_set_debug_req(Cosim *cosim, svBit debug_req);
2525
void riscv_cosim_set_mcycle(Cosim *cosim, svBitVecVal *mcycle);
26+
void riscv_cosim_set_minstret(Cosim *cosim, svBitVecVal *minstret);
2627
void riscv_cosim_set_csr(Cosim *cosim, const int csr_id,
2728
const svBitVecVal *csr_val);
2829
void riscv_cosim_set_ic_scr_key_valid(Cosim *cosim, svBit valid);

dv/cosim/cosim_dpi.svh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import "DPI-C" function void riscv_cosim_set_nmi(chandle cosim_handle, bit nmi);
1818
import "DPI-C" function void riscv_cosim_set_nmi_int(chandle cosim_handle, bit nmi_int);
1919
import "DPI-C" function void riscv_cosim_set_debug_req(chandle cosim_handle, bit debug_req);
2020
import "DPI-C" function void riscv_cosim_set_mcycle(chandle cosim_handle, bit [63:0] mcycle);
21+
import "DPI-C" function void riscv_cosim_set_minstret(chandle cosim_handle, bit [63:0] minstret);
2122
import "DPI-C" function void riscv_cosim_set_csr(chandle cosim_handle, int csr_id,
2223
bit [31:0] csr_val);
2324
import "DPI-C" function void riscv_cosim_set_ic_scr_key_valid(chandle cosim_handle, bit valid);

dv/cosim/spike_cosim.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,27 @@ void SpikeCosim::set_mcycle(uint64_t mcycle) {
750750
// to write all 64 bits at once at least.
751751
}
752752

753+
void SpikeCosim::set_minstret(uint64_t minstret) {
754+
uint32_t upper_minstret = minstret >> 32;
755+
uint32_t lower_minstret = minstret & 0xffffffff;
756+
757+
// Spike decrements the MINSTRET CSR when you write to it. This is the same
758+
// issue as with MCYCLE. See `set_mcycle` for more details.
759+
760+
// Write the lower half first, incremented twice due to the double decrement
761+
processor->get_state()->csrmap[CSR_MINSTRET]->write(lower_minstret + 2);
762+
763+
if ((processor->get_state()->csrmap[CSR_MINSTRET]->read() & 0xffffffff) ==
764+
0) {
765+
// If the lower half is 0 at this point then the upper half will get
766+
// decremented, so increment it first.
767+
upper_minstret++;
768+
}
769+
770+
// Set the upper half
771+
processor->get_state()->csrmap[CSR_MINSTRETH]->write(upper_minstret);
772+
}
773+
753774
void SpikeCosim::set_csr(const int csr_num, const uint32_t new_val) {
754775
// Note that this is tested with ibex-cosim-v0.3 version of Spike. 'set_csr'
755776
// method might have a hardwired zero for mhpmcounterX registers.

dv/cosim/spike_cosim.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ class SpikeCosim : public simif_t, public Cosim {
132132
void set_nmi_int(bool nmi_int) override;
133133
void set_debug_req(bool debug_req) override;
134134
void set_mcycle(uint64_t mcycle) override;
135+
void set_minstret(uint64_t minstret) override;
135136
void set_csr(const int csr_num, const uint32_t new_val) override;
136137
void set_ic_scr_key_valid(bool valid) override;
137138
void notify_dside_access(const DSideAccessInfo &access_info) override;

dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_cosim_scoreboard.sv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ class ibex_cosim_scoreboard extends uvm_scoreboard;
151151
riscv_cosim_set_nmi_int(cosim_handle, rvfi_instr.nmi_int);
152152
riscv_cosim_set_mip(cosim_handle, rvfi_instr.pre_mip, rvfi_instr.post_mip);
153153
riscv_cosim_set_mcycle(cosim_handle, rvfi_instr.mcycle);
154+
riscv_cosim_set_minstret(cosim_handle, rvfi_instr.minstret);
154155

155156
// Set performance counters through a pseudo-backdoor write
156157
for (int i=0; i < 10; i++) begin

dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_rvfi_monitor.sv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class ibex_rvfi_monitor extends uvm_monitor;
4444
trans_collected.debug_req = vif.monitor_cb.ext_debug_req;
4545
trans_collected.rf_wr_suppress = vif.monitor_cb.ext_rf_wr_suppress;
4646
trans_collected.mcycle = vif.monitor_cb.ext_mcycle;
47+
trans_collected.minstret = vif.monitor_cb.ext_minstret;
4748
trans_collected.ic_scr_key_valid = vif.monitor_cb.ext_ic_scr_key_valid;
4849

4950
for (int i=0; i < 10; i++) begin

dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_rvfi_seq_item.sv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class ibex_rvfi_seq_item extends uvm_sequence_item;
1616
bit debug_req;
1717
bit rf_wr_suppress;
1818
bit [63:0] mcycle;
19+
bit [63:0] minstret;
1920

2021
bit [31:0] mhpmcounters [10];
2122
bit [31:0] mhpmcountersh [10];
@@ -34,6 +35,7 @@ class ibex_rvfi_seq_item extends uvm_sequence_item;
3435
`uvm_field_int (debug_req, UVM_DEFAULT)
3536
`uvm_field_int (rf_wr_suppress, UVM_DEFAULT)
3637
`uvm_field_int (mcycle, UVM_DEFAULT)
38+
`uvm_field_int (minstret, UVM_DEFAULT)
3739
`uvm_field_sarray_int (mhpmcounters, UVM_DEFAULT)
3840
`uvm_field_sarray_int (mhpmcountersh, UVM_DEFAULT)
3941
`uvm_field_int (ic_scr_key_valid, UVM_DEFAULT)

dv/uvm/core_ibex/env/core_ibex_rvfi_if.sv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ interface core_ibex_rvfi_if(input logic clk);
3333
logic [31:0] ext_debug_req;
3434
logic [31:0] ext_rf_wr_suppress;
3535
logic [63:0] ext_mcycle;
36+
logic [63:0] ext_minstret;
3637
logic ext_irq_valid;
3738

3839
logic [31:0] ext_mhpmcounters [10];
@@ -70,6 +71,7 @@ interface core_ibex_rvfi_if(input logic clk);
7071
input ext_debug_req;
7172
input ext_rf_wr_suppress;
7273
input ext_mcycle;
74+
input ext_minstret;
7375
input ext_mhpmcounters;
7476
input ext_mhpmcountersh;
7577
input ext_ic_scr_key_valid;

0 commit comments

Comments
 (0)