Add minstret / minstreth to Kelvin sim
PiperOrigin-RevId: 600500043
diff --git a/sim/kelvin_state.cc b/sim/kelvin_state.cc
index 0c82a23..d6aeaa2 100644
--- a/sim/kelvin_state.cc
+++ b/sim/kelvin_state.cc
@@ -49,7 +49,9 @@
: mpact::sim::riscv::RiscVState(id, xlen, memory, atomic_memory),
kisa_("kisa", static_cast<RiscVCsrEnum>(KelvinCsrEnum::kKIsa), this),
mcycle_("mcycle", RiscVCsrEnum::kMCycle, this),
- mcycleh_("mcycleh", RiscVCsrEnum::kMCycleH, this) {
+ mcycleh_("mcycleh", RiscVCsrEnum::kMCycleH, this),
+ minstret_("minstret", RiscVCsrEnum::kMInstret, this),
+ minstreth_("minstreth", RiscVCsrEnum::kMInstretH, this) {
set_vector_register_width(kVectorRegisterWidth);
for (int i = 0; i < acc_register_.size(); ++i) {
acc_register_[i].fill(0);
@@ -71,6 +73,12 @@
if (!csr_set()->AddCsr(&mcycleh_).ok()) {
LOG(FATAL) << "Failed to register mcycleh";
}
+ if (!csr_set()->AddCsr(&minstret_).ok()) {
+ LOG(FATAL) << "Failed to register minstret";
+ }
+ if (!csr_set()->AddCsr(&minstreth_).ok()) {
+ LOG(FATAL) << "Failed to register minstreth";
+ }
}
KelvinState::KelvinState(absl::string_view id,
@@ -145,4 +153,11 @@
mcycleh_.Set(new_cycle >> 32);
}
+void KelvinState::IncrementMInstret(uint64_t value) {
+ uint64_t new_instret =
+ (minstret_.GetUint64() | (minstreth_.GetUint64() << 32)) + value;
+ minstret_.Set(new_instret & 0xFFFFFFFF);
+ minstreth_.Set(new_instret >> 32);
+}
+
} // namespace kelvin::sim
diff --git a/sim/kelvin_state.h b/sim/kelvin_state.h
index ffcfd84..7788fb1 100644
--- a/sim/kelvin_state.h
+++ b/sim/kelvin_state.h
@@ -98,6 +98,7 @@
}
void IncrementMCycle(uint64_t value);
+ void IncrementMInstret(uint64_t value);
private:
uint32_t vector_length_{kVectorLengthInBits};
@@ -120,6 +121,8 @@
// mcycle/mcycleh CSR.
mpact::sim::riscv::RiscV32SimpleCsr mcycle_;
mpact::sim::riscv::RiscV32SimpleCsr mcycleh_;
+ mpact::sim::riscv::RiscV32SimpleCsr minstret_;
+ mpact::sim::riscv::RiscV32SimpleCsr minstreth_;
};
} // namespace kelvin::sim
diff --git a/sim/kelvin_top.cc b/sim/kelvin_top.cc
index 3b49bd2..dcd2b79 100644
--- a/sim/kelvin_top.cc
+++ b/sim/kelvin_top.cc
@@ -257,7 +257,7 @@
} while (!executed);
// Increment counter.
counter_opcode_[real_inst->opcode()].Increment(1);
- counter_num_instructions_.Increment(1);
+ IncrementInstructionCount(1);
real_inst->DecRef();
// Re-enable the breakpoint.
if (status.ok()) {
@@ -315,7 +315,7 @@
count++;
// Update counters.
counter_opcode_[inst->opcode()].Increment(1);
- counter_num_instructions_.Increment(1);
+ IncrementInstructionCount(1);
// Get the next pc value.
next_pc = pc_operand->AsUint64(0);
}
@@ -411,7 +411,7 @@
} while (!executed);
// Update counters.
counter_opcode_[inst->opcode()].Increment(1);
- counter_num_instructions_.Increment(1);
+ IncrementInstructionCount(1);
// Get the next pc value.
next_pc = pc_operand->AsUint64(0);
}
@@ -730,4 +730,9 @@
state_->IncrementMCycle(value);
}
+void KelvinTop::IncrementInstructionCount(uint64_t value) {
+ counter_num_instructions_.Increment(value);
+ state_->IncrementMInstret(value);
+}
+
} // namespace kelvin::sim
diff --git a/sim/kelvin_top.h b/sim/kelvin_top.h
index 5bab3d1..9b48889 100644
--- a/sim/kelvin_top.h
+++ b/sim/kelvin_top.h
@@ -123,6 +123,7 @@
void SetPc(uint64_t value);
// Increment the cycle count.
void IncrementCycleCount(uint64_t value);
+ void IncrementInstructionCount(uint64_t value);
// The DB factory is used to manage data buffers for memory read/writes.
mpact::sim::generic::DataBufferFactory db_factory_;
diff --git a/sim/test/testfiles/kelvin_perf_counters.elf b/sim/test/testfiles/kelvin_perf_counters.elf
index 6037860..3a9c505 100755
--- a/sim/test/testfiles/kelvin_perf_counters.elf
+++ b/sim/test/testfiles/kelvin_perf_counters.elf
Binary files differ