diff --git a/src/main/scala/vexiiriscv/execute/lsu/LsuL1Plugin.scala b/src/main/scala/vexiiriscv/execute/lsu/LsuL1Plugin.scala index 4c3901d5..e7e1b8f7 100644 --- a/src/main/scala/vexiiriscv/execute/lsu/LsuL1Plugin.scala +++ b/src/main/scala/vexiiriscv/execute/lsu/LsuL1Plugin.scala @@ -792,6 +792,9 @@ class LsuL1Plugin(val lane : ExecuteLaneService, val loadDataHazard = LOAD && (bankNotRead || writeToReadHazard) val storeHazard = (STORE || FLUSH) && (!bankWriteReservation.win || !reservation.win) + // A few explanation : Some things have to be accurate, while some other can be deflected / ignored, especially + // when is need some shared ressources. + // For instance, a load miss may not trigger a refill, a flush may hit but may not trigger a flush val hazardReg = RegNext(this(HAZARD) && lane.isFreezed()) init(False) HAZARD := hazardReg || loadDataHazard || refillHazard || storeHazard MISS := !HAZARD && !WAYS_HIT && !FLUSH diff --git a/src/main/scala/vexiiriscv/execute/lsu/LsuPlugin.scala b/src/main/scala/vexiiriscv/execute/lsu/LsuPlugin.scala index 1bb44d2b..1cfabc3c 100644 --- a/src/main/scala/vexiiriscv/execute/lsu/LsuPlugin.scala +++ b/src/main/scala/vexiiriscv/execute/lsu/LsuPlugin.scala @@ -233,8 +233,8 @@ class LsuPlugin(var layer : LaneLayer, val holdHart = new Area{ val wordPerLine = LsuL1.LINE_BYTES*8/XLEN - assert(storeBufferOps >= wordPerLine) - val waitIt = RegInit(False) clearWhen (slotsFree && ops.occupancy <= storeBufferOps - wordPerLine) + val threshold = Math.max(storeBufferOps - wordPerLine, storeBufferOps/2) + val waitIt = RegInit(False) clearWhen (slotsFree && ops.occupancy <= threshold) host[DispatchPlugin].haltDispatchWhen(waitIt) } @@ -305,8 +305,10 @@ class LsuPlugin(var layer : LaneLayer, } val wb = withStoreBuffer generate new Area { + val isHead = storeBuffer.pop.ptr === storeBuffer.ops.freePtr + val flush = storeBuffer.waitL1.valid && !isHead val port = ports.addRet(Stream(LsuL1Cmd())) - port.valid := storeBuffer.pop.valid && !storeBuffer.waitL1.valid + port.valid := storeBuffer.pop.valid && !storeBuffer.waitL1.valid && !flush port.address := storeBuffer.pop.op.address.resized port.size := storeBuffer.pop.op.size port.load := False @@ -315,7 +317,7 @@ class LsuPlugin(var layer : LaneLayer, port.fromFlush := False port.fromAccess := False port.fromStoreBuffer := True - storeBuffer.pop.ready := port.ready + storeBuffer.pop.ready := port.ready || flush } val arbiter = StreamArbiterFactory().noLock.lowerFirst.buildOn(ports)