提交 72235fa4 编写于 作者: W William Wang

difftest: set up nemu difftest framework

上级 e402d94e
......@@ -68,7 +68,7 @@ class Dp1ToDp2IO extends XSBundle {
}
class DebugBundle extends XSBundle{
val isMMIO = Output(Bool())
val isMMIO = Bool()
}
class ExuInput extends XSBundle {
......
......@@ -153,27 +153,4 @@ class Backend(implicit val p: XSConfig) extends XSModule
)
for (s <- sinks){ BoringUtils.addSink(tmp, s) }
// A fake commit
// TODO: difftest 6 insts per cycle
val commit = RegNext(RegNext(RegNext(true.B)))
val pc = WireInit("h80000000".U)
val inst = WireInit("h66666666".U)
if(!p.FPGAPlatform){
BoringUtils.addSource(commit, "difftestCommit")
BoringUtils.addSource(pc, "difftestThisPC")
BoringUtils.addSource(inst, "difftestThisINST")
BoringUtils.addSource(tmp, "difftestIsMMIO")
BoringUtils.addSource(tmp, "difftestIsRVC")
BoringUtils.addSource(tmp, "difftestIntrNO")
BoringUtils.addSource(VecInit(Seq.fill(64)(tmp)), "difftestRegs")
BoringUtils.addSource(tmp, "difftestMode")
BoringUtils.addSource(tmp, "difftestMstatus")
BoringUtils.addSource(tmp, "difftestSstatus")
BoringUtils.addSource(tmp, "difftestMepc")
BoringUtils.addSource(tmp, "difftestSepc")
BoringUtils.addSource(tmp, "difftestMcause")
BoringUtils.addSource(tmp, "difftestScause")
}
}
......@@ -3,9 +3,10 @@ package xiangshan.backend.roq
import chisel3._
import chisel3.util._
import xiangshan._
import chisel3.util.experimental.BoringUtils
// A "just-enough" Roq
class Roq extends XSModule {
class Roq(implicit val p: XSConfig) extends XSModule {
val io = IO(new Bundle() {
val brqRedirect = Input(Valid(new Redirect))
val dp1Req = Vec(RenameWidth, Flipped(DecoupledIO(new MicroOp)))
......@@ -20,8 +21,10 @@ class Roq extends XSModule {
val valid = RegInit(VecInit(List.fill(RoqSize)(false.B)))
val writebacked = Reg(Vec(RoqSize, Bool()))
val redirect = Reg(Vec(RoqSize, new Redirect))
val isMMIO = Reg(Vec(RoqSize, Bool()))//for debug
val intrNO = Reg(Vec(RoqSize, UInt(XLEN.W)))//for debug
val exuData = Reg(Vec(RoqSize, UInt(XLEN.W)))//for debug
val exuDebug = Reg(Vec(RoqSize, new DebugBundle))//for debug
val archRF = RegInit(VecInit(List.fill(32)(0.U(32.W))))//for debug
val ringBufferHeadExtended = RegInit(0.U(ExtendedRoqIdxWidth.W))
val ringBufferTailExtended = RegInit(0.U(ExtendedRoqIdxWidth.W))
......@@ -57,6 +60,8 @@ class Roq extends XSModule {
for(i <- 0 until exuConfig.ExuCnt){
when(io.exeWbResults(i).fire()){
writebacked(io.exeWbResults(i).bits.uop.roqIdx) := true.B
exuData(io.exeWbResults(i).bits.uop.roqIdx) := io.exeWbResults(i).bits.data
exuDebug(io.exeWbResults(i).bits.uop.roqIdx) := io.exeWbResults(i).bits.debug
}
}
......@@ -65,6 +70,7 @@ class Roq extends XSModule {
when(state === s_idle){
io.commits(i).valid := valid(ringBufferTail+i.U) && writebacked(ringBufferTail+i.U)
io.commits(i).bits.uop := microOp(ringBufferTail+i.U)
when(microOp(i).ctrl.rfWen){ archRF(microOp(i).ctrl.ldest) := exuData(i) }
when(valid(ringBufferTail+i.U)){valid(ringBufferTail+i.U) := false.B}//FIXIT
}.otherwise{//state === s_walk
io.commits(i).valid := valid(ringBufferWalk+i.U) && writebacked(ringBufferWalk+i.U)
......@@ -78,6 +84,7 @@ class Roq extends XSModule {
when(state === s_idle){
ringBufferTailExtended := ringBufferTailExtended + PopCount(validCommit)
}
val retireCounter = Mux(state === s_idle, PopCount(validCommit), 0.U)
val walkFinished = (0 until CommitWidth).map(i => (ringBufferWalk + i.U) === ringBufferWalkTarget).reduce(_||_)
......@@ -102,4 +109,29 @@ class Roq extends XSModule {
// roq redirect only used for exception
io.redirect := DontCare //TODO
io.redirect.valid := false.B //TODO
//difftest signals
val firstValidCommit = ringBufferTail + PriorityMux(validCommit, VecInit(List.tabulate(CommitWidth)(_.U)))
val emptyCsr = WireInit(0.U(64.W))
if(!p.FPGAPlatform){
BoringUtils.addSink(RegNext(retireCounter), "difftestCommit")
BoringUtils.addSink(RegNext(microOp(firstValidCommit).cf.pc), "difftestThisPC")//first valid PC
BoringUtils.addSink(RegNext(microOp(firstValidCommit).cf.instr), "difftestThisINST")//first valid inst
BoringUtils.addSink(archRF, "difftestRegs")//arch RegFile
BoringUtils.addSink(RegNext(false.B), "difftestSkip")//SKIP
BoringUtils.addSink(RegNext(false.B), "difftestIsRVC")//FIXIT
BoringUtils.addSink(RegNext(0.U), "difftestIntrNO")
//TODO: skip insts that commited in the same cycle ahead of exception
//csr debug signals
val ModeM = WireInit(0x3.U)
BoringUtils.addSource(ModeM, "difftestMode")
BoringUtils.addSource(emptyCsr, "difftestMstatus")
BoringUtils.addSource(emptyCsr, "difftestSstatus")
BoringUtils.addSource(emptyCsr, "difftestMepc")
BoringUtils.addSource(emptyCsr, "difftestSepc")
BoringUtils.addSource(emptyCsr, "difftestMcause")
BoringUtils.addSource(emptyCsr, "difftestScause")
}
}
......@@ -83,9 +83,10 @@ static const char *reg_name[DIFFTEST_NR_REG] = {
"sstatus", "scause", "sepc"
};
int difftest_step(uint64_t *reg_scala, uint32_t this_inst,
int isMMIO, int isRVC, uint64_t intrNO, int priviledgeMode) {
int difftest_step(int commit, uint64_t *reg_scala, uint32_t this_inst,
int skip, int isRVC, uint64_t intrNO, int priviledgeMode) {
assert(!skip && !isRVC && intrNO == 0)
#define DEBUG_RETIRE_TRACE_SIZE 16
uint64_t ref_r[DIFFTEST_NR_REG];
......@@ -97,7 +98,7 @@ int difftest_step(uint64_t *reg_scala, uint32_t this_inst,
static uint32_t inst_retire_queue[DEBUG_RETIRE_TRACE_SIZE] = {0};
static int pc_retire_pointer = 7;
if (isMMIO) {
if (skip) {
// printf("diff pc: %x isRVC %x\n", this_pc, isRVC);
// MMIO accessing should not be a branch or jump, just +2/+4 to get the next pc
reg_scala[DIFFTEST_THIS_PC] += isRVC ? 2 : 4;
......@@ -112,10 +113,11 @@ int difftest_step(uint64_t *reg_scala, uint32_t this_inst,
if (intrNO) {
ref_difftest_raise_intr(intrNO);
} else {
ref_difftest_exec(1);
ref_difftest_exec(1);//TODO
}
assert(commit > 0 && commit <= 6)
ref_difftest_exec(commit);
ref_difftest_getregs(&ref_r);
uint64_t next_pc = ref_r[DIFFTEST_THIS_PC];
......@@ -123,17 +125,18 @@ int difftest_step(uint64_t *reg_scala, uint32_t this_inst,
pc_retire_queue[pc_retire_pointer] = this_pc;
inst_retire_queue[pc_retire_pointer] = this_inst;
int isCSR = ((this_inst & 0x7f) == 0x73);
int isCSRMip = ((this_inst >> 20) == 0x344) && isCSR;
if (isCSRMip) {
// We can not handle NEMU.mip.mtip since it is driven by CLINT,
// which is not accessed in NEMU due to MMIO.
// Just sync the state of NEMU from NOOP.
reg_scala[DIFFTEST_THIS_PC] = next_pc;
nemu_this_pc = next_pc;
ref_difftest_setregs(reg_scala);
return 0;
}
// TODO: fix mip.mtip
// int isCSR = ((this_inst & 0x7f) == 0x73);
// int isCSRMip = ((this_inst >> 20) == 0x344) && isCSR;
// if (isCSRMip) {
// // We can not handle NEMU.mip.mtip since it is driven by CLINT,
// // which is not accessed in NEMU due to MMIO.
// // Just sync the state of NEMU from NOOP.
// reg_scala[DIFFTEST_THIS_PC] = next_pc;
// nemu_this_pc = next_pc;
// ref_difftest_setregs(reg_scala);
// return 0;
// }
// replace with "this pc" for checking
ref_r[DIFFTEST_THIS_PC] = nemu_this_pc;
......
......@@ -148,10 +148,10 @@ class Emulator {
uint64_t reg[DIFFTEST_NR_REG];
read_emu_regs(reg);
extern int difftest_step(uint64_t *reg_scala, uint32_t this_inst,
int isMMIO, int isRVC, uint64_t intrNO, int priviledgeMode);
if (difftest_step(reg, dut_ptr->io_difftest_thisINST,
dut_ptr->io_difftest_isMMIO, dut_ptr->io_difftest_isRVC,
extern int difftest_step(int commit, uint64_t *reg_scala, uint32_t this_inst,
int skip, int isRVC, uint64_t intrNO, int priviledgeMode);
if (difftest_step(dut_ptr->io_difftest_commit, reg, dut_ptr->io_difftest_thisINST,
dut_ptr->io_difftest_skip, dut_ptr->io_difftest_isRVC,
dut_ptr->io_difftest_intrNO, dut_ptr->io_difftest_priviledgeMode)) {
#if VM_TRACE
tfp->close();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册