[rvvi] Handle vd conflicts for vector tracing - Multiple vector instructions can be dispatched concurrently with the same destination register. Update our retirement logic to only consume one write to a given register, per cycle. Change-Id: I1acf2ac2db19d3d048f295ac754d9ffc23cbd075
diff --git a/hdl/chisel/src/kelvin/RetirementBuffer.scala b/hdl/chisel/src/kelvin/RetirementBuffer.scala index 851e7f7..f776b7b 100644 --- a/hdl/chisel/src/kelvin/RetirementBuffer.scala +++ b/hdl/chisel/src/kelvin/RetirementBuffer.scala
@@ -114,12 +114,15 @@ // The entry is active if it's validly enqueued and not already complete. val validBufferEntry = (i.U < instBuffer.io.nEnqueued) && (!resultBuffer(i).valid) - // If the entry is active and its data dependency is met (or it has no dependency)... - val updated = (validBufferEntry && (scalarWriteIdxMap.reduce(_|_) || floatWriteIdxMap.reduce(_|_) || vectorWriteIdxMap.reduce(_|_) || nonWritingInstr)) // Find the index of the first write port that provides the needed data. val scalarWriteIdx = PriorityEncoder(scalarWriteIdxMap) val floatWriteIdx = PriorityEncoder(floatWriteIdxMap) val vectorWriteIdx = PriorityEncoder(vectorWriteIdxMap) + + // If the entry is active and its data dependency is met (or it has no dependency)... + // Special care here for vector, as multiple instructions are allowed to be dispatched for the same destination register. + // This differs from how the scalar/float scoreboards restrict dispatch. + val updated = (validBufferEntry && (scalarWriteIdxMap.reduce(_|_) || floatWriteIdxMap.reduce(_|_) || (vectorWriteIdxMap.reduce(_|_) && vectorWriteIdx === i.U) || nonWritingInstr)) // Select the actual data from the winning write port. val writeDataScalar = io.writeDataScalar(scalarWriteIdx).bits.data val writeDataFloat = io.writeDataFloat.map(x => x(floatWriteIdx).bits.data).getOrElse(0.U)