提交 6db214fc 编写于 作者: Y Yinan Xu

backend,dispatch: add dispatch2

上级 3e254c8b
......@@ -3,7 +3,6 @@ package xiangshan.backend.dispatch
import chisel3._
import chisel3.util._
import xiangshan._
import xiangshan.backend.regfile.RfReadPort
import utils.{GTimer, PipelineConnect}
case class DP1Config
......@@ -97,76 +96,76 @@ class Dispatch1 extends XSModule{
}
}
class Dispatch1Debug extends XSModule {
val io = IO(new Bundle() {
val redirect = Flipped(ValidIO(new Redirect))
// from rename
val fromRename = Vec(RenameWidth, Flipped(DecoupledIO(new MicroOp)))
// enq Roq
val toRoq = Vec(RenameWidth, DecoupledIO(new MicroOp))
// get RoqIdx
val roqIdxs = Input(Vec(RenameWidth, UInt(RoqIdxWidth.W)))
val fromIntDq = Vec(IntDqDeqWidth, DecoupledIO(UInt(46.W)))
val fromFpDq = Vec(FpDqDeqWidth, DecoupledIO(UInt(46.W)))
val fromLsDq = Vec(LsDqDeqWidth, DecoupledIO(UInt(46.W)))
// read regfile
// val readIntRf = Vec(NRReadPorts, Flipped(new RfReadPort))
// val readFpRf = Vec(NRReadPorts, Flipped(new RfReadPort))
// ro reservation stations
// val enqIQCtrl = Vec(exuConfig.ExuCnt, DecoupledIO(new MicroOp))
// val enqIQData = Vec(exuConfig.ExuCnt, ValidIO(new ExuInput))
})
// pipeline between rename and dispatch
val dispatch1 = Module(new Dispatch1())
for (i <- 0 until RenameWidth) {
// dispatch1.io.fromRename(i) <> Queue(io.fromRename(i))
PipelineConnect(io.fromRename(i), dispatch1.io.fromRename(i), dispatch1.io.recv(i), false.B)
}
// dispatch1.io.fromRename <> DontCare
// io.fromRename.foreach( x => x.ready <> DontCare)
val intDq = Module(new DispatchQueue(new MicroOp, dp1Config.IntDqSize, RenameWidth, IntDqDeqWidth))
val fpDq = Module(new DispatchQueue(new MicroOp, dp1Config.FpDqSize, RenameWidth, FpDqDeqWidth))
val lsDq = Module(new DispatchQueue(new MicroOp, dp1Config.LsDqSize, RenameWidth, LsDqDeqWidth))
// val dispatch2 = new Dispatch2()
dispatch1.io.redirect <> io.redirect
dispatch1.io.toRoq <> io.toRoq
dispatch1.io.roqIdxs <> io.roqIdxs
dispatch1.io.toIntDq <> intDq.io.enq
dispatch1.io.toFpDq <> fpDq.io.enq
dispatch1.io.toLsDq <> lsDq.io.enq
for (i <- 0 until IntDqDeqWidth) {
intDq.io.deq(i).ready := io.fromIntDq(i).ready
io.fromIntDq(i).valid := intDq.io.deq(i).valid
io.fromIntDq(i).bits := Cat(intDq.io.deq(i).bits.roqIdx, intDq.io.deq(i).bits.cf.pc)
when (io.fromIntDq(i).fire()) {
printf("[Dispatch1:%d]: instruction 0x%x leaves Int dispatch queue with nroq %d\n",
GTimer(), io.fromIntDq(i).bits(38, 0), io.fromIntDq(i).bits(45, 39))
}
}
for (i <- 0 until FpDqDeqWidth) {
fpDq.io.deq(i).ready := io.fromFpDq(i).ready
io.fromFpDq(i).valid := fpDq.io.deq(i).valid
io.fromFpDq(i).bits := Cat(fpDq.io.deq(i).bits.roqIdx, fpDq.io.deq(i).bits.cf.pc)
when (io.fromFpDq(i).fire()) {
printf("[Dispatch1:%d]: instruction 0x%x leaves FP dispatch queue with nroq %d\n",
GTimer(), io.fromFpDq(i).bits(38, 0), io.fromIntDq(i).bits(45, 39))
}
}
for (i <- 0 until LsDqDeqWidth) {
lsDq.io.deq(i).ready := io.fromLsDq(i).ready
io.fromLsDq(i).valid := lsDq.io.deq(i).valid
io.fromLsDq(i).bits := Cat(lsDq.io.deq(i).bits.roqIdx, lsDq.io.deq(i).bits.cf.pc)
when (io.fromLsDq(i).fire()) {
printf("[Dispatch1:%d]: instruction 0x%x leaves LS dispatch queue with nroq %d\n",
GTimer(), io.fromLsDq(i).bits(38, 0), io.fromIntDq(i).bits(45, 39))
}
}
}
object Dispatch1Top extends App {
Driver.execute(args, () => new Dispatch1Debug())
}
\ No newline at end of file
//class Dispatch1Debug extends XSModule {
// val io = IO(new Bundle() {
// val redirect = Flipped(ValidIO(new Redirect))
// // from rename
// val fromRename = Vec(RenameWidth, Flipped(DecoupledIO(new MicroOp)))
// // enq Roq
// val toRoq = Vec(RenameWidth, DecoupledIO(new MicroOp))
// // get RoqIdx
// val roqIdxs = Input(Vec(RenameWidth, UInt(RoqIdxWidth.W)))
// val fromIntDq = Vec(IntDqDeqWidth, DecoupledIO(UInt(46.W)))
// val fromFpDq = Vec(FpDqDeqWidth, DecoupledIO(UInt(46.W)))
// val fromLsDq = Vec(LsDqDeqWidth, DecoupledIO(UInt(46.W)))
// // read regfile
// // val readIntRf = Vec(NRReadPorts, Flipped(new RfReadPort))
// // val readFpRf = Vec(NRReadPorts, Flipped(new RfReadPort))
// // ro reservation stations
// // val enqIQCtrl = Vec(exuConfig.ExuCnt, DecoupledIO(new MicroOp))
// // val enqIQData = Vec(exuConfig.ExuCnt, ValidIO(new ExuInput))
// })
// // pipeline between rename and dispatch
// val dispatch1 = Module(new Dispatch1())
// for (i <- 0 until RenameWidth) {
//// dispatch1.io.fromRename(i) <> Queue(io.fromRename(i))
// PipelineConnect(io.fromRename(i), dispatch1.io.fromRename(i), dispatch1.io.recv(i), false.B)
// }
//
//// dispatch1.io.fromRename <> DontCare
//// io.fromRename.foreach( x => x.ready <> DontCare)
//
// val intDq = Module(new DispatchQueue(new MicroOp, dp1Config.IntDqSize, RenameWidth, IntDqDeqWidth))
// val fpDq = Module(new DispatchQueue(new MicroOp, dp1Config.FpDqSize, RenameWidth, FpDqDeqWidth))
// val lsDq = Module(new DispatchQueue(new MicroOp, dp1Config.LsDqSize, RenameWidth, LsDqDeqWidth))
//// val dispatch2 = new Dispatch2()
//
// dispatch1.io.redirect <> io.redirect
// dispatch1.io.toRoq <> io.toRoq
// dispatch1.io.roqIdxs <> io.roqIdxs
// dispatch1.io.toIntDq <> intDq.io.enq
// dispatch1.io.toFpDq <> fpDq.io.enq
// dispatch1.io.toLsDq <> lsDq.io.enq
//
// for (i <- 0 until IntDqDeqWidth) {
// intDq.io.deq(i).ready := io.fromIntDq(i).ready
// io.fromIntDq(i).valid := intDq.io.deq(i).valid
// io.fromIntDq(i).bits := Cat(intDq.io.deq(i).bits.roqIdx, intDq.io.deq(i).bits.cf.pc)
// when (io.fromIntDq(i).fire()) {
// printf("[Dispatch1:%d]: instruction 0x%x leaves Int dispatch queue with nroq %d\n",
// GTimer(), io.fromIntDq(i).bits(38, 0), io.fromIntDq(i).bits(45, 39))
// }
// }
// for (i <- 0 until FpDqDeqWidth) {
// fpDq.io.deq(i).ready := io.fromFpDq(i).ready
// io.fromFpDq(i).valid := fpDq.io.deq(i).valid
// io.fromFpDq(i).bits := Cat(fpDq.io.deq(i).bits.roqIdx, fpDq.io.deq(i).bits.cf.pc)
// when (io.fromFpDq(i).fire()) {
// printf("[Dispatch1:%d]: instruction 0x%x leaves FP dispatch queue with nroq %d\n",
// GTimer(), io.fromFpDq(i).bits(38, 0), io.fromIntDq(i).bits(45, 39))
// }
// }
// for (i <- 0 until LsDqDeqWidth) {
// lsDq.io.deq(i).ready := io.fromLsDq(i).ready
// io.fromLsDq(i).valid := lsDq.io.deq(i).valid
// io.fromLsDq(i).bits := Cat(lsDq.io.deq(i).bits.roqIdx, lsDq.io.deq(i).bits.cf.pc)
// when (io.fromLsDq(i).fire()) {
// printf("[Dispatch1:%d]: instruction 0x%x leaves LS dispatch queue with nroq %d\n",
// GTimer(), io.fromLsDq(i).bits(38, 0), io.fromIntDq(i).bits(45, 39))
// }
// }
//}
//
//object Dispatch1Top extends App {
// Driver.execute(args, () => new Dispatch1Debug ())
//}
......@@ -21,4 +21,130 @@ class Dispatch2 extends XSModule with NeedImpl {
val enqIQCtrl = Vec(exuConfig.ExuCnt, DecoupledIO(new MicroOp))
val enqIQData = Vec(exuConfig.ExuCnt, ValidIO(new ExuInput))
})
// disp
// inst indexes for reservation stations
// append a true.B to avoid PriorityEncode(0000) -> 3
// if find a target uop, index[2] == 0, else index[2] == 1
val bruInstIdx = PriorityEncoder(true.B +: io.fromIntDq.map(_.bits.ctrl.fuType === FuType.bru))
val alu0InstIdx = PriorityEncoder(true.B +: io.fromIntDq.map(_.bits.ctrl.fuType === FuType.alu))
val alu1InstIdx = PriorityEncoder(true.B +: (io.fromIntDq.zipWithIndex map { case (uop, i) =>
uop.bits.ctrl.fuType === FuType.alu && i.U > alu0InstIdx
}))
val alu2InstIdx = PriorityEncoder(true.B +: (io.fromIntDq.zipWithIndex map { case (uop, i) =>
uop.bits.ctrl.fuType === FuType.alu && i.U > alu1InstIdx
}))
val alu3InstIdx = PriorityEncoder(true.B +: (io.fromIntDq.zipWithIndex map { case (uop, i) =>
uop.bits.ctrl.fuType === FuType.alu && i.U > alu2InstIdx
}))
val mulInstIdx = PriorityEncoder(true.B +: (io.fromIntDq.map(_.bits.ctrl.fuType === FuType.mul)))
val muldivInstIdx = PriorityEncoder(true.B +: (io.fromIntDq.zipWithIndex map { case (uop, i) =>
(uop.bits.ctrl.fuType === FuType.mul && i.U > mulInstIdx) || uop.bits.ctrl.fuType === FuType.mdu
}))
val fmac0InstIdx = PriorityEncoder(true.B +: io.fromFpDq.map(_.bits.ctrl.fuType === FuType.fmac))
val fmac1InstIdx = PriorityEncoder(true.B +: (io.fromFpDq.zipWithIndex map { case (uop, i) =>
uop.bits.ctrl.fuType === FuType.fmac && i.U > fmac0InstIdx
}))
val fmac2InstIdx = PriorityEncoder(true.B +: (io.fromFpDq.zipWithIndex map { case (uop, i) =>
uop.bits.ctrl.fuType === FuType.fmac && i.U > fmac1InstIdx
}))
val fmac3InstIdx = PriorityEncoder(true.B +: (io.fromFpDq.zipWithIndex map { case (uop, i) =>
uop.bits.ctrl.fuType === FuType.fmac && i.U > fmac2InstIdx
}))
val fmisc0InstIdx = PriorityEncoder(true.B +: io.fromFpDq.map(_.bits.ctrl.fuType === FuType.fmisc))
val fmisc1InstIdx = PriorityEncoder(true.B +: (io.fromFpDq.zipWithIndex map { case (uop, i) =>
(uop.bits.ctrl.fuType === FuType.fmisc && i.U > fmisc0InstIdx) || uop.bits.ctrl.fuType === FuType.fmiscDivSqrt
}))
val load0InstIdx = PriorityEncoder(io.fromLsDq.map(_.bits.ctrl.fuType === FuType.ldu))
val load1InstIdx = PriorityEncoder(io.fromLsDq.zipWithIndex map { case (uop, i) =>
uop.bits.ctrl.fuType === FuType.ldu && i.U > load0InstIdx
})
val store0InstIdx = PriorityEncoder(io.fromLsDq.map(_.bits.ctrl.fuType === FuType.stu))
val store1InstIdx = PriorityEncoder(io.fromLsDq.zipWithIndex map { case (uop, i) =>
uop.bits.ctrl.fuType === FuType.stu && i.U > store0InstIdx
})
// regfile read ports
// regfile is sync-read, data can used at the next cycle
for (i <- 0 until IntDqDeqWidth) {
io.readIntRf(2 * i).addr := io.fromIntDq(i).bits.psrc1
io.readIntRf(2 * i + 1).addr := io.fromIntDq(i).bits.psrc2
}
for (i <- 0 until FpDqDeqWidth) {
io.readFpRf(3 * i).addr := io.fromFpDq(i).bits.psrc1
io.readFpRf(3 * i + 1).addr := io.fromFpDq(i).bits.psrc2
io.readFpRf(3 * i + 2).addr := io.fromFpDq(i).bits.psrc3
}
io.readIntRf(2*IntDqDeqWidth).addr := io.fromLsDq(load0InstIdx).bits.psrc1
io.readIntRf(2*IntDqDeqWidth + 1).addr := io.fromLsDq(load1InstIdx).bits.psrc1
io.readIntRf(2*IntDqDeqWidth + 2).addr := io.fromLsDq(store0InstIdx).bits.psrc1
io.readIntRf(2*IntDqDeqWidth + 3).addr := io.fromLsDq(store0InstIdx).bits.psrc2
io.readIntRf(2*IntDqDeqWidth + 4).addr := io.fromLsDq(store1InstIdx).bits.psrc1
io.readIntRf(2*IntDqDeqWidth + 5).addr := io.fromLsDq(store1InstIdx).bits.psrc2
io.readFpRf(3*FpDqDeqWidth).addr := io.fromLsDq(store0InstIdx).bits.psrc1
io.readFpRf(3*FpDqDeqWidth + 1).addr := io.fromLsDq(store1InstIdx).bits.psrc1
// insert into reservation station
val instIdxes = Seq(bruInstIdx, alu0InstIdx, alu1InstIdx, alu2InstIdx, alu3InstIdx, mulInstIdx, muldivInstIdx,
fmac0InstIdx, fmac1InstIdx, fmac2InstIdx, fmac3InstIdx, fmisc0InstIdx, fmisc1InstIdx,
load0InstIdx, store0InstIdx)
io.enqIQCtrl.zipWithIndex map { case (enq, i) =>
if (i < exuConfig.IntExuCnt) {
enq.valid := !instIdxes(i)(2) && io.fromIntDq(instIdxes(i)(1, 0)).valid
enq.bits := io.fromIntDq(instIdxes(i)(1, 0)).bits
}
else if (i < exuConfig.IntExuCnt + exuConfig.FpExuCnt) {
enq.valid := !instIdxes(i)(2) && io.fromFpDq(instIdxes(i)(1, 0)).valid
enq.bits := io.fromFpDq(instIdxes(i)(1, 0)).bits
}
else {
enq.valid := !instIdxes(i)(2) && io.fromLsDq(instIdxes(i)(1, 0)).valid
enq.bits := io.fromLsDq(instIdxes(i)(1, 0)).bits
}
}
// responds to dispatch queue
val portIndexMapping
for (i <- 0 until IntDqDeqWidth) {
io.fromIntDq(i).ready := (io.enqIQCtrl.zipWithIndex map {case (rs, j) =>
(rs.ready && instIdxes(j) === i.U && (i < exuConfig.IntExuCnt).asBool())
}).reduce((l, r) => l || r)
}
for (i <- 0 until FpDqDeqWidth) {
io.fromFpDq(i).ready := (io.enqIQCtrl.zipWithIndex map {case (rs, j) =>
(rs.ready && instIdxes(j) === i.U
&& (i > exuConfig.IntExuCnt && i < exuConfig.IntExuCnt + exuConfig.FpExuCnt).asBool())
}).reduce((l, r) => l || r)
}
for (i <- 0 until LsDqDeqWidth) {
io.fromLsDq(i).ready := (io.enqIQCtrl.zipWithIndex map {case (rs, j) =>
(rs.ready && instIdxes(j) === i.U
&& (i > exuConfig.IntExuCnt + exuConfig.FpExuCnt).asBool())
}).reduce((l, r) => l || r)
}
// next stage: insert data
val data_valid = Reg(Vec(exuConfig.ExuCnt, Bool()))
val uop_reg = Reg(Vec(exuConfig.ExuCnt, new MicroOp))
// indexes can be one-hot to reduce overhead
val index_reg = Reg(Vec(exuConfig.ExuCnt, UInt(instIdxes(0).getWidth.W)))
for (i <- 0 until exuConfig.ExuCnt) {
data_valid(i) := io.enqIQCtrl(i).fire()
uop_reg := io.enqIQCtrl(i).bits
index_reg(i) := instIdxes(i)
io.enqIQData(i).valid := data_valid(i)
io.enqIQData(i).bits.uop := uop_reg(i)
val intSrc1 = io.readIntRf((index_reg(i) << 1).asUInt()).data
val fpSrc1 = io.readFpRf((index_reg(i) * 3.U).asUInt()).data
io.enqIQData(i).bits.src1 := Mux(index_reg(i)(2), 0.U, if (i < exuConfig.IntExuCnt) intSrc1
else if (i < exuConfig.IntExuCnt + exuConfig.FpExuCnt)
io.enqIQData(i).bits.src2 :=
io.enqIQData(i).bits.src3 :=
io.enqIQData(i).bits.isRVF =
}
}
......@@ -16,6 +16,7 @@ class DispatchQueue[T <: Data](gen: T, size: Int, enqnum: Int, deqnum: Int) exte
// queue data array
val entries = Reg(Vec(size, gen))
val entriesValid = Reg(Vec(size, Bool()))
val head = RegInit(0.U(index_width.W))
val tail = RegInit(0.U(index_width.W))
val enq_index = Wire(Vec(enqnum, UInt(index_width.W)))
......@@ -32,10 +33,16 @@ class DispatchQueue[T <: Data](gen: T, size: Int, enqnum: Int, deqnum: Int) exte
enq_index(i) := (tail + enq_count(i) - 1.U) % size.U
when (io.enq(i).fire()) {
entries(enq_index(i)) := io.enq(i).bits
entriesValid(enq_index(i)) := true.B
}
}
(0 until deqnum).map(i => deq_index(i) := ((head + i.U) % size.U).asUInt())
for (i <- 0 until deqnum) {
deq_index(i) := ((head + i.U) % size.U).asUInt()
when (io.deq(i).fire()) {
entriesValid(deq_index(i)) := false.B
}
}
// enqueue
val num_enq_try = enq_count(enqnum - 1)
......@@ -46,13 +53,15 @@ class DispatchQueue[T <: Data](gen: T, size: Int, enqnum: Int, deqnum: Int) exte
// dequeue
val num_deq_try = Mux(valid_entries > deqnum.U, deqnum.U, valid_entries)
val num_deq = PopCount(io.deq.map(_.fire()))
val num_deq = PriorityEncoder(true.B +: (io.deq.zipWithIndex map { case (deq, i) =>
!deq.fire() && entriesValid(deq_index(i))
}))
(0 until deqnum).map(i => io.deq(i).bits := entries(deq_index(i)))
(0 until deqnum).map(i => io.deq(i).valid := i.U < num_deq_try)
(0 until deqnum).map(i => io.deq(i).valid := (i.U < num_deq_try) && entriesValid(deq_index(i)))
head := (head + num_deq) % size.U
head_direction := ((Cat(0.U(1.W), head) + num_deq) >= size.U).asUInt() ^ head_direction
}
object DispatchQueueTop extends App {
Driver.execute(args, () => new DispatchQueue(UInt(32.W), 16, 6, 4))
}
\ No newline at end of file
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册