Changes necessary to trace memory operations.
This is not thoroughly tested, as we quickly throw an exception due to out-of-bounds memory and need some RVFI-DII control flow fixup to proceed further.
This commit is contained in:
@@ -175,8 +175,7 @@ module mkCore#(CoreId coreId)(Core);
|
||||
|
||||
// ================================================================
|
||||
// If using Direct Instruction Injection then make a
|
||||
// bridge that can insert instructions as if it were
|
||||
// an instruction cache.
|
||||
// bridge that can insert instructions.
|
||||
`ifdef RVFI_DII
|
||||
Toooba_RVFI_DII_Bridge_IFC rvfi_bridge <- mkTooobaRVFIDIIBridge;
|
||||
mkConnection(rvfi_bridge.dii, fetchStage.dii);
|
||||
|
||||
@@ -84,6 +84,9 @@ typedef struct {
|
||||
ControlFlow controlFlow;
|
||||
// speculation
|
||||
Maybe#(SpecTag) spec_tag;
|
||||
`ifdef RVFI
|
||||
ExtraTraceBundle traceBundle;
|
||||
`endif
|
||||
} AluExeToFinish deriving(Bits, Eq, FShow);
|
||||
|
||||
// XXX currently ALU/Br should not have any exception, so we don't have cause feild above
|
||||
@@ -137,7 +140,14 @@ interface AluExeInput;
|
||||
method Addr rob_getPC(InstTag t);
|
||||
method Addr rob_getPredPC(InstTag t);
|
||||
method Bit #(32) rob_getOrig_Inst (InstTag t);
|
||||
method Action rob_setExecuted(InstTag t, Maybe#(Data) csrData, ControlFlow cf);
|
||||
method Action rob_setExecuted(
|
||||
InstTag t,
|
||||
Maybe#(Data) csrData,
|
||||
ControlFlow cf
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
`endif
|
||||
);
|
||||
// Fetch stage
|
||||
method Action fetch_train_predictors(FetchTrainBP train);
|
||||
|
||||
@@ -292,7 +302,13 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
|
||||
tag: x.tag,
|
||||
dpTrain: x.dpTrain,
|
||||
data: exec_result.data,
|
||||
csrData: isValid(x.dInst.csr) ? Valid (exec_result.csrData) : Invalid,
|
||||
csrData: isValid(x.dInst.csr) ? Valid (exec_result.csrData) : tagged Invalid,
|
||||
`ifdef RVFI
|
||||
traceBundle: ExtraTraceBundle{
|
||||
regWriteData: exec_result.data,
|
||||
memByteEn: replicate(False)
|
||||
},
|
||||
`endif
|
||||
controlFlow: exec_result.controlFlow,
|
||||
spec_tag: x.spec_tag
|
||||
},
|
||||
@@ -317,6 +333,9 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
|
||||
x.tag,
|
||||
x.csrData,
|
||||
x.controlFlow
|
||||
`ifdef RVFI
|
||||
, x.traceBundle
|
||||
`endif
|
||||
);
|
||||
|
||||
// handle spec tags for branch predictions
|
||||
|
||||
@@ -132,6 +132,20 @@ typedef struct {
|
||||
|
||||
`ifdef RVFI
|
||||
function RVFI_DII_Execution#(DataSz,DataSz) genRVFI(ToReorderBuffer rot);
|
||||
Addr addr = 0;
|
||||
Addr next_pc = rot.pc + 4;
|
||||
Data data = rot.traceBundle.regWriteData;
|
||||
case (rot.ppc_vaddr_csrData) matches
|
||||
tagged VAddr .vaddr: addr = vaddr;
|
||||
tagged PPC .ppc: next_pc = ppc;
|
||||
tagged CSRData .csrdata: data = csrdata;
|
||||
endcase
|
||||
ByteEn rmask = replicate(False);
|
||||
ByteEn wmask = replicate(False);
|
||||
case (rot.lsqTag) matches
|
||||
tagged Ld .l: rmask = rot.traceBundle.memByteEn;
|
||||
tagged St .s: wmask = rot.traceBundle.memByteEn;
|
||||
endcase
|
||||
return RVFI_DII_Execution {
|
||||
rvfi_order: 0, // Instruction number? InstID maybe?
|
||||
rvfi_trap: isValid(rot.trap),
|
||||
@@ -143,14 +157,14 @@ function RVFI_DII_Execution#(DataSz,DataSz) genRVFI(ToReorderBuffer rot);
|
||||
rvfi_rs1_data: ?,
|
||||
rvfi_rs2_data: ?,
|
||||
rvfi_pc_rdata: rot.pc,
|
||||
rvfi_pc_wdata: rot.pc + 4,
|
||||
rvfi_pc_wdata: next_pc,
|
||||
rvfi_mem_wdata: 0,
|
||||
rvfi_rd_addr: rot.orig_inst[11:7],
|
||||
rvfi_rd_wdata: ?,
|
||||
rvfi_mem_addr: 0,
|
||||
rvfi_mem_rmask: 0,
|
||||
rvfi_mem_wmask: 0,
|
||||
rvfi_mem_rdata: 0
|
||||
rvfi_rd_wdata: ((rot.orig_inst[11:7]==0) ? 0:data),
|
||||
rvfi_mem_addr: addr,
|
||||
rvfi_mem_rmask: pack(rmask),
|
||||
rvfi_mem_wmask: pack(wmask),
|
||||
rvfi_mem_rdata: data
|
||||
};
|
||||
endfunction
|
||||
`endif
|
||||
|
||||
@@ -461,6 +461,20 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
let x = dTlbResp.inst;
|
||||
let {paddr, cause} = dTlbResp.resp;
|
||||
|
||||
`ifdef RVFI_DII
|
||||
// TestRIG expects us throw an access fault for any memory access outside of a 64-KiB memory at 0x8000000.
|
||||
if (!isValid(cause) && (paddr < 'h80000000 || paddr >= 'h80010000)) begin
|
||||
case(x.mem_func)
|
||||
Ld, Lr: begin
|
||||
cause = Valid (LoadAccessFault);
|
||||
end
|
||||
default: begin
|
||||
cause = Valid (StoreAccessFault);
|
||||
end
|
||||
endcase
|
||||
end
|
||||
`endif
|
||||
|
||||
if(verbose) $display("[doFinishMem] ", fshow(dTlbResp));
|
||||
if(isValid(cause) && verbose) $display(" [doFinishMem - dTlb response] PAGEFAULT!");
|
||||
|
||||
|
||||
@@ -44,6 +44,13 @@ typedef union tagged {
|
||||
Data CSRData; // for Csr inst, store csr_data
|
||||
} PPCVAddrCSRData deriving(Bits, Eq, FShow);
|
||||
|
||||
`ifdef RVFI
|
||||
typedef struct {
|
||||
Data regWriteData;
|
||||
ByteEn memByteEn;
|
||||
} ExtraTraceBundle deriving(Bits, Eq, FShow);
|
||||
`endif
|
||||
|
||||
typedef struct {
|
||||
Addr pc;
|
||||
Bit #(32) orig_inst; // original 16b or 32b instruction ([1:0] will distinguish 16b or 32b)
|
||||
@@ -75,6 +82,9 @@ typedef struct {
|
||||
|
||||
// speculation
|
||||
SpecBits spec_bits;
|
||||
`ifdef RVFI
|
||||
ExtraTraceBundle traceBundle;
|
||||
`endif
|
||||
} ToReorderBuffer deriving(Bits, Eq, FShow);
|
||||
|
||||
typedef enum {
|
||||
@@ -83,7 +93,13 @@ typedef enum {
|
||||
} RobInstState deriving (Bits, Eq, FShow);
|
||||
|
||||
interface Row_setExecuted_doFinishAlu;
|
||||
method Action set(Maybe#(Data) csrData, ControlFlow cf);
|
||||
method Action set(
|
||||
Maybe#(Data) csrData,
|
||||
ControlFlow cf
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
`endif
|
||||
);
|
||||
endinterface
|
||||
|
||||
interface Row_setExecuted_doFinishFpuMulDiv;
|
||||
@@ -186,6 +202,9 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
Ehr#(2, Bool) nonMMIOStDone <- mkEhr(?);
|
||||
Reg#(Bool) epochIncremented <- mkRegU;
|
||||
Ehr#(3, SpecBits) spec_bits <- mkEhr(?);
|
||||
`ifdef RVFI
|
||||
Ehr#(TAdd#(2, aluExeNum), (ExtraTraceBundle)) traceBundle <- mkEhr(?);
|
||||
`endif
|
||||
|
||||
// wires to get stale (EHR port 0) values of PPC
|
||||
Wire#(Addr) predPcWire <- mkBypassWire;
|
||||
@@ -197,7 +216,13 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
Vector#(aluExeNum, Row_setExecuted_doFinishAlu) aluSetExe;
|
||||
for(Integer i = 0; i < valueof(aluExeNum); i = i+1) begin
|
||||
aluSetExe[i] = (interface Row_setExecuted_doFinishAlu;
|
||||
method Action set(Maybe#(Data) csrData, ControlFlow cf);
|
||||
method Action set(
|
||||
Maybe#(Data) csrData,
|
||||
ControlFlow cf
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
`endif
|
||||
);
|
||||
// inst is done
|
||||
rob_inst_state[state_finishAlu_port(i)] <= Executed;
|
||||
// update PPC or csrData (vaddr is always useless for ALU results)
|
||||
@@ -207,6 +232,9 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
else begin
|
||||
ppc_vaddr_csrData[pvc_finishAlu_port(i)] <= PPC (cf.nextPc);
|
||||
end
|
||||
`ifdef RVFI
|
||||
traceBundle[pvc_finishAlu_port(i)] <= tb;
|
||||
`endif
|
||||
doAssert(isValid(csr) == isValid(csrData), "csr valid should match");
|
||||
endmethod
|
||||
endinterface);
|
||||
@@ -281,6 +309,9 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
ldKilled[ldKill_enq_port] <= Invalid;
|
||||
lsqAtCommitNotified[lsqNotified_enq_port] <= False;
|
||||
nonMMIOStDone[nonMMIOSt_enq_port] <= False;
|
||||
`ifdef RVFI
|
||||
traceBundle[pvc_enq_port] <= x.traceBundle;
|
||||
`endif
|
||||
// check
|
||||
doAssert(!isValid(x.ldKilled), "ld killed must be false");
|
||||
doAssert(x.memAccessAtCommit == False, "mem access at commit must be false");
|
||||
@@ -307,6 +338,9 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
lsqAtCommitNotified: lsqAtCommitNotified[lsqNotified_deq_port],
|
||||
nonMMIOStDone: nonMMIOStDone[nonMMIOSt_deq_port],
|
||||
epochIncremented: epochIncremented,
|
||||
`ifdef RVFI
|
||||
traceBundle: traceBundle[pvc_deq_port],
|
||||
`endif
|
||||
spec_bits: spec_bits[sb_deq_port]
|
||||
};
|
||||
endmethod
|
||||
@@ -379,7 +413,13 @@ endinterface
|
||||
// not raise false conflicts between the superscalar enq/deq actions
|
||||
|
||||
interface ROB_setExecuted_doFinishAlu;
|
||||
method Action set(InstTag x, Maybe#(Data) csrData, ControlFlow cf);
|
||||
method Action set(InstTag x,
|
||||
Maybe#(Data) csrData,
|
||||
ControlFlow cf
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
`endif
|
||||
);
|
||||
endinterface
|
||||
|
||||
interface ROB_setExecuted_doFinishFpuMulDiv;
|
||||
@@ -891,11 +931,22 @@ module mkSupReorderBuffer#(
|
||||
for(Integer i = 0; i < valueof(aluExeNum); i = i+1) begin
|
||||
aluSetExeIfc[i] = (interface ROB_setExecuted_doFinishAlu;
|
||||
method Action set(
|
||||
InstTag x, Maybe#(Data) csrData, ControlFlow cf
|
||||
InstTag x,
|
||||
Maybe#(Data) csrData,
|
||||
ControlFlow cf
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
`endif
|
||||
) if(
|
||||
all(id, readVReg(setExeAlu_SB_enq)) // ordering: < enq
|
||||
);
|
||||
row[x.way][x.ptr].setExecuted_doFinishAlu[i].set(csrData, cf);
|
||||
row[x.way][x.ptr].setExecuted_doFinishAlu[i].set(
|
||||
csrData,
|
||||
cf
|
||||
`ifdef RVFI
|
||||
, tb
|
||||
`endif
|
||||
);
|
||||
endmethod
|
||||
endinterface);
|
||||
end
|
||||
|
||||
Submodule src_Verifier/BSV-RVFI-DII updated: 2383117b4b...380f77da5b
@@ -61,10 +61,11 @@ module mkTooobaRVFIDIIBridge(Toooba_RVFI_DII_Bridge_IFC);
|
||||
// DII state
|
||||
FIFOF#(Tuple2#(Bit#(32), Dii_Id)) dii_in <- mkUGFIFOF;
|
||||
Reg#(InstsAndIDs) buff <- mkConfigRegU;
|
||||
FIFOF#(InstsAndIDs) instrs <- mkSizedFIFOF(128);
|
||||
FIFOF#(InstsAndIDs) instrs <- mkSizedFIFOF(2048);
|
||||
PulseWire putFromBridge <- mkPulseWire;
|
||||
// RVFI state
|
||||
FIFO#(Rvfi_Traces) report_vectors <- mkSizedFIFO(128);
|
||||
FIFO#(RVFI_DII_Execution#(DataSz,DataSz)) reports <- mkSizedFIFO(256);
|
||||
FIFO#(Rvfi_Traces) report_vectors <- mkSizedFIFO(2048);
|
||||
FIFO#(RVFI_DII_Execution#(DataSz,DataSz)) reports <- mkFIFO;
|
||||
// Request ID
|
||||
FIFO#(Dii_Id) seq_req <- mkFIFO;
|
||||
|
||||
@@ -93,7 +94,7 @@ module mkTooobaRVFIDIIBridge(Toooba_RVFI_DII_Bridge_IFC);
|
||||
InstsAndIDs cb = buff;
|
||||
Bit#(32) ins = nop;
|
||||
Dii_Id id = ?;
|
||||
if (dii_in.notEmpty) {ins, id} = dii_in.first;
|
||||
if (dii_in.notEmpty) {ins, id} <- toGet(dii_in).get;
|
||||
cb.insts[buffLvl] = tagged Valid ins;
|
||||
cb.ids[buffLvl] = id;
|
||||
if (buffLvl == -1) begin
|
||||
@@ -106,14 +107,19 @@ module mkTooobaRVFIDIIBridge(Toooba_RVFI_DII_Bridge_IFC);
|
||||
|
||||
interface Toooba_RVFI_DII_Server rvfi_dii_server;
|
||||
interface Get seqReq = toGet(seq_req);
|
||||
interface Put inst = toPut(dii_in);
|
||||
interface Put inst;
|
||||
method Action put(Tuple2#(Bit#(32), Dii_Id) in) if (dii_in.notFull);
|
||||
dii_in.enq(in);
|
||||
putFromBridge.send();
|
||||
endmethod
|
||||
endinterface
|
||||
interface Get trace_report = toGet(reports);
|
||||
endinterface
|
||||
|
||||
interface Server dii;
|
||||
interface Put request = toPut(seq_req);
|
||||
interface Get response;
|
||||
method ActionValue#(InstsAndIDs) get;
|
||||
method ActionValue#(InstsAndIDs) get if (!putFromBridge);
|
||||
InstsAndIDs insts = instrs.first();
|
||||
instrs.deq();
|
||||
if (verbose)
|
||||
|
||||
Reference in New Issue
Block a user