Added checking for wild exceptions in MemExePipeline including adding an addtional port to the ROB for reading ppc/orig_inst
This commit is contained in:
@@ -504,6 +504,10 @@ module mkCore#(CoreId coreId)(Core);
|
||||
method setRegReadyAggr_forward = writeAggr(forwardWrAggrPort);
|
||||
method writeRegFile = writeCons(memWrConsPort);
|
||||
method doStats = doStatsReg._read;
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
method rob_getPredPC = rob.getOrigPredPC[valueof(AluExeNum)].get; // last getOrigPredPC port
|
||||
method rob_getOrig_Inst = rob.getOrig_Inst[valueof(AluExeNum)].get; // last getOrig_Inst port
|
||||
`endif
|
||||
endinterface);
|
||||
let memExe <- mkMemExePipeline(memExeInput);
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ import CacheUtils::*;
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
import PerformanceMonitor::*;
|
||||
import BlueUtils::*;
|
||||
import DReg::*;
|
||||
`endif
|
||||
|
||||
import Cur_Cycle :: *;
|
||||
@@ -219,6 +220,11 @@ interface MemExeInput;
|
||||
|
||||
// performance
|
||||
method Bool doStats;
|
||||
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
method CapMem rob_getPredPC(InstTag t);
|
||||
method Bit #(32) rob_getOrig_Inst (InstTag t);
|
||||
`endif
|
||||
endinterface
|
||||
|
||||
interface MemExePipeline;
|
||||
@@ -236,6 +242,7 @@ interface MemExePipeline;
|
||||
method Data getPerf(ExeStagePerfType t);
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
method EventsCoreMem events;
|
||||
method EventsTransExe events_trans;
|
||||
`endif
|
||||
endinterface
|
||||
|
||||
@@ -278,6 +285,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
Array #(Reg #(EventsCoreMem)) events_reg <- mkDRegOR (5, unpack (0));
|
||||
Reg#(EventsTransExe) events_trans_reg <- mkDReg(unpack(0));
|
||||
`endif
|
||||
|
||||
// reservation station
|
||||
@@ -672,6 +680,24 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
`endif
|
||||
);
|
||||
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
function Bool is_16b_inst (Bit #(n) inst);
|
||||
return (inst [1:0] != 2'b11);
|
||||
endfunction
|
||||
let pc = inIfc.rob_getPC(x.tag);
|
||||
let ppc = inIfc.rob_getPredPC(x.tag);
|
||||
let inst = inIfc.rob_getOrig_Inst(x.tag);
|
||||
let validPc = is_16b_inst(inst) ? addPc(pc,2) : addPc(pc,4);
|
||||
$display("spec_excps: pc = ", fshow(pc), ", ppc = ", fshow(ppc), ", validPc = ", fshow(validPc));
|
||||
$display("sbc_excps: cause = ", fshow(cause));
|
||||
if(cause matches tagged Valid .c &&& (ppc != validPc)) begin
|
||||
$display("Wild Exception");
|
||||
EventsTransExe events_trans = unpack(0);
|
||||
events_trans.evt_WILD_EXCEPTION = 1;
|
||||
events_trans_reg <= events_trans;
|
||||
end
|
||||
`endif
|
||||
|
||||
// update LSQ
|
||||
LSQUpdateAddrResult updRes <- lsq.updateAddr(
|
||||
x.ldstq_tag, cause, x.allowCapLoad && allowCapPTE, paddr, isMMIO, x.shiftedBE
|
||||
@@ -1581,5 +1607,6 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
endmethod
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
method events = events_reg[0];
|
||||
method events_trans = events_trans_reg;
|
||||
`endif
|
||||
endmodule
|
||||
|
||||
@@ -645,9 +645,13 @@ interface SupReorderBuffer#(numeric type aluExeNum, numeric type fpuMulDivExeNum
|
||||
|
||||
// get original PC/PPC before execution, EHR port 0 will suffice
|
||||
interface Vector#(TAdd#(1, aluExeNum), ROB_getOrigPC) getOrigPC;
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
interface Vector#(TAdd#(1, aluExeNum), ROB_getOrigPredPC) getOrigPredPC;
|
||||
interface Vector#(TAdd#(1, aluExeNum), ROB_getOrig_Inst) getOrig_Inst;
|
||||
`else
|
||||
interface Vector#(aluExeNum, ROB_getOrigPredPC) getOrigPredPC;
|
||||
interface Vector#(aluExeNum, ROB_getOrig_Inst) getOrig_Inst;
|
||||
|
||||
`endif
|
||||
// get enq time for reservation station dispatch
|
||||
method InstTime getEnqTime;
|
||||
|
||||
@@ -1172,18 +1176,39 @@ module mkSupReorderBuffer#(
|
||||
|
||||
// get pc/ppc ifc used by alu exe (also one pc for mem exe)
|
||||
Vector#(TAdd#(1, aluExeNum), ROB_getOrigPC) getOrigPCIfc;
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
Vector#(TAdd#(1, aluExeNum), ROB_getOrigPredPC) getOrigPredPCIfc;
|
||||
`else
|
||||
Vector#(aluExeNum, ROB_getOrigPredPC) getOrigPredPCIfc;
|
||||
`endif
|
||||
for(Integer i = 0; i < valueof(aluExeNum) + 1; i = i+1) begin
|
||||
getOrigPCIfc[i] = (interface ROB_getOrigPC;
|
||||
method CapMem get(InstTag x) = row[x.way][x.ptr].getOrigPC;
|
||||
endinterface);
|
||||
end
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
for(Integer i = 0; i < valueof(aluExeNum) + 1; i = i+1) begin
|
||||
getOrigPredPCIfc[i] = (interface ROB_getOrigPredPC;
|
||||
method CapMem get(InstTag x) = row[x.way][x.ptr].getOrigPredPC;
|
||||
endinterface);
|
||||
end
|
||||
`else
|
||||
for(Integer i = 0; i < valueof(aluExeNum); i = i+1) begin
|
||||
getOrigPredPCIfc[i] = (interface ROB_getOrigPredPC;
|
||||
method CapMem get(InstTag x) = row[x.way][x.ptr].getOrigPredPC;
|
||||
endinterface);
|
||||
end
|
||||
`endif
|
||||
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
// get original instr (16b or 32b). Lsbs [1:0] encode whether 16b or 32b
|
||||
Vector#(TAdd#(1, aluExeNum), ROB_getOrig_Inst) getOrig_Inst_Ifc;
|
||||
for(Integer i = 0; i < valueof(aluExeNum) + 1; i = i+1) begin
|
||||
getOrig_Inst_Ifc[i] = (interface ROB_getOrig_Inst;
|
||||
method Bit #(32) get(InstTag x) = row[x.way][x.ptr].getOrig_Inst;
|
||||
endinterface);
|
||||
end
|
||||
`else
|
||||
// get original instr (16b or 32b). Lsbs [1:0] encode whether 16b or 32b
|
||||
Vector#(aluExeNum, ROB_getOrig_Inst) getOrig_Inst_Ifc;
|
||||
for(Integer i = 0; i < valueof(aluExeNum); i = i+1) begin
|
||||
@@ -1191,6 +1216,7 @@ module mkSupReorderBuffer#(
|
||||
method Bit #(32) get(InstTag x) = row[x.way][x.ptr].getOrig_Inst;
|
||||
endinterface);
|
||||
end
|
||||
`endif
|
||||
|
||||
interface enqPort = enqIfc;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user