diff --git a/libs/RISCV_HPM_Events b/libs/RISCV_HPM_Events index ad8aafb..f422ffa 160000 --- a/libs/RISCV_HPM_Events +++ b/libs/RISCV_HPM_Events @@ -1 +1 @@ -Subproject commit ad8aafbbd0bc4f98fbd19d94e02982cae2e44329 +Subproject commit f422ffa0bad3233135d99daa9f8d2b6f1eb95ba1 diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv old mode 100755 new mode 100644 diff --git a/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi b/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi index 018b513..c13ed2c 100644 --- a/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi +++ b/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi @@ -22,4 +22,5 @@ `CAP_CHECK_FIELD(src1_derivable,"src1_derivable") `CAP_CHECK_FIELD(cfromptr_bypass,"cfromptr_bypass") `CAP_CHECK_FIELD(ccseal_bypass,"ccseal_bypass") +`CAP_CHECK_FIELD(ccopytype_bypass,"ccopytype_bypass") `CAP_CHECK_FIELD(cap_exact,"cap_exact") diff --git a/src_Core/RISCY_OOO/procs/lib/Decode.bsv b/src_Core/RISCY_OOO/procs/lib/Decode.bsv old mode 100755 new mode 100644 index 8287ad4..b9d84df --- a/src_Core/RISCY_OOO/procs/lib/Decode.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Decode.bsv @@ -1174,6 +1174,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capChecks.check_low_src = Src1Type; dInst.capChecks.check_high_src = Src1Type; dInst.capChecks.check_inclusive = False; + dInst.capChecks.ccopytype_bypass = True; dInst.iType = Cap; regs.dst = Valid(tagged Gpr rd); diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv old mode 100755 new mode 100644 index 2d317db..de79c83 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -5,6 +5,7 @@ // Copyright (c) 2020 Alexandre Joannou // Copyright (c) 2020 Peter Rugg // Copyright (c) 2020 Jonathan Woodruff +// Copyright (c) 2021 Marno van der Maas // All rights reserved. // // This software was developed by SRI International and the University of @@ -437,6 +438,10 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C capException = Invalid; boundsCheck = Invalid; end + if (dInst.capChecks.ccopytype_bypass && isValidCap(rVal2) && getKind(rVal2) == UNSEALED && (getKind(rVal1) matches tagged SEALED_WITH_TYPE .t ? !validAsType(rVal2, zeroExtend(t)) : True)) begin + capException = Invalid; + boundsCheck = Invalid; + end cf.nextPc = setKind(cf.nextPc, UNSEALED); cf.mispredict = cf.nextPc != ppc; diff --git a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv old mode 100755 new mode 100644 diff --git a/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv b/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv old mode 100755 new mode 100644 index 784f28c..1ca4aa7 --- a/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv @@ -685,7 +685,7 @@ module mkSupReorderBuffer#( // these are handled in mkReorderBufferRowEhr // wrong speculation: make wrong speculation conflict with enq - Vector#(SupSize, RWire#(void)) wrongSpec_enq_conflict <- replicateM(mkRWire); + Vector#(SupSize, PulseWire) wrongSpec_enq_conflict <- replicateM(mkPulseWire); // SupSize number of FIFOs Vector#(SupSize, Vector#(SingleScalarSize, ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum))) row <- replicateM(replicateM(mkRobRow)); @@ -1051,12 +1051,11 @@ module mkSupReorderBuffer#( Bool can_enq = can_enq_fifo[way]; enqIfc[i] = (interface ROB_EnqPort; method Bool canEnq = can_enq; - method Action enq(ToReorderBuffer x) if(can_enq); + method Action enq(ToReorderBuffer x) if(can_enq + && !wrongSpec_enq_conflict[i]); // make it conflict with wrong speculation doAssert(getEnqPort(way) == fromInteger(i), "enq FIFO way matches enq port"); // record enq action, real action is applied later enqEn[i].wset(x); - // make it conflict with wrong speculation - wrongSpec_enq_conflict[i].wset(?); // ordering: sequence after many other methods deq_SB_enq[i] <= False; setExeAlu_SB_enq[i] <= False; @@ -1321,7 +1320,7 @@ module mkSupReorderBuffer#( deq_SB_wrongSpec <= False; // make it conflict with enq for(Integer i = 0; i < valueof(SupSize); i = i+1) begin - wrongSpec_enq_conflict[i].wset(?); + wrongSpec_enq_conflict[i].send; end endmethod endinterface diff --git a/src_Core/RISCY_OOO/procs/lib/SpecFifo.bsv b/src_Core/RISCY_OOO/procs/lib/SpecFifo.bsv index 019b93b..3a40a87 100644 --- a/src_Core/RISCY_OOO/procs/lib/SpecFifo.bsv +++ b/src_Core/RISCY_OOO/procs/lib/SpecFifo.bsv @@ -90,21 +90,21 @@ module mkSpecFifo#( Reg#(idxT) deqP = deqP_ehr[0]; // port 0 is for deq and canon_deqP // make incorrectSpeculation conflict with others - RWire#(void) dummyRWire = (interface RWire; - method Maybe#(void) wget = Invalid; - method Action wset(void x) = noAction; - endinterface); - RWire#(void) wrongSpec_enq_conflict = dummyRWire; - RWire#(void) wrongSpec_deq_conflict = dummyRWire; - RWire#(void) wrongSpec_canon_conflict = dummyRWire; + PulseWire dummyPulseWire = interface PulseWire; + method Bool _read = False; + method Action send = noAction; + endinterface; + PulseWire wrongSpec_enq_conflict = dummyPulseWire; + PulseWire wrongSpec_deq_conflict = dummyPulseWire; + PulseWire wrongSpec_canon_conflict = dummyPulseWire; if(sched.wrongSpec_conflict_enq) begin - wrongSpec_enq_conflict <- mkRWire; + wrongSpec_enq_conflict <- mkPulseWire; end if(sched.wrongSpec_conflict_deq) begin - wrongSpec_deq_conflict <- mkRWire; + wrongSpec_deq_conflict <- mkPulseWire; end if(sched.wrongSpec_conflict_canon) begin - wrongSpec_canon_conflict <- mkRWire; + wrongSpec_canon_conflict <- mkPulseWire; end function idxT getNextPtr(idxT p); @@ -112,11 +112,10 @@ module mkSpecFifo#( endfunction Bool empty_for_canon = all( \== (False) , readVEhr(sched.validDeqPort, valid) ); - rule canon_deqP(!valid[deqP][sched.validDeqPort] && (enqP != deqP || !empty_for_canon)); + rule canon_deqP(!valid[deqP][sched.validDeqPort] && (enqP != deqP || !empty_for_canon) + && !wrongSpec_canon_conflict); // make conflict with incorrect spec // element at deqP was killed, so increment deqP deqP <= getNextPtr(deqP); - // make conflict with incorrect spec - wrongSpec_canon_conflict.wset(?); endrule // calculate guard for enq, we can do aggressively or lazily @@ -146,24 +145,20 @@ module mkSpecFifo#( valid_for_enq = valid[enqP][sched.validEnqPort]; end - method Action enq(ToSpecFifo#(t) x) if (empty_for_enq || enqP != deqP_for_enq); + method Action enq(ToSpecFifo#(t) x) if ((empty_for_enq || enqP != deqP_for_enq) + && !wrongSpec_enq_conflict); // make conflict with incorrect spec // [sizhuo] I don't think valid bit needs to be checked here doAssert(!valid_for_enq, "enq entry cannot be valid"); enqP <= getNextPtr(enqP); valid[enqP][sched.validEnqPort] <= True; row[enqP] <= x.data; specBits[enqP][sched.sbEnqPort] <= x.spec_bits; - // make conflict with incorrect spec - wrongSpec_enq_conflict.wset(?); endmethod - method Bool notFull = (empty_for_enq || enqP != deqP_for_enq); - - method Action deq if (valid[deqP][sched.validDeqPort]); + method Action deq if (valid[deqP][sched.validDeqPort] + && !wrongSpec_deq_conflict); // make conflict with incorrect spec valid[deqP][sched.validDeqPort] <= False; deqP <= getNextPtr(deqP); - // make conflict with incorrect spec - wrongSpec_deq_conflict.wset(?); endmethod method ToSpecFifo#(t) first if (valid[deqP][sched.validDeqPort]); @@ -201,9 +196,9 @@ module mkSpecFifo#( Vector#(size, Integer) idxVec = genVector; joinActions(map(incorrectSpec, idxVec)); // make conflict with others - wrongSpec_enq_conflict.wset(?); - wrongSpec_canon_conflict.wset(?); - wrongSpec_deq_conflict.wset(?); + wrongSpec_enq_conflict.send; + wrongSpec_canon_conflict.send; + wrongSpec_deq_conflict.send; endmethod endinterface endmodule