Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions src/src/pipeline/dispatch/NewDispatchStage.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import pipeline.dispatch.bundles.ReservationStationBundle
import pipeline.dispatch.rs.InOrderReservationStation
import control.enums.ExceptionPos
import pipeline.dispatch.rs.OutOfOrderReservationStation
import pipeline.dispatch.rs.SimpleOoOReservationStation

// class DispatchNdPort extends Bundle {
// val issueEns = Vec(Param.pipelineNum, Bool())
Expand Down Expand Up @@ -57,11 +58,7 @@ class NewDispatchStage(
val reservationStations = Seq.fill(pipelineNum)(
Module(
if (Param.isOutOfOrderIssue)
new OutOfOrderReservationStation(
Param.Width.Rob._channelLength,
1,
1,
1,
new SimpleOoOReservationStation(
Param.Width.Rob._channelLength,
true
)
Expand Down
18 changes: 1 addition & 17 deletions src/src/pipeline/dispatch/bundles/PreExeInstNdPort.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,5 @@ class PreExeInstNdPort(readNum: Int = Param.instRegReadNum) extends Bundle {
}

object PreExeInstNdPort {
def default = (new PreExeInstNdPort).Lit(
_.needCsr -> false.B,
_.exeSel -> ExeInst.Sel.none,
_.exeOp -> ExeInst.Op.nop,
_.gprReadPorts -> Vec.Lit(RfAccessInfoNdPort.default, RfAccessInfoNdPort.default),
_.gprWritePort -> RfAccessInfoNdPort.default,
_.isHasImm -> false.B,
_.imm -> 0.U,
_.jumpBranchAddr -> zeroWord,
_.csrReadEn -> false.B,
_.csrWriteEn -> false.B,
_.isTlb -> false.B,
_.issueEn -> Vec.Lit(Seq.fill(Param.pipelineNum)(false.B): _*),
_.isPrivilege -> false.B,
_.branchType -> 0.U,
_.isBranch -> false.B
)
def default = 0.U.asTypeOf(new PreExeInstNdPort)
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class OutOfOrderReservationStation(
channelLength
) {

require(supportCheckForIssue == true)

// Fallback
io.dequeuePorts.foreach(_ <> DontCare)
io.enqueuePorts.foreach(_.ready := false.B)
Expand Down Expand Up @@ -108,7 +110,7 @@ class OutOfOrderReservationStation(
// .contains(elem.bits.regReadPort.preExeInstInfo.exeSel
elem.bits.regReadPort.preExeInstInfo.forbidOutOfOrder
) {
if (idx >= enqMaxNum) {
if (idx >= deqMaxNum) {
en := false.B
} else {
when(!ramDownViewEnableDeq.take(idx).foldLeft(true.B)(_ && _)) {
Expand Down
177 changes: 177 additions & 0 deletions src/src/pipeline/dispatch/rs/SimpleOoOReservationStation.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
package pipeline.dispatch.rs

import chisel3._
import chisel3.util._
import pipeline.dispatch.bundles.ReservationStationBundle
import pipeline.rob.enums.RobDistributeSel
import utils.MultiCounter

class SimpleOoOReservationStation(
queueLength: Int,
supportCheckForIssue: Boolean = true)
extends BaseReservationStation(
queueLength,
1,
1,
1,
queueLength
) {

require(supportCheckForIssue == true)

// Fallback
io.dequeuePorts.foreach(_ <> DontCare)
io.enqueuePorts.foreach(_.ready := false.B)
io.dequeuePorts.foreach(_.valid := false.B)

require(queueLength > 1)
require(queueLength > 1)
require(isPow2(queueLength))

val ram = RegInit(VecInit(Seq.fill(queueLength)(0.U.asTypeOf(Valid(new ReservationStationBundle)))))

val enq_ptr = Module(new MultiCounter(queueLength, 1))
val deq_ptr = Module(new MultiCounter(queueLength, 1))

enq_ptr.io.inc := 0.U
enq_ptr.io.flush := io.isFlush
deq_ptr.io.inc := 0.U
deq_ptr.io.flush := io.isFlush

val maybeFull = RegInit(false.B)
val ptrMatch = enq_ptr.io.value === deq_ptr.io.value
val isEmpty = WireDefault(ptrMatch && !maybeFull)
val isFull = WireDefault(ptrMatch && maybeFull)

io.enqueuePorts.head.ready := !isFull

val enqEn = io.enqueuePorts.head.valid && io.enqueuePorts.head.ready
val enqueueNum = enqEn.asUInt

val deqEn = io.dequeuePorts.head.valid && io.dequeuePorts.head.ready
val dequeueNum = deqEn.asUInt

enq_ptr.io.inc := enqueueNum
deq_ptr.io.inc := dequeueNum

when(enqueueNum > dequeueNum) {
maybeFull := true.B
}.elsewhen(enqueueNum < dequeueNum) {
maybeFull := false.B
}

// dequeue
// invalidate which are dequeue
when(deqEn) {
ram(deq_ptr.io.value).valid := false.B
}

// select which can issue
val ramDownView = WireDefault(VecInit(Seq.range(0, queueLength).map { idx =>
ram(deq_ptr.io.incResults(idx))
}))

val ramDownViewEnableDeq = Wire(Vec(queueLength, Bool()))

ramDownViewEnableDeq.lazyZip(ramDownView).zipWithIndex.foreach {
case ((en, elem), idx) =>
en := elem.valid && elem.bits.robResult.readResults.forall(
_.sel === RobDistributeSel.realData
)
if (idx != 0) {
when(elem.bits.regReadPort.preExeInstInfo.forbidOutOfOrder) {
en := false.B
}
}
}

// // select dequeue num of elem to issue
val selectedDownViewIndex = PriorityEncoder(ramDownViewEnableDeq)

io.dequeuePorts.head.valid := ramDownViewEnableDeq(selectedDownViewIndex)
io.dequeuePorts.head.bits := ramDownView(selectedDownViewIndex).bits

// compress
// deq_ptr - out - enq_ptr
// for those between deq_ptr and out idx += 1
val compressResult = Wire(Vec(queueLength, Valid(new ReservationStationBundle)))

when(deqEn) {
compressResult.zip(ramDownView).foreach {
case (dst, src) =>
dst.valid := false.B
dst.bits := DontCare
}
ramDownView.zipWithIndex.foreach {
case (elem, src_idx) =>
when(src_idx.U === selectedDownViewIndex) {
// pass
}.elsewhen(src_idx.U < selectedDownViewIndex) {
// up one
if (src_idx != queueLength - 1) {
compressResult(src_idx + 1) := elem
}
}.otherwise {
compressResult(src_idx) := elem
}
}
}.otherwise {
compressResult.zip(ramDownView).foreach {
case (dst, src) =>
dst := src
}
}

// // write
compressResult.zipWithIndex.foreach {
case (src, idx) =>
ram(deq_ptr.io.incResults(idx)) := src

io.writebacks.foreach { wb =>
src.bits.regReadPort.preExeInstInfo.gprReadPorts
.lazyZip(src.bits.robResult.readResults)
.lazyZip(ram(deq_ptr.io.incResults(idx)).bits.robResult.readResults)
.foreach {
case (readPort, robReadResult, dst) =>
when(
wb.en && readPort.en &&
robReadResult.sel === RobDistributeSel.robId &&
wb.robId === robReadResult.result
) {
dst.sel := RobDistributeSel.realData
dst.result := wb.data
}
}
}
}

// enqueue
val in = io.enqueuePorts.head
when(enqEn) {
ram(enq_ptr.io.value).bits := in.bits
ram(enq_ptr.io.value).valid := true.B

io.writebacks.foreach { wb =>
in.bits.regReadPort.preExeInstInfo.gprReadPorts
.lazyZip(in.bits.robResult.readResults)
.lazyZip(ram(enq_ptr.io.value).bits.robResult.readResults)
.foreach {
case (readPort, robReadResult, dst) =>
when(
wb.en && readPort.en &&
robReadResult.sel === RobDistributeSel.robId &&
wb.robId === robReadResult.result
) {
dst.sel := RobDistributeSel.realData
dst.result := wb.data
}
}
}
}

when(io.isFlush) {
ram.foreach(_.valid := false.B)
maybeFull := false.B
}

}
5 changes: 1 addition & 4 deletions src/src/pipeline/queue/bundles/DecodeOutNdPort.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,5 @@ class DecodeOutNdPort extends Bundle {
}

object DecodeOutNdPort {
def default = (new DecodeOutNdPort).Lit(
_.isMatched -> false.B,
_.info -> PreExeInstNdPort.default
)
def default = 0.U.asTypeOf(new DecodeOutNdPort)
}