Pipe through memory results. This design passes 100 memory test sequences of TestRIG. Yay!
This commit is contained in:
@@ -135,18 +135,23 @@ function Maybe#(RVFI_DII_Execution#(DataSz,DataSz)) genRVFI(ToReorderBuffer rot,
|
||||
Addr addr = 0;
|
||||
Addr next_pc = 0;
|
||||
Data data = 0;
|
||||
Data wdata = 0;
|
||||
ByteEn rmask = replicate(False);
|
||||
ByteEn wmask = replicate(False);
|
||||
if (!isValid(rot.trap)) begin
|
||||
next_pc = rot.pc + 4;
|
||||
data = rot.traceBundle.regWriteData;
|
||||
data = rot.traceBundle.regWriteData; // Default for register-to-register operations.
|
||||
case (rot.ppc_vaddr_csrData) matches
|
||||
tagged VAddr .vaddr: begin
|
||||
addr = vaddr;
|
||||
case (rot.lsqTag) matches
|
||||
tagged Ld .l: rmask = rot.traceBundle.memByteEn;
|
||||
tagged St .s: wmask = rot.traceBundle.memByteEn;
|
||||
endcase
|
||||
addr = vaddr;
|
||||
case (rot.lsqTag) matches
|
||||
tagged Ld .l: rmask = rot.traceBundle.memByteEn;
|
||||
tagged St .s: begin
|
||||
wmask = rot.traceBundle.memByteEn;
|
||||
data = 0;
|
||||
wdata = rot.traceBundle.regWriteData;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
tagged PPC .ppc: next_pc = ppc;
|
||||
tagged CSRData .csrdata: data = csrdata;
|
||||
@@ -164,7 +169,7 @@ function Maybe#(RVFI_DII_Execution#(DataSz,DataSz)) genRVFI(ToReorderBuffer rot,
|
||||
rvfi_rs2_data: ?,
|
||||
rvfi_pc_rdata: rot.pc,
|
||||
rvfi_pc_wdata: next_pc,
|
||||
rvfi_mem_wdata: 0,
|
||||
rvfi_mem_wdata: wdata,
|
||||
rvfi_rd_addr: rot.orig_inst[11:7],
|
||||
rvfi_rd_wdata: ((rot.orig_inst[11:7]==0) ? 0:data),
|
||||
rvfi_mem_addr: addr,
|
||||
|
||||
@@ -28,6 +28,7 @@ import GetPut::*;
|
||||
import ClientServer::*;
|
||||
import Cntrs::*;
|
||||
import Fifo::*;
|
||||
import Ehr::*;
|
||||
import Types::*;
|
||||
import ProcTypes::*;
|
||||
import MemoryTypes::*;
|
||||
@@ -144,8 +145,16 @@ interface MemExeInput;
|
||||
method Data csrf_rd(CSR csr);
|
||||
// ROB
|
||||
method Addr rob_getPC(InstTag t);
|
||||
method Action rob_setExecuted_doFinishMem(InstTag t, Addr vaddr, Bool access_at_commit, Bool non_mmio_st_done);
|
||||
method Action rob_setExecuted_deqLSQ(InstTag t, Maybe#(Exception) cause, Maybe#(LdKilledBy) ld_killed);
|
||||
method Action rob_setExecuted_doFinishMem(InstTag t, Addr vaddr, Bool access_at_commit, Bool non_mmio_st_done
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
`endif
|
||||
);
|
||||
method Action rob_setExecuted_deqLSQ(InstTag t, Maybe#(Exception) cause, Maybe#(LdKilledBy) ld_killed
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
`endif
|
||||
);
|
||||
// MMIO
|
||||
method Bool isMMIOAddr(Addr a);
|
||||
method Action mmioReq(MMIOCRq r);
|
||||
@@ -179,7 +188,7 @@ interface MemExePipeline;
|
||||
endinterface
|
||||
|
||||
module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
Bool verbose = False;
|
||||
Bool verbose = True;
|
||||
|
||||
// we change cache request in case of single core, becaues our MSI protocol
|
||||
// is not good with single core
|
||||
@@ -270,7 +279,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
inIfc.setRegReadyAggr_mem(dst.indx);
|
||||
end
|
||||
if(verbose) begin
|
||||
$display("[Ld resp] ", fshow(id), "; ", fshow(d), "; ", fshow(info));
|
||||
$display("%t : [Ld resp] ", $time, fshow(id), "; ", fshow(d), "; ", fshow(info));
|
||||
end
|
||||
`ifdef PERF_COUNT
|
||||
// perf: load mem latency
|
||||
@@ -416,6 +425,10 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
});
|
||||
endrule
|
||||
|
||||
`ifdef RVFI_DII
|
||||
Vector#(TExp#(SizeOf#(LdStQTag)), Reg#(Data)) memData <- replicateM(mkReg(?));
|
||||
`endif
|
||||
|
||||
rule doExeMem;
|
||||
regToExeQ.deq;
|
||||
let regToExe = regToExeQ.first;
|
||||
@@ -425,6 +438,11 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
// get virtual addr & St/Sc/Amo data
|
||||
Addr vaddr = x.rVal1 + signExtend(x.imm);
|
||||
Data data = x.rVal2;
|
||||
|
||||
`ifdef RVFI_DII
|
||||
memData[pack(x.ldstq_tag)] <= data;
|
||||
$display("%t : memData[%x] <= %x", $time(), pack(x.ldstq_tag), data);
|
||||
`endif
|
||||
|
||||
// get shifted data and BE
|
||||
// we can use virtual addr to shift, since page size > dword size
|
||||
@@ -512,8 +530,21 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
endcase);
|
||||
Bool access_at_commit = !isValid(cause) && (isMMIO || isLrScAmo);
|
||||
Bool non_mmio_st_done = !isValid(cause) && !isMMIO && x.mem_func == St;
|
||||
inIfc.rob_setExecuted_doFinishMem(x.tag, x.vaddr,
|
||||
access_at_commit, non_mmio_st_done);
|
||||
inIfc.rob_setExecuted_doFinishMem(
|
||||
x.tag,
|
||||
x.vaddr,
|
||||
access_at_commit,
|
||||
non_mmio_st_done
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle{
|
||||
regWriteData: memData[pack(x.ldstq_tag)],
|
||||
memByteEn: unpack(pack(x.shiftedBE) >> x.vaddr[2:0])
|
||||
}
|
||||
`endif
|
||||
);
|
||||
`ifdef RVFI
|
||||
$display("%t : memData[%x]: %x", $time(), pack(x.ldstq_tag), memData[pack(x.ldstq_tag)]);
|
||||
`endif
|
||||
|
||||
// update LSQ
|
||||
LSQUpdateAddrResult updRes <- lsq.updateAddr(
|
||||
@@ -640,7 +671,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
function Action doRespLd(LdQTag tag, Data data, String rule_name);
|
||||
action
|
||||
LSQRespLdResult res <- lsq.respLd(tag, data);
|
||||
if(verbose) $display(rule_name, " ", fshow(tag), "; ", fshow(data), "; ", fshow(res));
|
||||
if(verbose) $display("%t : ", $time, rule_name, " ", fshow(tag), "; ", fshow(data), "; ", fshow(res));
|
||||
if(res.dst matches tagged Valid .dst) begin
|
||||
inIfc.writeRegFile(dst.indx, res.data);
|
||||
`ifdef PERF_COUNT
|
||||
@@ -650,6 +681,11 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
exeLdToUseLat.incr(zeroExtend(lat));
|
||||
exeLdToUseCnt.incr(1);
|
||||
end
|
||||
`endif
|
||||
`ifdef RVFI
|
||||
LdStQTag idx = tagged Ld tag;
|
||||
memData[pack(idx)] <= res.data;
|
||||
$display("%t : memData[%x] <= %x", $time(), pack(idx), res.data);
|
||||
`endif
|
||||
end
|
||||
if(res.wrongPath) begin
|
||||
@@ -657,7 +693,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
|
||||
rule doRespLdMem;
|
||||
memRespLdQ.deq;
|
||||
let {t, d} = memRespLdQ.first;
|
||||
@@ -673,12 +709,22 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
|
||||
// deqStQ
|
||||
LdQDeqEntry lsqDeqLd = lsq.firstLd;
|
||||
`ifdef RVFI
|
||||
LdStQTag lsqDeqIdx = tagged Ld lsqDeqLd.tag;
|
||||
`endif
|
||||
|
||||
// deq fault/killed ld
|
||||
rule doDeqLdQ_fault(isValid(lsqDeqLd.fault));
|
||||
if(verbose) $display("[doDeqLdQ_fault] ", fshow(lsqDeqLd));
|
||||
lsq.deqLd;
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqLd.instTag, lsqDeqLd.fault, Invalid);
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqLd.instTag, lsqDeqLd.fault, Invalid
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle{
|
||||
regWriteData: memData[pack(lsqDeqIdx)],
|
||||
memByteEn: replicate(False)
|
||||
}
|
||||
`endif
|
||||
);
|
||||
// check
|
||||
doAssert(!isValid(lsqDeqLd.killed), "cannot be killed");
|
||||
endrule
|
||||
@@ -693,7 +739,14 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
// normal load should not have .rl, so no need to check SB empty
|
||||
doAssert(!lsqDeqLd.rel, "normal Ld cannot have .rl");
|
||||
// set ROB as Executed (may be killed)
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqLd.instTag, Invalid, lsqDeqLd.killed);
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqLd.instTag, Invalid, lsqDeqLd.killed
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle{
|
||||
regWriteData: memData[pack(lsqDeqIdx)],
|
||||
memByteEn: replicate(False)
|
||||
}
|
||||
`endif
|
||||
);
|
||||
endrule
|
||||
|
||||
// issue non-MMIO Lr wihtout fault when
|
||||
@@ -781,7 +834,17 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
inIfc.writeRegFile(dst.indx, resp);
|
||||
inIfc.setRegReadyAggr_mem(dst.indx);
|
||||
end
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqLd.instTag, Invalid, Invalid);
|
||||
inIfc.rob_setExecuted_deqLSQ(
|
||||
lsqDeqLd.instTag,
|
||||
Invalid,
|
||||
Invalid
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle{
|
||||
regWriteData: resp,
|
||||
memByteEn: replicate(False)
|
||||
}
|
||||
`endif
|
||||
);
|
||||
if(verbose) $display("[doDeqLdQ_Lr_deq] ", fshow(lsqDeqLd), "; ", fshow(d), "; ", fshow(resp));
|
||||
// check
|
||||
doAssert(lsqDeqLd.memFunc == Lr && !lsqDeqLd.isMMIO, "must be non-MMIO Lr");
|
||||
@@ -856,7 +919,14 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
inIfc.writeRegFile(dst.indx, resp);
|
||||
inIfc.setRegReadyAggr_mem(dst.indx);
|
||||
end
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqLd.instTag, Invalid, Invalid);
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqLd.instTag, Invalid, Invalid
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle{
|
||||
regWriteData: resp,
|
||||
memByteEn: replicate(False)
|
||||
}
|
||||
`endif
|
||||
);
|
||||
if(verbose) $display("[doDeqLdQ_MMIO_deq] ", fshow(lsqDeqLd), "; ", fshow(d), "; ", fshow(resp));
|
||||
// check
|
||||
doAssert(lsqDeqLd.memFunc == Ld && lsqDeqLd.isMMIO, "must be MMIO Ld");
|
||||
@@ -881,7 +951,14 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
lsq.deqLd;
|
||||
waitLrScAmoMMIOResp <= Invalid;
|
||||
// set ROB to raise access fault
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqLd.instTag, Valid (LoadAccessFault), Invalid);
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqLd.instTag, Valid (LoadAccessFault), Invalid
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle{
|
||||
regWriteData: memData[pack(lsqDeqIdx)],
|
||||
memByteEn: replicate(False)
|
||||
}
|
||||
`endif
|
||||
);
|
||||
if(verbose) $display("[doDeqLdQ_MMIO_fault] ", fshow(lsqDeqLd));
|
||||
// check
|
||||
doAssert(lsqDeqLd.memFunc == Ld && lsqDeqLd.isMMIO, "must be MMIO Ld");
|
||||
@@ -894,7 +971,14 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
rule doDeqStQ_fault(isValid(lsqDeqSt.fault));
|
||||
if(verbose) $display("[doDeqStQ_fault] ", fshow(lsqDeqSt));
|
||||
lsq.deqSt;
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqSt.instTag, lsqDeqSt.fault, Invalid);
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqSt.instTag, lsqDeqSt.fault, Invalid
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle{
|
||||
regWriteData: lsqDeqSt.stData,
|
||||
memByteEn: replicate(False)
|
||||
}
|
||||
`endif
|
||||
);
|
||||
endrule
|
||||
|
||||
`ifdef TSO_MM
|
||||
@@ -983,7 +1067,14 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
`endif
|
||||
lsq.deqSt;
|
||||
// set ROB executed
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqSt.instTag, Invalid, Invalid);
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqSt.instTag, Invalid, Invalid
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle{
|
||||
regWriteData: lsqDeqSt.stData,
|
||||
memByteEn: replicate(False)
|
||||
}
|
||||
`endif
|
||||
);
|
||||
if(verbose) $display("[doDeqStQ_Fence] ", fshow(lsqDeqSt));
|
||||
`ifdef PERF_COUNT
|
||||
if(inIfc.doStats) begin
|
||||
@@ -1076,7 +1167,14 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
inIfc.writeRegFile(dst.indx, resp);
|
||||
inIfc.setRegReadyAggr_mem(dst.indx);
|
||||
end
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqSt.instTag, Invalid, Invalid);
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqSt.instTag, Invalid, Invalid
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle{
|
||||
regWriteData: resp,
|
||||
memByteEn: replicate(False)
|
||||
}
|
||||
`endif
|
||||
);
|
||||
if(verbose) $display("[doDeqStQ_ScAmo_deq] ", fshow(lsqDeqSt), "; ", fshow(resp));
|
||||
// check
|
||||
doAssert((lsqDeqSt.memFunc == Sc || lsqDeqSt.memFunc == Amo) &&
|
||||
@@ -1172,7 +1270,14 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
inIfc.writeRegFile(dst.indx, resp);
|
||||
inIfc.setRegReadyAggr_mem(dst.indx);
|
||||
end
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqSt.instTag, Invalid, Invalid);
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqSt.instTag, Invalid, Invalid
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle{
|
||||
regWriteData: resp,
|
||||
memByteEn: replicate(False)
|
||||
}
|
||||
`endif
|
||||
);
|
||||
if(verbose) $display("[doDeqStQ_MMIO_deq] ", fshow(lsqDeqSt), "; ", fshow(resp));
|
||||
// check
|
||||
doAssert(lsqDeqSt.memFunc == St || lsqDeqSt.memFunc == Amo, "must be St/Amo");
|
||||
@@ -1197,7 +1302,14 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
lsq.deqSt;
|
||||
waitLrScAmoMMIOResp <= Invalid;
|
||||
// set ROB to raise access fault
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqSt.instTag, Valid (StoreAccessFault), Invalid);
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqSt.instTag, Valid (StoreAccessFault), Invalid
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle{
|
||||
regWriteData: lsqDeqSt.stData,
|
||||
memByteEn: replicate(False)
|
||||
}
|
||||
`endif
|
||||
);
|
||||
if(verbose) $display("[doDeqStQ_MMIO_fault] ", fshow(lsqDeqSt));
|
||||
// check
|
||||
doAssert(lsqDeqSt.memFunc == St || lsqDeqSt.memFunc == Amo, "must be St/Amo");
|
||||
|
||||
@@ -49,12 +49,7 @@ endfunction
|
||||
|
||||
module mkEhr#(t init)(Ehr#(n, t)) provisos(Bits#(t, tSz));
|
||||
Vector#(n, RWire#(t)) lat <- replicateM(mkUnsafeRWire);
|
||||
|
||||
Vector#(n, Vector#(n, RWire#(Bool))) dummy <- replicateM(replicateM(mkUnsafeRWire));
|
||||
Vector#(n, Reg#(Bool)) dummy2 <- replicateM(mkRevertingVirtualReg(True)); // this must be true
|
||||
|
||||
Reg#(t) rl <- mkReg(init);
|
||||
|
||||
Ehr#(n, t) r = newVector;
|
||||
|
||||
(* fire_when_enabled, no_implicit_conditions *)
|
||||
@@ -70,22 +65,16 @@ module mkEhr#(t init)(Ehr#(n, t)) provisos(Bits#(t, tSz));
|
||||
r[i] = (interface Reg;
|
||||
method Action _write(t x);
|
||||
lat[i].wset(x);
|
||||
dummy2[i] <= True;
|
||||
for(Integer j = 0; j < i; j = j + 1)
|
||||
dummy[i][j].wset(isValid(lat[j].wget));
|
||||
endmethod
|
||||
|
||||
method t _read;
|
||||
t upd = rl;
|
||||
Bool yes = True;
|
||||
for(Integer j = i; j < valueOf(n); j = j + 1)
|
||||
yes = yes && dummy2[j];
|
||||
for(Integer j = 0; j < i; j = j + 1)
|
||||
begin
|
||||
if(lat[j].wget matches tagged Valid .x)
|
||||
upd = x;
|
||||
end
|
||||
return yes? upd : unpack(0);
|
||||
return upd;
|
||||
// use a non-? val here! otherwise new BSV compiler will stop optimize at ? val
|
||||
// this affects judging if two rules are exclusive
|
||||
endmethod
|
||||
|
||||
@@ -111,7 +111,11 @@ interface ReorderBufferRowEhr#(numeric type aluExeNum, numeric type fpuMulDivExe
|
||||
method ToReorderBuffer read_deq;
|
||||
method Action setLSQAtCommitNotified;
|
||||
// deqLSQ rules set ROB state: set execeptions, load mispeculation, and becomes Executed
|
||||
method Action setExecuted_deqLSQ(Maybe#(Exception) cause, Maybe#(LdKilledBy) ld_killed);
|
||||
method Action setExecuted_deqLSQ(Maybe#(Exception) cause, Maybe#(LdKilledBy) ld_killed
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
`endif
|
||||
);
|
||||
// doFinish rules set ROB state for ALU and FPU/MUL/DIV (always become Executed)
|
||||
interface Vector#(aluExeNum, Row_setExecuted_doFinishAlu) setExecuted_doFinishAlu;
|
||||
interface Vector#(fpuMulDivExeNum, Row_setExecuted_doFinishFpuMulDiv) setExecuted_doFinishFpuMulDiv;
|
||||
@@ -120,7 +124,11 @@ interface ReorderBufferRowEhr#(numeric type aluExeNum, numeric type fpuMulDivExe
|
||||
// faulting inst cannot have this set, since there is no access to
|
||||
// perform), and non-MMIO St can become Executed (NOTE faulting
|
||||
// instructions are not Executed, they are set at deqLSQ time)
|
||||
method Action setExecuted_doFinishMem(Addr vaddr, Bool access_at_commit, Bool non_mmio_st_done);
|
||||
method Action setExecuted_doFinishMem(Addr vaddr, Bool access_at_commit, Bool non_mmio_st_done
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
`endif
|
||||
);
|
||||
`ifdef INORDER_CORE
|
||||
// in-order core sets LSQ tag after getting out of issue queue
|
||||
method Action setLSQTag(LdStQTag t, Bool isFence);
|
||||
@@ -204,6 +212,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
Ehr#(3, SpecBits) spec_bits <- mkEhr(?);
|
||||
`ifdef RVFI
|
||||
Ehr#(TAdd#(2, aluExeNum), (ExtraTraceBundle)) traceBundle <- mkEhr(?);
|
||||
Reg#(ExtraTraceBundle) traceBundleMem <- mkRegU;
|
||||
`endif
|
||||
|
||||
// wires to get stale (EHR port 0) values of PPC
|
||||
@@ -233,6 +242,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
ppc_vaddr_csrData[pvc_finishAlu_port(i)] <= PPC (cf.nextPc);
|
||||
end
|
||||
`ifdef RVFI
|
||||
$display("%t : traceBundle = ", $time(), fshow(tb), " in Row_setExecuted_doFinishAlu for %x", pc);
|
||||
traceBundle[pvc_finishAlu_port(i)] <= tb;
|
||||
`endif
|
||||
doAssert(isValid(csr) == isValid(csrData), "csr valid should match");
|
||||
@@ -260,7 +270,11 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
|
||||
interface setExecuted_doFinishFpuMulDiv = fpuMulDivExe;
|
||||
|
||||
method Action setExecuted_doFinishMem(Addr vaddr, Bool access_at_commit, Bool non_mmio_st_done);
|
||||
method Action setExecuted_doFinishMem(Addr vaddr, Bool access_at_commit, Bool non_mmio_st_done
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
`endif
|
||||
);
|
||||
doAssert(!(access_at_commit && non_mmio_st_done),
|
||||
"cannot both be true");
|
||||
// update ROB state
|
||||
@@ -270,6 +284,10 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
end
|
||||
// update VAddr
|
||||
ppc_vaddr_csrData[pvc_finishMem_port] <= VAddr (vaddr);
|
||||
`ifdef RVFI
|
||||
$display("%t : traceBundle = ", $time(), fshow(tb), " in setExecuted_doFinishMem for %x", pc);
|
||||
traceBundle[pvc_finishMem_port] <= tb;
|
||||
`endif
|
||||
// update access at commit
|
||||
memAccessAtCommit[accessCom_finishMem_port] <= access_at_commit;
|
||||
// udpate non mmio st
|
||||
@@ -310,6 +328,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
lsqAtCommitNotified[lsqNotified_enq_port] <= False;
|
||||
nonMMIOStDone[nonMMIOSt_enq_port] <= False;
|
||||
`ifdef RVFI
|
||||
$display("%t : traceBundle = ", $time(), fshow(x.traceBundle), " in write_enq for %x", pc);
|
||||
traceBundle[pvc_enq_port] <= x.traceBundle;
|
||||
`endif
|
||||
// check
|
||||
@@ -339,7 +358,15 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
nonMMIOStDone: nonMMIOStDone[nonMMIOSt_deq_port],
|
||||
epochIncremented: epochIncremented,
|
||||
`ifdef RVFI
|
||||
traceBundle: traceBundle[pvc_deq_port],
|
||||
traceBundle: case (ppc_vaddr_csrData[pvc_deq_port]) matches
|
||||
tagged VAddr .v: begin
|
||||
case (lsqTag) matches
|
||||
tagged Ld .l: return traceBundleMem;
|
||||
default: return traceBundle[pvc_deq_port];
|
||||
endcase
|
||||
end
|
||||
default: return traceBundle[pvc_deq_port];
|
||||
endcase,
|
||||
`endif
|
||||
spec_bits: spec_bits[sb_deq_port]
|
||||
};
|
||||
@@ -349,9 +376,19 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
lsqAtCommitNotified[lsqNotified_setNotified_port] <= True;
|
||||
endmethod
|
||||
|
||||
method Action setExecuted_deqLSQ(Maybe#(Exception) cause, Maybe#(LdKilledBy) ld_killed);
|
||||
method Action setExecuted_deqLSQ(
|
||||
Maybe#(Exception) cause,
|
||||
Maybe#(LdKilledBy) ld_killed
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
`endif
|
||||
);
|
||||
// inst becomes Executed
|
||||
rob_inst_state[state_deqLSQ_port] <= Executed;
|
||||
`ifdef RVFI
|
||||
traceBundleMem <= tb;
|
||||
$display("%t: Wrote tb for deqLSQ ", $time(), fshow(tb));
|
||||
`endif
|
||||
// record trap
|
||||
doAssert(!isValid(trap[trap_deqLSQ_port]), "cannot have trap");
|
||||
if(cause matches tagged Valid .e) begin
|
||||
@@ -447,12 +484,20 @@ interface SupReorderBuffer#(numeric type aluExeNum, numeric type fpuMulDivExeNum
|
||||
// record that we have notified LSQ about inst reaching commit
|
||||
method Action setLSQAtCommitNotified(InstTag x);
|
||||
// deqLSQ rules set ROB state
|
||||
method Action setExecuted_deqLSQ(InstTag x, Maybe#(Exception) cause, Maybe#(LdKilledBy) ld_killed);
|
||||
method Action setExecuted_deqLSQ(InstTag x, Maybe#(Exception) cause, Maybe#(LdKilledBy) ld_killed
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
`endif
|
||||
);
|
||||
// doFinish rules set ROB state in ALU and FPU/MUL/DIV
|
||||
interface Vector#(aluExeNum, ROB_setExecuted_doFinishAlu) setExecuted_doFinishAlu;
|
||||
interface Vector#(fpuMulDivExeNum, ROB_setExecuted_doFinishFpuMulDiv) setExecuted_doFinishFpuMulDiv;
|
||||
// doFinishMem, after addr translation
|
||||
method Action setExecuted_doFinishMem(InstTag x, Addr vaddr, Bool access_at_commit, Bool non_mmio_st_done);
|
||||
method Action setExecuted_doFinishMem(InstTag x, Addr vaddr, Bool access_at_commit, Bool non_mmio_st_done
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
`endif
|
||||
);
|
||||
`ifdef INORDER_CORE
|
||||
// in-order core sets LSQ tag after getting out of issue queue
|
||||
method Action setLSQTag(InstTag x, LdStQTag t, Bool isFence);
|
||||
@@ -1016,10 +1061,18 @@ module mkSupReorderBuffer#(
|
||||
row[x.way][x.ptr].setLSQAtCommitNotified;
|
||||
endmethod
|
||||
|
||||
method Action setExecuted_deqLSQ(InstTag x, Maybe#(Exception) cause, Maybe#(LdKilledBy) ld_killed) if(
|
||||
method Action setExecuted_deqLSQ(InstTag x, Maybe#(Exception) cause, Maybe#(LdKilledBy) ld_killed
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
`endif
|
||||
) if(
|
||||
all(id, readVReg(setExeLSQ_SB_enq)) // ordering: < enq
|
||||
);
|
||||
row[x.way][x.ptr].setExecuted_deqLSQ(cause, ld_killed);
|
||||
row[x.way][x.ptr].setExecuted_deqLSQ(cause, ld_killed
|
||||
`ifdef RVFI
|
||||
, tb
|
||||
`endif
|
||||
);
|
||||
endmethod
|
||||
|
||||
interface setExecuted_doFinishAlu = aluSetExeIfc;
|
||||
@@ -1028,10 +1081,17 @@ module mkSupReorderBuffer#(
|
||||
|
||||
method Action setExecuted_doFinishMem(
|
||||
InstTag x, Addr vaddr, Bool access_at_commit, Bool non_mmio_st_done
|
||||
`ifdef RVFI
|
||||
, tb
|
||||
`endif
|
||||
) if(
|
||||
all(id, readVReg(setExeMem_SB_enq)) // ordering: < enq
|
||||
);
|
||||
row[x.way][x.ptr].setExecuted_doFinishMem(vaddr, access_at_commit, non_mmio_st_done);
|
||||
row[x.way][x.ptr].setExecuted_doFinishMem(vaddr, access_at_commit, non_mmio_st_done
|
||||
`ifdef RVFI
|
||||
, tb
|
||||
`endif
|
||||
);
|
||||
endmethod
|
||||
|
||||
`ifdef INORDER_CORE
|
||||
|
||||
@@ -288,6 +288,7 @@ typedef struct {
|
||||
} LSQHitInfo deriving(Bits, Eq, FShow);
|
||||
|
||||
typedef struct {
|
||||
LdQTag tag;
|
||||
InstTag instTag;
|
||||
LdQMemFunc memFunc;
|
||||
ByteEn byteEn;
|
||||
@@ -2009,6 +2010,7 @@ module mkSplitLSQ(SplitLSQ);
|
||||
method LdQDeqEntry firstLd if(deqLdGuard);
|
||||
LdQTag deqP = ld_deqP_deqLd;
|
||||
return LdQDeqEntry {
|
||||
tag: deqP,
|
||||
instTag: ld_instTag[deqP],
|
||||
memFunc: ld_memFunc[deqP],
|
||||
byteEn: ld_byteEn[deqP],
|
||||
|
||||
Reference in New Issue
Block a user