diff --git a/src_Core/CPU/Core.bsv b/src_Core/CPU/Core.bsv index 2608116..6e01c05 100644 --- a/src_Core/CPU/Core.bsv +++ b/src_Core/CPU/Core.bsv @@ -309,6 +309,10 @@ module mkCore#(CoreId coreId)(Core); for(Integer i = 0; i < valueof(SupSize); i=i+1) begin bags[i] <- mkSmallBag; end + Vector#(SupSize, Bag#(16, CapMem, CapMem)) returnBags; + for(Integer i = 0; i < valueof(SupSize); i=i+1) begin + returnBags[i] <- mkSmallBag; + end // We have two scoreboards: one conservative and other aggressive // - Aggressive sb is checked at rename stage, so inst after rename may be issued early @@ -436,6 +440,13 @@ module mkCore#(CoreId coreId)(Core); end return ret; endmethod + method Bool checkReturnTarget(CapMem ppc); + Bool ret = False; + for(Integer j = 0; j < valueof(SupSize); j=j+1) begin + ret = ret || returnBags[j].isMember(ppc).v; + end + return ret; + endmethod endinterface); aluExe[i] <- mkAluExePipeline(aluExeInput); // truly call fetch method to train branch predictor @@ -696,6 +707,14 @@ module mkCore#(CoreId coreId)(Core); end endmethod + method Action updateReturnTargets(Vector#(SupSize, Maybe#(CapMem)) returnTargets); + for(Integer i = 0; i < valueof(SupSize); i=i+1) begin + if(returnTargets[i] matches tagged Valid .retTar) begin + returnBags[i].insert(retTar, retTar); + end + end + endmethod + `ifdef INCLUDE_TANDEM_VERIF interface v_to_TV = map (toPut, v_f_to_TV); `endif diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv index b54e0be..2073bb4 100755 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv @@ -198,6 +198,8 @@ interface AluExeInput; // check previous branch targets method Bool checkTarget(CapMem ppc); + // check (previous) return targets + method Bool checkReturnTarget(CapMem ppc); endinterface interface AluExePipeline; @@ -294,6 +296,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline); let ppc = inIfc.rob_getPredPC(x.tag); let orig_inst = inIfc.rob_getOrig_Inst (x.tag); + // TODO: split into Br, jumps, and rets `ifdef PERFORMANCE_MONITORING if(x.dInst.iType == Br || x.dInst.iType == Jr || x.dInst.iType == CJALR) begin $display("BRANCH pc = ", fshow(pc), ", ppc = ", fshow(ppc)); diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv index e6f00c8..219f5fd 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv @@ -134,6 +134,8 @@ interface CommitInput; // update branch targets method Action updateTargets(Vector#(SupSize, Maybe#(CapMem)) targets); + // update return targets + method Action updateReturnTargets(Vector#(SupSize, Maybe#(CapMem)) returnTargets); `ifdef INCLUDE_TANDEM_VERIF interface Vector #(SupSize, Put #(Trace_Data2)) v_to_TV; @@ -1093,9 +1095,12 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage); // update targets vector Vector#(SupSize, Maybe#(CapMem)) targets; + // update return targets vector + Vector#(SupSize, Maybe#(CapMem)) returnTargets; // compute what actions to take for(Integer i = 0; i < valueof(SupSize); i = i+1) begin Maybe#(CapMem) tar = tagged Invalid; + Maybe#(CapMem) retTar = tagged Invalid; if(!stop && rob.deqPort[i].canDeq) begin let x = rob.deqPort[i].deq_data; let inst_tag = rob.deqPort[i].getDeqInstTag; @@ -1139,6 +1144,20 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage); // inst can be committed, deq it rob.deqPort[i].deq; + // return address stack link reg is x1 or x5 + function Bool linkedR(Maybe#(ArchRIndx) register); + Bool res = False; + if (register matches tagged Valid .r &&& (r == tagged Gpr 1 || r == tagged Gpr 5)) begin + res = True; + end + return res; + endfunction + + // update return target + if((x.iType == J || x.iType == CJAL) && linkedR(x.dst)) begin + retTar = tagged Valid x.ppc_vaddr_csrData.PPC; + end + // update target if(x.iType == CJALR || x.iType == Jr) begin tar = tagged Valid x.ppc_vaddr_csrData.PPC; @@ -1220,6 +1239,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage); end end targets[i] = tar; + returnTargets[i] = retTar; end rg_serial_num <= rg_serial_num + instret; @@ -1285,6 +1305,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage); `endif inIfc.updateTargets(targets); + inIfc.updateReturnTargets(returnTargets); `ifdef RVFI rvfiQ.enq(rvfis);