Skip to content

Commit 6430146

Browse files
committed
fix: 收敛 InOrder/OOO 语义并补齐 DiffTest 与回归脚本
- 为 ICpuInterface 新增 getCSR/setCSR,并在 InOrder/OOO 与 CPU 适配器中统一实现 CSR 访问接口。 - OOO 执行路径补齐 M 扩展分流与 MISC_MEM(FENCE) NOP 处理;CSR 改为执行阶段只读、提交阶段统一写回,避免乱序提前生效。 - Issue 阶段仅对 CSR 指令施加 ROB 头部顺序约束,既保证 CSR 语义一致性,也不影响 ECALL 正常推进。 - Commit 阶段将 DiffTest 比对移动到体系结构状态更新之后,避免提交时序导致的假不一致。 - DiffTest 覆盖从仅 GPR 扩展到 GPR+FPR+关键 CSR,并补充对应单测。 - 新增 OOO 回归单测:MExtensionMulInstruction、FenceInstructionAsNop、SystemCSRInstructions;补齐 syscall mock 的 CSR 接口实现。 - run_tests.py 统一英文输出,并增加“无 PASS 标记但正常结束(Program finished + halted)”的 PASS 兜底判定,修复 rv32uc-p-rvc 被误判 ERROR。 验证: 1) cmake --build build -j 2) ctest --test-dir build --output-on-failure 3) python3 run_tests.py -p "rv32*-p-*" --ooo 4) python3 run_tests.py -p "rv64ui-p-*" --ooo
1 parent acb10a1 commit 6430146

15 files changed

Lines changed: 355 additions & 130 deletions

File tree

