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