@@ -244,6 +244,8 @@ class StoreQueue(implicit p: Parameters) extends XSModule
244
244
// val vec_lastuop = Reg(Vec(StoreQueueSize, Bool())) // last uop of vector store instruction
245
245
val vecMbCommit = RegInit (VecInit (List .fill(StoreQueueSize )(false .B ))) // vector store committed from merge buffer to rob
246
246
val vecDataValid = RegInit (VecInit (List .fill(StoreQueueSize )(false .B ))) // vector store need write to sbuffer
247
+ val hasException = RegInit (VecInit (List .fill(StoreQueueSize )(false .B ))) // store has exception, should deq but not write sbuffer
248
+ val waitStoreS2 = RegInit (VecInit (List .fill(StoreQueueSize )(false .B ))) // wait for mmio and exception result until store_s2
247
249
// val vec_robCommit = Reg(Vec(StoreQueueSize, Bool())) // vector store committed by rob
248
250
// val vec_secondInv = RegInit(VecInit(List.fill(StoreQueueSize)(false.B))) // Vector unit-stride, second entry is invalid
249
251
@@ -265,15 +267,9 @@ class StoreQueue(implicit p: Parameters) extends XSModule
265
267
val deqMask = UIntToMask (deqPtr, StoreQueueSize )
266
268
val enqMask = UIntToMask (enqPtr, StoreQueueSize )
267
269
268
- // TODO: count commit numbers for scalar / vector store separately
269
- val scalarCommitCount = RegInit (0 .U (log2Ceil(StoreQueueSize + 1 ).W ))
270
- val scalarCommitted = WireInit (0 .U (log2Ceil(CommitWidth + 1 ).W ))
271
- val vecCommitted = WireInit (0 .U (log2Ceil(CommitWidth + 1 ).W ))
272
270
val commitCount = WireInit (0 .U (log2Ceil(CommitWidth + 1 ).W ))
273
271
val scommit = GatedRegNext (io.rob.scommit)
274
272
275
- scalarCommitCount := scalarCommitCount + scommit - scalarCommitted
276
-
277
273
// store can be committed by ROB
278
274
io.rob.mmio := DontCare
279
275
io.rob.uop := DontCare
@@ -348,6 +344,8 @@ class StoreQueue(implicit p: Parameters) extends XSModule
348
344
isVec((index + j.U ).value) := enqInstr.isVecStore // check vector store by the encoding of inst
349
345
vecMbCommit((index + j.U ).value) := false .B
350
346
vecDataValid((index + j.U ).value) := false .B
347
+ hasException((index + j.U ).value) := false .B
348
+ waitStoreS2((index + j.U ).value) := true .B
351
349
XSError (! io.enq.canAccept || ! io.enq.lqCanAccept, s " must accept $i\n " )
352
350
XSError (index.value =/= sqIdx.value, s " must be the same entry $i\n " )
353
351
}
@@ -484,6 +482,8 @@ class StoreQueue(implicit p: Parameters) extends XSModule
484
482
pending(stWbIndexReg) := io.storeAddrInRe(i).mmio
485
483
mmio(stWbIndexReg) := io.storeAddrInRe(i).mmio
486
484
atomic(stWbIndexReg) := io.storeAddrInRe(i).atomic
485
+ hasException(stWbIndexReg) := ExceptionNO .selectByFu(uop(stWbIndexReg).exceptionVec, StaCfg ).asUInt.orR || io.storeAddrInRe(i).af
486
+ waitStoreS2(stWbIndexReg) := false .B
487
487
}
488
488
// dcache miss info (one cycle later than storeIn)
489
489
// if dcache report a miss in sta pipeline, this store will trigger a prefetch when committing to sbuffer (if EnableAtCommitMissTrigger)
@@ -851,39 +851,30 @@ class StoreQueue(implicit p: Parameters) extends XSModule
851
851
XSError (uncacheState =/= s_idle && uncacheState =/= s_wait && commitCount > 0 .U ,
852
852
" should not commit instruction when MMIO has not been finished\n " )
853
853
854
- val scalarcommitVec = WireInit (VecInit (Seq .fill(CommitWidth )(false .B )))
855
- val veccommitVec = WireInit (VecInit (Seq .fill(CommitWidth )(false .B )))
854
+ val commitVec = WireInit (VecInit (Seq .fill(CommitWidth )(false .B )))
855
+ val needCancel = Wire (Vec (StoreQueueSize , Bool ())) // Will be assigned later
856
+ dontTouch(commitVec)
856
857
// TODO: Deal with vector store mmio
857
858
for (i <- 0 until CommitWidth ) {
858
- val veccount = PopCount (veccommitVec.take(i))
859
- when (allocated(cmtPtrExt(i).value) && isVec(cmtPtrExt(i).value) && isNotAfter(uop(cmtPtrExt(i).value).robIdx, RegNext (io.rob.pendingPtr)) && vecMbCommit(cmtPtrExt(i).value)) {
859
+ when (allocated(cmtPtrExt(i).value) && isNotAfter(uop(cmtPtrExt(i).value).robIdx, RegNext (io.rob.pendingPtr)) && ! needCancel(cmtPtrExt(i).value) && ! waitStoreS2(cmtPtrExt(i).value)) {
860
860
if (i == 0 ){
861
861
// TODO: fixme for vector mmio
862
862
when ((uncacheState === s_idle) || (uncacheState === s_wait && scommit > 0 .U )){
863
- committed(cmtPtrExt(0 ).value) := true .B
864
- veccommitVec(i) := true .B
863
+ when ((isVec(cmtPtrExt(i).value) && vecMbCommit(cmtPtrExt(i).value)) || ! isVec(cmtPtrExt(i).value)) {
864
+ committed(cmtPtrExt(0 ).value) := true .B
865
+ commitVec(0 ) := true .B
866
+ }
865
867
}
866
868
} else {
867
- committed(cmtPtrExt(i).value) := true .B
868
- veccommitVec(i) := veccommitVec(i - 1 ) || scalarcommitVec(i - 1 )
869
- }
870
- } .elsewhen (scalarCommitCount > i.U - veccount) {
871
- if (i == 0 ){
872
- when ((uncacheState === s_idle) || (uncacheState === s_wait && scommit > 0 .U )){
873
- committed(cmtPtrExt(0 ).value) := true .B
874
- scalarcommitVec(i) := true .B
869
+ when ((isVec(cmtPtrExt(i).value) && vecMbCommit(cmtPtrExt(i).value)) || ! isVec(cmtPtrExt(i).value)) {
870
+ committed(cmtPtrExt(i).value) := true .B
871
+ commitVec(i) := commitVec(i - 1 )
875
872
}
876
- } else {
877
- committed(cmtPtrExt(i).value) := true .B
878
- scalarcommitVec(i) := veccommitVec(i - 1 ) || scalarcommitVec(i - 1 )
879
873
}
880
874
}
881
875
}
882
876
883
- scalarCommitted := PopCount (scalarcommitVec)
884
- vecCommitted := PopCount (veccommitVec)
885
- commitCount := scalarCommitted + vecCommitted
886
-
877
+ commitCount := PopCount (commitVec)
887
878
cmtPtrExt := cmtPtrExt.map(_ + commitCount)
888
879
889
880
// committed stores will not be cancelled and can be sent to lower level.
@@ -892,10 +883,10 @@ class StoreQueue(implicit p: Parameters) extends XSModule
892
883
// Read data from data module
893
884
// As store queue grows larger and larger, time needed to read data from data
894
885
// module keeps growing higher. Now we give data read a whole cycle.
895
- val mmioStall = mmio(rdataPtrExt(0 ).value)
896
886
for (i <- 0 until EnsbufferWidth ) {
897
887
val ptr = rdataPtrExt(i).value
898
- dataBuffer.io.enq(i).valid := allocated(ptr) && committed(ptr) && (! isVec(ptr) || vecMbCommit(ptr)) && ! mmioStall
888
+ val mmioStall = if (i == 0 ) mmio(rdataPtrExt(0 ).value) else (mmio(rdataPtrExt(i).value) || mmio(rdataPtrExt(i- 1 ).value))
889
+ dataBuffer.io.enq(i).valid := allocated(ptr) && committed(ptr) && ((! isVec(ptr) && allvalid(ptr)) || vecMbCommit(ptr)) && ! mmioStall
899
890
// Note that store data/addr should both be valid after store's commit
900
891
assert(! dataBuffer.io.enq(i).valid || allvalid(ptr) || (allocated(ptr) && vecMbCommit(ptr)))
901
892
dataBuffer.io.enq(i).bits.addr := paddrModule.io.rdata(i)
@@ -905,7 +896,8 @@ class StoreQueue(implicit p: Parameters) extends XSModule
905
896
dataBuffer.io.enq(i).bits.wline := paddrModule.io.rlineflag(i)
906
897
dataBuffer.io.enq(i).bits.sqPtr := rdataPtrExt(i)
907
898
dataBuffer.io.enq(i).bits.prefetch := prefetch(ptr)
908
- dataBuffer.io.enq(i).bits.vecValid := ! isVec(ptr) || vecDataValid(ptr) // scalar is always valid
899
+ // when scalar has exception, will also not write into sbuffer
900
+ dataBuffer.io.enq(i).bits.vecValid := (! isVec(ptr) || vecDataValid(ptr)) && ! hasException(ptr)
909
901
}
910
902
911
903
// Send data stored in sbufferReqBitsReg to sbuffer
@@ -944,6 +936,7 @@ class StoreQueue(implicit p: Parameters) extends XSModule
944
936
if (env.EnableDifftest ) {
945
937
for (i <- 0 until EnsbufferWidth ) {
946
938
val ptr = rdataPtrExt(i).value
939
+ val mmioStall = if (i == 0 ) mmio(rdataPtrExt(0 ).value) else (mmio(rdataPtrExt(i).value) || mmio(rdataPtrExt(i- 1 ).value))
947
940
difftestBuffer.get.io.enq(i).valid := allocated(ptr) && committed(ptr) && (! isVec(ptr) || vecMbCommit(ptr)) && ! mmioStall
948
941
difftestBuffer.get.io.enq(i).bits := uop(ptr)
949
942
}
@@ -993,7 +986,6 @@ class StoreQueue(implicit p: Parameters) extends XSModule
993
986
994
987
// misprediction recovery / exception redirect
995
988
// invalidate sq term using robIdx
996
- val needCancel = Wire (Vec (StoreQueueSize , Bool ()))
997
989
for (i <- 0 until StoreQueueSize ) {
998
990
needCancel(i) := uop(i).robIdx.needFlush(io.brqRedirect) && allocated(i) && ! committed(i)
999
991
when (needCancel(i)) {
0 commit comments