include/common/cpu_interface.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ class ICpuInterface {
3838
virtual void setFPRegister(RegNum reg, uint64_t value) = 0;
3939
virtual float getFPRegisterFloat(RegNum reg) const = 0;
4040
virtual void setFPRegisterFloat(RegNum reg, float value) = 0;
41+
42+
// CSR寄存器访问
43+
virtual uint64_t getCSR(uint32_t addr) const = 0;
44+
virtual void setCSR(uint32_t addr, uint64_t value) = 0;
4145

4246
// 程序计数器
4347
virtual uint64_t getPC() const = 0;

include/cpu/inorder/cpu.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ class CPU : public ICpuInterface {
4242
void setFPRegister(RegNum reg, uint64_t value) override;
4343
float getFPRegisterFloat(RegNum reg) const override;
4444
void setFPRegisterFloat(RegNum reg, float value) override;
45+
46+
// CSR寄存器访问
47+
uint64_t getCSR(uint32_t addr) const override;
48+
void setCSR(uint32_t addr, uint64_t value) override;
4549

4650
// 程序计数器
4751
uint64_t getPC() const override { return pc_; }

include/cpu/ooo/ooo_cpu.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ class OutOfOrderCPU : public ICpuInterface {
6161
void setFPRegister(RegNum reg, uint64_t value) override;
6262
float getFPRegisterFloat(RegNum reg) const override;
6363
void setFPRegisterFloat(RegNum reg, float value) override;
64+
65+
// CSR寄存器访问
66+
uint64_t getCSR(uint32_t addr) const override;
67+
void setCSR(uint32_t addr, uint64_t value) override;
6468

6569
// 程序计数器
6670
uint64_t getPC() const override { return cpu_state_.pc; }

include/system/difftest.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class DiffTest {
7979
bool compareRegisters(ICpuInterface* ooo_cpu);
8080
bool comparePC(ICpuInterface* ooo_cpu);
8181
bool compareFPRegisters(ICpuInterface* ooo_cpu);
82+
bool compareCSRRegisters(ICpuInterface* ooo_cpu);
8283

8384
/**
8485
* 转储状态信息用于调试
@@ -94,4 +95,4 @@ class DiffTest {
9495
uint64_t mismatch_count_; // 不一致次数
9596
};
9697

97-
} // namespace riscv
98+
} // namespace riscv

run_tests.py

Lines changed: 116 additions & 106 deletions
Large diffs are not rendered by default.

src/cpu/cpu_factory.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ class InOrderCpuAdapter : public ICpuInterface {
2828
void setFPRegister(RegNum reg, uint64_t value) override { cpu_->setFPRegister(reg, value); }
2929
float getFPRegisterFloat(RegNum reg) const override { return cpu_->getFPRegisterFloat(reg); }
3030
void setFPRegisterFloat(RegNum reg, float value) override { cpu_->setFPRegisterFloat(reg, value); }
31+
32+
uint64_t getCSR(uint32_t addr) const override { return cpu_->getCSR(addr); }
33+
void setCSR(uint32_t addr, uint64_t value) override { cpu_->setCSR(addr, value); }
3134

3235
uint64_t getPC() const override { return cpu_->getPC(); }
3336
void setPC(uint64_t pc) override { cpu_->setPC(pc); }
@@ -68,6 +71,9 @@ class OutOfOrderCpuAdapter : public ICpuInterface {
6871
void setFPRegister(RegNum reg, uint64_t value) override { cpu_->setFPRegister(reg, value); }
6972
float getFPRegisterFloat(RegNum reg) const override { return cpu_->getFPRegisterFloat(reg); }
7073
void setFPRegisterFloat(RegNum reg, float value) override { cpu_->setFPRegisterFloat(reg, value); }
74+
75+
uint64_t getCSR(uint32_t addr) const override { return cpu_->getCSR(addr); }
76+
void setCSR(uint32_t addr, uint64_t value) override { cpu_->setCSR(addr, value); }
7177

7278
uint64_t getPC() const override { return cpu_->getPC(); }
7379
void setPC(uint64_t pc) override { cpu_->setPC(pc); }

src/cpu/inorder/cpu.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,20 @@ void CPU::setFPRegisterFloat(RegNum reg, float value) {
190190
fp_registers_[reg] = *reinterpret_cast<const uint32_t*>(&value);
191191
}
192192

193+
uint64_t CPU::getCSR(uint32_t addr) const {
194+
if (addr >= NUM_CSR_REGISTERS) {
195+
throw SimulatorException("无效的CSR地址: " + std::to_string(addr));
196+
}
197+
return csr_registers_[addr];
198+
}
199+
200+
void CPU::setCSR(uint32_t addr, uint64_t value) {
201+
if (addr >= NUM_CSR_REGISTERS) {
202+
throw SimulatorException("无效的CSR地址: " + std::to_string(addr));
203+
}
204+
csr_registers_[addr] = value;
205+
}
206+
193207
void CPU::dumpRegisters() const {
194208
std::cout << "Registers:\n";
195209
for (int i = 0; i < NUM_REGISTERS; i += 4) {

src/cpu/ooo/ooo_cpu.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,20 @@ void OutOfOrderCPU::setFPRegisterFloat(RegNum reg, float value) {
208208
cpu_state_.arch_fp_registers[reg] = *reinterpret_cast<const uint32_t*>(&value);
209209
}
210210

211+
uint64_t OutOfOrderCPU::getCSR(uint32_t addr) const {
212+
if (addr >= cpu_state_.csr_registers.size()) {
213+
throw SimulatorException("无效的CSR地址: " + std::to_string(addr));
214+
}
215+
return cpu_state_.csr_registers[addr];
216+
}
217+
218+
void OutOfOrderCPU::setCSR(uint32_t addr, uint64_t value) {
219+
if (addr >= cpu_state_.csr_registers.size()) {
220+
throw SimulatorException("无效的CSR地址: " + std::to_string(addr));
221+
}
222+
cpu_state_.csr_registers[addr] = value;
223+
}
224+
211225
void OutOfOrderCPU::handle_exception(const std::string& exception_msg, uint64_t pc) {
212226
LOGE(SYSTEM, "exception: %s, pc=0x%" PRIx64, exception_msg.c_str(), pc);
213227
flush_pipeline();

src/cpu/ooo/stages/commit_stage.cpp

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,6 @@ void CommitStage::execute(CPUState& state) {
106106
// 这确保Store指令提交到内存后,相应的Store Buffer条目被清除
107107
state.store_buffer->retire_stores_before(committed_inst->get_instruction_id());
108108

109-
// DiffTest: 当乱序CPU提交一条指令时,同步执行参考CPU并比较状态
110-
if (state.cpu_interface && state.cpu_interface->isDiffTestEnabled()) {
111-
LOGT(DIFFTEST, "inst=%" PRId64 " [COMMIT_TRACK] commit count=%" PRId64,
112-
committed_inst->get_instruction_id(), state.instruction_count);
113-
// 使用提交指令的PC进行DiffTest
114-
state.cpu_interface->performDiffTestWithCommittedPC(committed_inst->get_pc());
115-
LOGT(COMMIT, "run difftest comparison");
116-
}
117-
118109
// 处理跳转指令:只有is_jump=true的指令才会改变PC
119110
if (committed_inst->is_jump()) {
120111
state.pc = committed_inst->get_jump_target();
@@ -127,14 +118,32 @@ void CommitStage::execute(CPUState& state) {
127118

128119
// 处理系统调用
129120
if (committed_inst->get_decoded_info().opcode == Opcode::SYSTEM) {
130-
if (InstructionExecutor::isSystemCall(committed_inst->get_decoded_info())) {
121+
const auto& sys_inst = committed_inst->get_decoded_info();
122+
123+
if (InstructionExecutor::isCsrInstruction(sys_inst)) {
124+
const uint32_t csr_addr = static_cast<uint32_t>(sys_inst.imm) & 0xFFFU;
125+
const auto csr_result = InstructionExecutor::executeCsrInstruction(
126+
sys_inst, committed_inst->get_src1_value(), state.csr_registers[csr_addr]);
127+
state.csr_registers[csr_addr] = csr_result.write_value;
128+
LOGT(COMMIT, "inst=%" PRId64 " commit csr[0x%03x]: old=0x%" PRIx64 ", new=0x%" PRIx64,
129+
committed_inst->get_instruction_id(), csr_addr,
130+
csr_result.read_value, csr_result.write_value);
131+
} else if (InstructionExecutor::isSystemCall(sys_inst)) {
131132
// ECALL
132133
handle_ecall(state, committed_inst->get_pc());
133-
} else if (InstructionExecutor::isBreakpoint(committed_inst->get_decoded_info())) {
134+
} else if (InstructionExecutor::isBreakpoint(sys_inst)) {
134135
// EBREAK
135136
handle_ebreak(state);
136137
}
137138
}
139+
140+
// DiffTest: 在提交阶段所有体系结构状态更新完成后再做比较
141+
if (state.cpu_interface && state.cpu_interface->isDiffTestEnabled()) {
142+
LOGT(DIFFTEST, "inst=%" PRId64 " [COMMIT_TRACK] commit count=%" PRId64,
143+
committed_inst->get_instruction_id(), state.instruction_count);
144+
state.cpu_interface->performDiffTestWithCommittedPC(committed_inst->get_pc());
145+
LOGT(COMMIT, "run difftest comparison");
146+
}
138147

139148
// 如果没有更多指令可提交,跳出循环
140149
if (!commit_result.has_more) {

src/cpu/ooo/stages/execute_stage.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,14 @@ void ExecuteStage::execute_instruction(ExecutionUnit& unit, DynamicInstPtr instr
7676
switch (inst.type) {
7777
case InstructionType::R_TYPE:
7878
if (inst.opcode == Opcode::OP) {
79-
// 寄存器-寄存器运算
80-
unit.result = InstructionExecutor::executeRegisterOperation(inst, instruction->get_src1_value(), instruction->get_src2_value());
79+
// OP指令包含基础整数和M扩展,按funct7分流
80+
if (inst.funct7 == Funct7::M_EXT) {
81+
unit.result = InstructionExecutor::executeMExtension(
82+
inst, instruction->get_src1_value(), instruction->get_src2_value());
83+
} else {
84+
unit.result = InstructionExecutor::executeRegisterOperation(
85+
inst, instruction->get_src1_value(), instruction->get_src2_value());
86+
}
8187
} else if (inst.opcode == Opcode::OP_32) {
8288
// RV64I: 32位寄存器运算(W后缀)
8389
unit.result = InstructionExecutor::executeRegisterOperation32(inst, instruction->get_src1_value(), instruction->get_src2_value());
@@ -111,6 +117,9 @@ void ExecuteStage::execute_instruction(ExecutionUnit& unit, DynamicInstPtr instr
111117
unit.jump_target = InstructionExecutor::calculateJumpAndLinkTarget(inst, instruction->get_pc(), instruction->get_src1_value());
112118
unit.is_jump = true; // 标记为跳转指令
113119
instruction->set_jump_info(true, unit.jump_target);
120+
} else if (inst.opcode == Opcode::MISC_MEM) {
121+
// FENCE/FENCE.I:在当前单核模型中作为NOP处理
122+
unit.result = 0;
114123
} else {
115124
unit.has_exception = true;
116125
unit.exception_msg = "unsupported I-type instruction";
@@ -146,9 +155,8 @@ void ExecuteStage::execute_instruction(ExecutionUnit& unit, DynamicInstPtr instr
146155
const uint32_t csr_addr = static_cast<uint32_t>(inst.imm) & 0xFFFU;
147156
const auto csr_result = InstructionExecutor::executeCsrInstruction(
148157
inst, instruction->get_src1_value(), state.csr_registers[csr_addr]);
149-
state.csr_registers[csr_addr] = csr_result.write_value;
150158
unit.result = csr_result.read_value;
151-
LOGT(EXECUTE, "inst=%" PRId64 " csr[0x%03x]: old=0x%" PRIx64 ", new=0x%" PRIx64,
159+
LOGT(EXECUTE, "inst=%" PRId64 " csr[0x%03x]: old=0x%" PRIx64 ", pending_new=0x%" PRIx64,
152160
instruction->get_instruction_id(), csr_addr,
153161
csr_result.read_value, csr_result.write_value);
154162
}

0 commit comments

Comments
 (0)