提交 07635e87 编写于 作者: W wangkaifan

difftest: wire out load instr info from core to enhance difftest

上级 614546f4
......@@ -448,6 +448,9 @@ class DifftestBundle extends XSBundle {
val wdata = Output(Vec(CommitWidth, UInt(XLEN.W))) // set difftest width to 6
val wdst = Output(Vec(CommitWidth, UInt(32.W))) // set difftest width to 6
val wpc = Output(Vec(CommitWidth, UInt(XLEN.W))) // set difftest width to 6
val lpaddr = Output(Vec(CommitWidth, UInt(64.W)))
val ltype = Output(Vec(CommitWidth, UInt(32.W)))
val lfu = Output(Vec(CommitWidth, UInt(4.W)))
val isRVC = Output(UInt(32.W))
val scFailed = Output(Bool())
}
......
......@@ -69,6 +69,9 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
val wpc = Output(Vec(CommitWidth, UInt(XLEN.W))) // set difftest width to 6
val isRVC = Output(UInt(32.W))
val scFailed = Output(Bool())
val lpaddr = Output(Vec(CommitWidth, UInt(64.W)))
val ltype = Output(Vec(CommitWidth, UInt(32.W)))
val lfu = Output(Vec(CommitWidth, UInt(4.W)))
}
})
difftestIO <> DontCare
......
......@@ -220,6 +220,9 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
val wpc = Output(Vec(CommitWidth, UInt(XLEN.W))) // set difftest width to 6
val isRVC = Output(UInt(32.W))
val scFailed = Output(Bool())
val lpaddr = Output(Vec(CommitWidth, UInt(64.W)))
val ltype = Output(Vec(CommitWidth, UInt(32.W)))
val lfu = Output(Vec(CommitWidth, UInt(4.W)))
})
difftestIO <> DontCare
......@@ -738,7 +741,9 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
val skip = Wire(Vec(CommitWidth, Bool()))
val wen = Wire(Vec(CommitWidth, Bool()))
val wdata = Wire(Vec(CommitWidth, UInt(XLEN.W)))
val paddr = Wire(Vec(CommitWidth, UInt(PAddrBits.W)))
val lpaddr = Wire(Vec(CommitWidth, UInt(PAddrBits.W)))
val ltype = Wire(Vec(CommitWidth, UInt(32.W)))
val lfu = Wire(Vec(CommitWidth, UInt(4.W)))
val wdst = Wire(Vec(CommitWidth, UInt(32.W)))
val diffTestDebugLrScValid = Wire(Vec(CommitWidth, Bool()))
val wpc = Wire(Vec(CommitWidth, UInt(XLEN.W)))
......@@ -761,7 +766,9 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
}
wen(i) := io.commits.valid(i) && uop.ctrl.rfWen && uop.ctrl.ldest =/= 0.U
wdata(i) := debug_exuData(idx)
paddr(i) := debug_exuDebug(idx).paddr
lpaddr(i) := debug_exuDebug(idx).paddr
lfu(i) := uop.ctrl.fuType
ltype(i) := uop.ctrl.fuOpType
wdst(i) := uop.ctrl.ldest
diffTestDebugLrScValid(i) := uop.diffTestDebugLrScValid
wpc(i) := SignExt(uop.cf.pc, XLEN)
......@@ -823,5 +830,8 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
difftestIO.wpc := RegNext(wpc)
difftestIO.isRVC := RegNext(isRVC.asUInt)
difftestIO.scFailed := RegNext(scFailed)
difftestIO.lpaddr := RegNext(lpaddr)
difftestIO.ltype := RegNext(ltype)
difftestIO.lfu := RegNext(lfu)
}
}
......@@ -269,6 +269,7 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
io.mmioStout.bits.redirect := DontCare
io.mmioStout.bits.brUpdate := DontCare
io.mmioStout.bits.debug.isMMIO := true.B
io.mmioStout.bits.debug.paddr := DontCare
io.mmioStout.bits.debug.isPerfCnt := false.B
io.mmioStout.bits.fflags := DontCare
when (io.mmioStout.fire()) {
......
......@@ -223,6 +223,7 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
io.out.bits.redirect := DontCare
io.out.bits.brUpdate := DontCare
io.out.bits.debug.isMMIO := is_mmio
io.out.bits.debug.paddr := paddr
when (io.out.fire()) {
XSDebug("atomics writeback: pc %x data %x\n", io.out.bits.uop.cf.pc, io.dcache.resp.bits.data)
state := s_invalid
......
......@@ -128,6 +128,7 @@ class StoreUnit_S3 extends XSModule {
io.stout.bits.redirect := DontCare
io.stout.bits.brUpdate := DontCare
io.stout.bits.debug.isMMIO := io.in.bits.mmio
io.stout.bits.debug.paddr := DontCare
io.stout.bits.debug.isPerfCnt := false.B
io.stout.bits.fflags := DontCare
......
......@@ -132,7 +132,6 @@ void difftest_display(uint8_t mode, int coreid) {
}
int difftest_step(DiffState *s, int coreid) {
// assert(!s->isRVC);
uint64_t ref_r[DIFFTEST_NR_REG];
uint64_t this_pc = s->reg_scala[DIFFTEST_THIS_PC];
......@@ -154,7 +153,7 @@ int difftest_step(DiffState *s, int coreid) {
// }
// sync lr/sc reg status
if(s->scFailed){
if (s->scFailed) {
struct SyncState sync;
sync.lrscValid = 0;
sync.lrscAddr = 0;
......@@ -168,36 +167,71 @@ int difftest_step(DiffState *s, int coreid) {
}
else {
assert(s->commit > 0 && s->commit <= DIFFTEST_WIDTH);
for(int i = 0; i < s->commit; i++){
for (int i = 0; i < s->commit; i++) {
pc_wb_queue[coreid][wb_pointer[coreid]] = s->wpc[i];
wen_wb_queue[coreid][wb_pointer[coreid]] = selectBit(s->wen, i);
wdst_wb_queue[coreid][wb_pointer[coreid]] = s->wdst[i];
wdata_wb_queue[coreid][wb_pointer[coreid]] = s->wdata[i];
wb_pointer[coreid] = (wb_pointer[coreid]+1) % DEBUG_WB_TRACE_SIZE;
if(selectBit(s->skip, i)){
if (selectBit(s->skip, i)) {
// MMIO accessing should not be a branch or jump, just +2/+4 to get the next pc
// printf("SKIP %d\n", i);
// to skip the checking of an instruction, just copy the reg state to reference design
ref_difftest_getregs(&ref_r, coreid);
ref_r[DIFFTEST_THIS_PC] += selectBit(s->isRVC, i) ? 2 : 4;
if(selectBit(s->wen, i)){
if(s->wdst[i] != 0){
if (selectBit(s->wen, i)) {
if (s->wdst[i] != 0) {
ref_r[s->wdst[i]] = s->wdata[i];
}
}
ref_difftest_setregs(ref_r, coreid);
}else{
} else {
// single step exec
// IPF, LPF, SPF
if(s->cause == 12 || s->cause == 13 || s->cause == 15){
if (s->cause == 12 || s->cause == 13 || s->cause == 15) {
// printf("s->cause %ld\n", s->cause);
struct DisambiguationState ds;
ds.exceptionNo = s->cause;
ds.mtval = s->reg_scala[DIFFTEST_MTVAL];
ds.stval = s->reg_scala[DIFFTEST_STVAL];
ref_disambiguate_exec(&ds, coreid);
}else{
} else {
ref_difftest_exec(1, coreid);
if (s->lfu[i] == 0xC || s->lfu[i] == 0xF) { // Load instruction
ref_difftest_getregs(&ref_r, coreid);
if (ref_r[s->wdst[i]] != s->wdata[i]) {
printf("[DIFF] This load instruction gets fucked!\n");
printf("[DIFF] ltype: 0x%x paddr: 0x%lx wen: 0x%x wdst: 0x%x wdata: 0x%lx pc: 0x%lx\n", s->ltype[i], s->lpaddr[i], selectBit(s->wen, i), s->wdst[i], s->wdata[i], s->wpc[i]);
uint64_t golden;
int len = 0;
if (s->lfu[i] == 0xC) {
switch (s->ltype[i]) {
case 0: len = 1; break;
case 1: len = 2; break;
case 2: len = 4; break;
case 3: len = 8; break;
default: panic("Unknown fuOpType: 0x%x", s->ltype[i]);
}
} else if (s->lfu[i] == 0xF) {
if (s->ltype[i] % 2 == 0) {
len = 4;
} else if (s->ltype[i] % 2 == 1) {
len = 8;
}
}
read_goldenmem(s->lpaddr[i], &golden, len);
printf("[DIFF] golden: 0x%lx original: 0x%lx\n", golden, ref_r[s->wdst[i]]);
if (golden == s->wdata[i]) {
// ref_difftest_memcpy_from_dut(0x80000000, get_img_start(), get_img_size(), i);
ref_difftest_memcpy_from_dut(s->lpaddr[i], &golden, len, coreid);
if (s->wdst[i] != 0) {
ref_r[s->wdst[i]] = s->wdata[i];
ref_difftest_setregs(ref_r, coreid);
}
}
}
}
}
}
}
......
......@@ -56,6 +56,9 @@ struct DiffState {
uint64_t *wpc;
uint64_t *wdata;
uint32_t *wdst;
uint64_t *lpaddr;
uint32_t *ltype;
uint8_t *lfu;
int wen;
uint64_t intrNO;
uint64_t cause; // for disambiguate_exec
......
......@@ -209,11 +209,14 @@ inline void Emulator::read_emu_regs2(uint64_t *r) {
r[DIFFTEST_MODE] = dut_ptr->io_difftest2_priviledgeMode;
}
inline void Emulator::read_wb_info(uint64_t *wpc, uint64_t *wdata, uint32_t *wdst) {
inline void Emulator::read_wb_info(uint64_t *wpc, uint64_t *wdata, uint32_t *wdst, uint64_t *lpaddr, uint32_t *ltype, uint8_t *lfu) {
#define dut_ptr_wpc(x) wpc[x] = dut_ptr->io_difftest_wpc_##x
#define dut_ptr_wdata(x) wdata[x] = dut_ptr->io_difftest_wdata_##x
#define dut_ptr_wdst(x) wdst[x] = dut_ptr->io_difftest_wdst_##x
#define dut_ptr_read_wb(x) dut_ptr_wpc(x); dut_ptr_wdata(x); dut_ptr_wdst(x);
#define dut_ptr_lpaddr(x) lpaddr[x] = dut_ptr->io_difftest_lpaddr_##x
#define dut_ptr_ltype(x) ltype[x] = dut_ptr->io_difftest_ltype_##x
#define dut_ptr_lfu(x) lfu[x] = dut_ptr->io_difftest_lfu_##x
#define dut_ptr_read_wb(x) dut_ptr_wpc(x); dut_ptr_wdata(x); dut_ptr_wdst(x); dut_ptr_lpaddr(x); dut_ptr_ltype(x); dut_ptr_lfu(x);
#if DIFFTEST_WIDTH >= 13 || DIFFTEST_WIDTH < 6
#error "not supported difftest width"
......@@ -245,11 +248,14 @@ inline void Emulator::read_wb_info(uint64_t *wpc, uint64_t *wdata, uint32_t *wds
#endif
}
inline void Emulator::read_wb_info2(uint64_t *wpc, uint64_t *wdata, uint32_t *wdst) {
inline void Emulator::read_wb_info2(uint64_t *wpc, uint64_t *wdata, uint32_t *wdst, uint64_t *lpaddr, uint32_t *ltype, uint8_t *lfu) {
#define dut_ptr_wpc2(x) wpc[x] = dut_ptr->io_difftest2_wpc_##x
#define dut_ptr_wdata2(x) wdata[x] = dut_ptr->io_difftest2_wdata_##x
#define dut_ptr_wdst2(x) wdst[x] = dut_ptr->io_difftest2_wdst_##x
#define dut_ptr_read_wb2(x) dut_ptr_wpc2(x); dut_ptr_wdata2(x); dut_ptr_wdst2(x);
#define dut_ptr_lpaddr2(x) lpaddr[x] = dut_ptr->io_difftest2_lpaddr_##x
#define dut_ptr_ltype2(x) ltype[x] = dut_ptr->io_difftest2_ltype_##x
#define dut_ptr_lfu2(x) lfu[x] = dut_ptr->io_difftest2_lfu_##x
#define dut_ptr_read_wb2(x) dut_ptr_wpc2(x); dut_ptr_wdata2(x); dut_ptr_wdst2(x); dut_ptr_lpaddr2(x); dut_ptr_ltype2(x); dut_ptr_lfu2(x);
#if DIFFTEST_WIDTH >= 13 || DIFFTEST_WIDTH < 6
#error "not supported difftest width"
......@@ -429,12 +435,18 @@ uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) {
uint64_t wpc[NumCore][DIFFTEST_WIDTH];
uint64_t reg[NumCore][DIFFTEST_NR_REG];
uint8_t sbufferData[64];
uint64_t lpaddr[NumCore][DIFFTEST_WIDTH];
uint32_t ltype[NumCore][DIFFTEST_WIDTH];
uint8_t lfu[NumCore][DIFFTEST_WIDTH];
DiffState diff[NumCore];
for (int i = 0; i < NumCore; i++) {
diff[i].reg_scala = reg[i];
diff[i].wpc = wpc[i];
diff[i].wdata = wdata[i];
diff[i].wdst = wdst[i];
diff[i].lpaddr = lpaddr[i];
diff[i].ltype = ltype[i];
diff[i].lfu = lfu[i];
lastcommit[i] = max_cycle;
instr_left_last_cycle[i] = max_cycle;
core_max_instr[i] = max_instr;
......@@ -504,10 +516,10 @@ uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) {
if (core_nr_commit && hascommit[i]) {
if (i == 0) {
read_emu_regs(reg[i]);
read_wb_info(wpc[i], wdata[i], wdst[i]);
read_wb_info(wpc[i], wdata[i], wdst[i], lpaddr[i], ltype[i], lfu[i]);
} else {
read_emu_regs2(reg[i]);
read_wb_info2(wpc[i], wdata[i], wdst[i]);
read_wb_info2(wpc[i], wdata[i], wdst[i], lpaddr[i], ltype[i], lfu[i]);
}
load_diff_info(diff, i);
......
......@@ -57,14 +57,14 @@ class Emulator {
int trapCode;
inline void read_emu_regs(uint64_t *r);
inline void read_wb_info(uint64_t *wpc, uint64_t *wdata, uint32_t *wdst);
inline void read_wb_info(uint64_t *wpc, uint64_t *wdata, uint32_t *wdst, uint64_t *lpaddr, uint32_t *ltype, uint8_t *lfu);
inline void read_store_info(uint64_t *saddr, uint64_t *sdata, uint8_t *smask);
inline void read_sbuffer_info(uint8_t *sbufferData);
inline void load_diff_info(void* diff, int coreid);
// TODO: dirty methods
inline void read_emu_regs2(uint64_t *r);
inline void read_wb_info2(uint64_t *wpc, uint64_t *wdata, uint32_t *wdst);
inline void read_wb_info2(uint64_t *wpc, uint64_t *wdata, uint32_t *wdst, uint64_t *lpaddr, uint32_t *ltype, uint8_t *lfu);
inline void read_store_info2(uint64_t *saddr, uint64_t *sdata, uint8_t *smask);
inline void read_sbuffer_info2(uint8_t *sbufferData);
......
......@@ -70,7 +70,7 @@ static inline void pmem_write(paddr_t addr, word_t data, int len) {
inline word_t paddr_read(paddr_t addr, int len) {
if (in_pmem(addr)) return pmem_read(addr, len);
else panic("read not in pmem!");
else panic("read not in pmem! addr: %lx", addr);
return 0;
}
......
......@@ -58,6 +58,10 @@ class DiffTestIO extends XSBundle {
val sbufferAddr = Output(UInt(64.W))
val sbufferData = Output(Vec(64, UInt(8.W)))
val sbufferMask = Output(UInt(64.W))
val lpaddr = Output(Vec(CommitWidth, UInt(64.W)))
val ltype = Output(Vec(CommitWidth, UInt(32.W)))
val lfu = Output(Vec(CommitWidth, UInt(4.W)))
}
class LogCtrlIO extends Bundle {
......@@ -221,6 +225,10 @@ class XSSimSoC(axiSim: Boolean)(implicit p: config.Parameters) extends LazyModul
difftest(i).sbufferAddr := soc.module.difftestIO(i).fromSbuffer.sbufferAddr
difftest(i).sbufferData := soc.module.difftestIO(i).fromSbuffer.sbufferData
difftest(i).sbufferMask := soc.module.difftestIO(i).fromSbuffer.sbufferMask
difftest(i).lpaddr := soc.module.difftestIO(i).fromRoq.lpaddr
difftest(i).ltype := soc.module.difftestIO(i).fromRoq.ltype
difftest(i).lfu := soc.module.difftestIO(i).fromRoq.lfu
}
io.difftest2 := difftest(1)
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册