Skip to content

Commit

Permalink
fix(StoreQueue): commitLastFlow should be true when the port 1 has no…
Browse files Browse the repository at this point in the history
… exception (#3704)

When an exception is thrown by vector store:

* If not the last flow triggers an exception, then pull up the
vecExceptionFlag and do not allow subsequent flows to actually
    * write to the sbuffer, but can exit the queue from the sq normally.

* If it is the last flow that triggered the exception, then there is no
need to pull up vecExceptionFlag.

The vecExceptionFlag affects the vecvalid signal passed into the
sbuffer, and only when vecvalid is high can data actually be written to
the sbuffer.

Based on the current ports of the sbuffer, we list the cases as shown in
the implementation:

* When only the first port is valid, we only need to see if the first
port is lastflow.

* When both ports are valid, we need to judge based on whether robidx is
equal or not:
* When equal, the first port is definitely not lastflow, so we only need
to judge whether the second port is lastflow.

* When unequal, the first port is definitely lastflow, so we need to
pull up vecCommitLastFlow when the second port
* doesn't trigger an exception, and we need to judge whether the second
port is lastflow when the second port triggers
           * an exception.
  • Loading branch information
huxuan0307 authored Oct 9, 2024
1 parent ea2894c commit 0861ab0
Showing 1 changed file with 8 additions and 2 deletions.
10 changes: 8 additions & 2 deletions src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1045,13 +1045,19 @@ class StoreQueue(implicit p: Parameters) extends XSModule
// If the last flow with an exception is the LastFlow of this instruction, the flag is not set.
// compare robidx to select the last flow
require(EnsbufferWidth == 2, "The vector store exception handle process only support EnsbufferWidth == 2 yet.")
val robidxEQ = uop(rdataPtrExt(0).value).robIdx === uop(rdataPtrExt(1).value).robIdx
val robidxEQ = dataBuffer.io.enq(0).valid && dataBuffer.io.enq(1).valid &&
uop(rdataPtrExt(0).value).robIdx === uop(rdataPtrExt(1).value).robIdx
val robidxNE = dataBuffer.io.enq(0).valid && dataBuffer.io.enq(1).valid && (
uop(rdataPtrExt(0).value).robIdx =/= uop(rdataPtrExt(1).value).robIdx
)
val onlyCommit0 = dataBuffer.io.enq(0).valid && !dataBuffer.io.enq(1).valid

val vecCommitLastFlow =
// robidx equal => check if 1 is last flow
robidxEQ && vecCommitHasExceptionLastFlow(1) ||
// robidx not equal => 0 must be the last flow, just check if 1 is last flow when 1 has exception
!robidxEQ && vecCommitHasExceptionValid(1) && vecCommitHasExceptionLastFlow(1)
robidxNE && (vecCommitHasExceptionValid(1) && vecCommitHasExceptionLastFlow(1) || !vecCommitHasExceptionValid(1)) ||
onlyCommit0 && vecCommitHasExceptionLastFlow(0)


val vecExceptionFlagCancel = (0 until EnsbufferWidth).map{ i =>
Expand Down

0 comments on commit 0861ab0

Please sign in to comment.