diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/MemExePipeline.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/MemExePipeline.bsv index 2869826..b625352 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/MemExePipeline.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/MemExePipeline.bsv @@ -1314,7 +1314,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline); // write reg file & set ROB as Executed & wake up rs if(lsqDeqSt.dst matches tagged Valid .dst) begin CapPipe dataUnpacked = fromMem(tuple2(resp.tag, pack(resp.data))); - dataUnpacked = setValidCap(dataUnpacked, False); // TODO no allowCapLoad around. Can a cap be loaded this way (e.g. AMOSWAP?) + dataUnpacked = setValidCap(dataUnpacked, lsqDeqSt.allowCapAmoLd && isValidCap(dataUnpacked)); inIfc.writeRegFile(dst.indx, dataUnpacked); inIfc.setRegReadyAggr_mem(dst.indx); `ifdef INCLUDE_TANDEM_VERIF @@ -1428,7 +1428,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline); // write reg file & wakeup rs (this wakeup is late but MMIO is rare) & set ROB as Executed if(lsqDeqSt.dst matches tagged Valid .dst) begin CapPipe dataUnpacked = fromMem(tuple2(resp.tag, pack(resp.data))); - dataUnpacked = setValidCap(dataUnpacked, False); // TODO no allowCapLoad around. Can a cap be loaded this way (e.g. AMOSWAP?) + dataUnpacked = setValidCap(dataUnpacked, lsqDeqSt.allowCapAmoLd && isValidCap(dataUnpacked)); inIfc.writeRegFile(dst.indx, dataUnpacked); inIfc.setRegReadyAggr_mem(dst.indx); `ifdef INCLUDE_TANDEM_VERIF diff --git a/src_Core/RISCY_OOO/procs/lib/Decode.bsv b/src_Core/RISCY_OOO/procs/lib/Decode.bsv index 4ff0195..f415631 100755 --- a/src_Core/RISCY_OOO/procs/lib/Decode.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Decode.bsv @@ -92,6 +92,13 @@ function Maybe#(MemInst) decodeMemInst(Instruction inst, Bool cap_mode); illegalInst = True; end + Bool capWidth = ((mem_func == St || mem_func == Amo) && funct3 == 3'b100) + || (opcode == opcMiscMem && funct3 == 3'b010); + + if (capWidth && amo_func != None && amo_func != Swap) begin + illegalInst = True; // Don't support atomic cap arithmetic + end + // unsignedLd // it doesn't matter if this is set to True for stores Bool unsignedLd = False; @@ -109,9 +116,6 @@ function Maybe#(MemInst) decodeMemInst(Instruction inst, Bool cap_mode); unsignedLd = True; end - Bool capWidth = (mem_func == St && funct3 == 3'b100) - || (opcode == opcMiscMem && funct3 == 3'b010); - // byteEn // TODO: Some combinations of operations and byteEn's are illegal. // They should be detected here. diff --git a/src_Core/RISCY_OOO/procs/lib/SplitLSQ.bsv b/src_Core/RISCY_OOO/procs/lib/SplitLSQ.bsv index ece0f03..24fa28c 100644 --- a/src_Core/RISCY_OOO/procs/lib/SplitLSQ.bsv +++ b/src_Core/RISCY_OOO/procs/lib/SplitLSQ.bsv @@ -338,7 +338,7 @@ typedef struct { Bool isMMIO; MemDataByteEn shiftedBE; MemTaggedData stData; - Bool allowCap; + Bool allowCapAmoLd; Maybe#(Trap) fault; } StQDeqEntry deriving (Bits, Eq, FShow); @@ -857,6 +857,7 @@ module mkSplitLSQ(SplitLSQ); Vector#(StQSize, Ehr#(2, MemDataByteEn)) st_shiftedBE <- replicateM(mkEhr(?)); Vector#(StQSize, Ehr#(1, MemTaggedData)) st_stData <- replicateM(mkEhr(?)); Vector#(StQSize, Ehr#(2, Maybe#(Trap))) st_fault <- replicateM(mkEhr(?)); + Vector#(StQSize, Ehr#(2, Bool)) st_allowCapAmoLd <- replicateM(mkEhr(?)); Vector#(StQSize, Ehr#(2, Bool)) st_computed <- replicateM(mkEhr(?)); Vector#(StQSize, Ehr#(2, Bool)) st_verified <- replicateM(mkEhr(?)); Vector#(StQSize, Ehr#(2, SpecBits)) st_specBits <- replicateM(mkEhr(?)); @@ -896,6 +897,10 @@ module mkSplitLSQ(SplitLSQ); let st_fault_deqSt = getVEhrPort(st_fault, 1); let st_fault_enq = getVEhrPort(st_fault, 1); // write + let st_allowCapAmoLd_updAddr = getVEhrPort(st_allowCapAmoLd, 0); // write + let st_allowCapAmoLd_deqSt = getVEhrPort(st_allowCapAmoLd, 1); + let st_allowCapAmoLd_enq = getVEhrPort(st_allowCapAmoLd, 1); // write + let st_computed_verify = getVEhrPort(st_computed, 0); let st_computed_updAddr = getVEhrPort(st_computed, 0); // write let st_computed_issue = getVEhrPort(st_computed, 1); @@ -1544,6 +1549,7 @@ module mkSplitLSQ(SplitLSQ); st_rel[st_enqP] <= mem_inst.rl; st_dst[st_enqP] <= dst; st_fault_enq[st_enqP] <= Invalid; + st_allowCapAmoLd_enq[st_enqP] <= False; st_computed_enq[st_enqP] <= False; st_verified_enq[st_enqP] <= False; st_specBits_enq[st_enqP] <= spec_bits; @@ -1635,6 +1641,7 @@ module mkSplitLSQ(SplitLSQ); // write fault, computed paddr, shift be. NOTE computed is // true only when no fault. st_fault_updAddr[tag] <= fault; + st_allowCapAmoLd_updAddr[tag] <= allowCap; st_computed_updAddr[tag] <= !isValid(fault); st_paddr_updAddr[tag] <= pa; st_isMMIO_updAddr[tag] <= mmio; @@ -2174,6 +2181,7 @@ module mkSplitLSQ(SplitLSQ); isMMIO: st_isMMIO_deqSt[deqP], shiftedBE: st_shiftedBE_deqSt[deqP], stData: st_stData_deqSt[deqP], + allowCapAmoLd: st_allowCapAmoLd_deqSt[deqP], fault: st_fault_deqSt[deqP] }; endmethod