Dispatch.scala 9.0 KB
Newer Older
L
Lemover 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/***************************************************************************************
* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
*
* XiangShan is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*          http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the Mulan PSL v2 for more details.
***************************************************************************************/

16 17
package xiangshan.backend.dispatch

18
import chipsalliance.rocketchip.config.Parameters
19 20 21
import chisel3._
import chisel3.util._
import xiangshan._
L
LinJiawei 已提交
22
import utils._
23
import xiangshan.backend.regfile.RfReadPort
Y
Yinan Xu 已提交
24
import xiangshan.backend.roq.{RoqPtr, RoqEnqIO}
Y
Yinan Xu 已提交
25
import xiangshan.backend.rename.{RenameBypassInfo, BusyTableReadIO}
Y
Yinan Xu 已提交
26
import xiangshan.mem.LsqEnqIO
27

28 29 30 31 32 33 34
case class DispatchParameters
(
  IntDqSize: Int,
  FpDqSize: Int,
  LsDqSize: Int,
  IntDqDeqWidth: Int,
  FpDqDeqWidth: Int,
Y
Yinan Xu 已提交
35
  LsDqDeqWidth: Int
36 37
)

38
class Dispatch(implicit p: Parameters) extends XSModule {
39
  val io = IO(new Bundle() {
L
LinJiawei 已提交
40
    // flush or replay
41
    val redirect = Flipped(ValidIO(new Redirect))
42
    val flush = Input(Bool())
43 44
    // from rename
    val fromRename = Vec(RenameWidth, Flipped(DecoupledIO(new MicroOp)))
45
    val renameBypass = Input(new RenameBypassInfo)
46
    val preDpInfo = Input(new PreDispatchInfo)
Y
Yinan Xu 已提交
47 48
    // to busytable: set pdest to busy (not ready) when they are dispatched
    val allocPregs = Vec(RenameWidth, Output(new ReplayPregReq))
49
    // enq Roq
Y
Yinan Xu 已提交
50
    val enqRoq = Flipped(new RoqEnqIO)
Y
Yinan Xu 已提交
51
    // enq Lsq
Y
Yinan Xu 已提交
52
    val enqLsq = Flipped(new LsqEnqIO)
53
    // read regfile
Y
Yinan Xu 已提交
54 55 56 57 58
    val readIntRf = Vec(NRIntReadPorts, Output(UInt(PhyRegIdxWidth.W)))
    val readFpRf = Vec(NRFpReadPorts, Output(UInt(PhyRegIdxWidth.W)))
    // to busytable: read physical registers' state (busy/ready)
    val readIntState= Vec(NRIntReadPorts, Flipped(new BusyTableReadIO))
    val readFpState = Vec(NRFpReadPorts, Flipped(new BusyTableReadIO))
59
    // to reservation stations
60
    val numExist = Input(Vec(exuParameters.ExuCnt, UInt(log2Ceil(IssQueSize).W)))
L
LinJiawei 已提交
61
    val enqIQCtrl = Vec(exuParameters.ExuCnt, DecoupledIO(new MicroOp))
62 63
    // send reg file read port index to reservation stations
    val readPortIndex = new Bundle {
Y
YikeZhou 已提交
64 65
      val intIndex = Vec(exuParameters.IntExuCnt, Output(UInt(log2Ceil(8 / 2).W)))
      val fpIndex = Vec(exuParameters.FpExuCnt, Output(UInt(log2Ceil((NRFpReadPorts - exuParameters.StuCnt) / 3).W)))
66 67
      // ls: hardwired to (0, 1, 2, 4)
    }
68 69 70
    val csrCtrl = Input(new CustomCSRCtrlIO)
    // LFST state sync
    val storeIssue = Vec(StorePipelineWidth, Flipped(Valid(new ExuInput)))
71 72 73 74 75 76
    val ctrlInfo = new Bundle {
      val roqFull   = Output(Bool())
      val intdqFull = Output(Bool())
      val fpdqFull  = Output(Bool())
      val lsdqFull  = Output(Bool())
    }
77
  })
78

79
  val dispatch1 = Module(new Dispatch1)
80 81 82
  val intDq = Module(new DispatchQueue(dpParams.IntDqSize, RenameWidth, dpParams.IntDqDeqWidth, "int"))
  val fpDq = Module(new DispatchQueue(dpParams.FpDqSize, RenameWidth, dpParams.FpDqDeqWidth, "fp"))
  val lsDq = Module(new DispatchQueue(dpParams.LsDqSize, RenameWidth, dpParams.LsDqDeqWidth, "ls"))
83

84 85
  // pipeline between rename and dispatch
  // accepts all at once
86
  val redirectValid = io.redirect.valid || io.flush
87
  for (i <- 0 until RenameWidth) {
88
    PipelineConnect(io.fromRename(i), dispatch1.io.fromRename(i), dispatch1.io.recv(i), redirectValid)
89 90 91
  }

  // dispatch 1: accept uops from rename and dispatch them to the three dispatch queues
92
  // dispatch1.io.redirect <> io.redirect
93
  dispatch1.io.renameBypass := RegEnable(io.renameBypass, io.fromRename(0).valid && dispatch1.io.fromRename(0).ready)
94
  dispatch1.io.preDpInfo := RegEnable(io.preDpInfo, io.fromRename(0).valid && dispatch1.io.fromRename(0).ready)
95
  dispatch1.io.enqRoq <> io.enqRoq
96
  dispatch1.io.enqLsq <> io.enqLsq
97 98 99
  dispatch1.io.toIntDq <> intDq.io.enq
  dispatch1.io.toFpDq <> fpDq.io.enq
  dispatch1.io.toLsDq <> lsDq.io.enq
Y
Yinan Xu 已提交
100
  dispatch1.io.allocPregs <> io.allocPregs
101 102 103 104
  dispatch1.io.csrCtrl <> io.csrCtrl
  dispatch1.io.storeIssue <> io.storeIssue
  dispatch1.io.redirect <> io.redirect
  dispatch1.io.flush <> io.flush
105

106 107
  // dispatch queue: queue uops and dispatch them to different reservation stations or issue queues
  // it may cancel the uops
108
  intDq.io.redirect <> io.redirect
109
  intDq.io.flush <> io.flush
110
  fpDq.io.redirect <> io.redirect
111
  fpDq.io.flush <> io.flush
112
  lsDq.io.redirect <> io.redirect
113
  lsDq.io.flush <> io.flush
114

115
  // Int dispatch queue to Int reservation stations
116
  val intDispatch = Module(new Dispatch2Int)
117
  intDispatch.io.fromDq <> intDq.io.deq
118
  intDispatch.io.readRf.zipWithIndex.map({case (r, i) => r <> io.readIntRf(i)})
Y
Yinan Xu 已提交
119
  intDispatch.io.readState.zipWithIndex.map({case (r, i) => r <> io.readIntState(i)})
Y
Yinan Xu 已提交
120 121
  intDispatch.io.numExist.zipWithIndex.map({case (num, i) => num := io.numExist(i)})
  intDispatch.io.enqIQCtrl.zipWithIndex.map({case (enq, i) => enq <> io.enqIQCtrl(i)})
122
//  intDispatch.io.enqIQData.zipWithIndex.map({case (enq, i) => enq <> io.enqIQData(i)})
123
  intDispatch.io.readPortIndex <> io.readPortIndex.intIndex
124

125
  // Fp dispatch queue to Fp reservation stations
126
  val fpDispatch = Module(new Dispatch2Fp)
127 128
  fpDispatch.io.fromDq <> fpDq.io.deq
  fpDispatch.io.readRf.zipWithIndex.map({case (r, i) => r <> io.readFpRf(i)})
Y
Yinan Xu 已提交
129
  fpDispatch.io.readState.zipWithIndex.map({case (r, i) => r <> io.readFpState(i)})
130 131
  fpDispatch.io.numExist.zipWithIndex.map({case (num, i) => num := io.numExist(i + exuParameters.IntExuCnt)})
  fpDispatch.io.enqIQCtrl.zipWithIndex.map({case (enq, i) => enq <> io.enqIQCtrl(i + exuParameters.IntExuCnt)})
132
//  fpDispatch.io.enqIQData.zipWithIndex.map({case (enq, i) => enq <> io.enqIQData(i + exuParameters.IntExuCnt)})
133
  fpDispatch.io.readPortIndex <> io.readPortIndex.fpIndex
134
  
135
  // Load/store dispatch queue to load/store issue queues
136
  val lsDispatch = Module(new Dispatch2Ls)
137
  lsDispatch.io.fromDq <> lsDq.io.deq
138 139
  lsDispatch.io.readIntRf.zipWithIndex.map({case (r, i) => r <> io.readIntRf(i + 8)})
  lsDispatch.io.readFpRf.zipWithIndex.map({case (r, i) => r <> io.readFpRf(i + 12)})
Y
Yinan Xu 已提交
140 141
  lsDispatch.io.readIntState.zipWithIndex.map({case (r, i) => r <> io.readIntState(i + 8)})
  lsDispatch.io.readFpState.zipWithIndex.map({case (r, i) => r <> io.readFpState(i + 12)})
Y
Yinan Xu 已提交
142 143
  lsDispatch.io.numExist.zipWithIndex.map({case (num, i) => num := io.numExist(exuParameters.IntExuCnt + exuParameters.FpExuCnt + i)})
  lsDispatch.io.enqIQCtrl.zipWithIndex.map({case (enq, i) => enq <> io.enqIQCtrl(exuParameters.IntExuCnt + exuParameters.FpExuCnt + i)})
144
//  lsDispatch.io.enqIQData.zipWithIndex.map({case (enq, i) => enq <> io.enqIQData(exuParameters.IntExuCnt + exuParameters.FpExuCnt + i)})
145 146 147 148 149

  io.ctrlInfo <> DontCare
  io.ctrlInfo.intdqFull := intDq.io.dqFull
  io.ctrlInfo.fpdqFull := fpDq.io.dqFull
  io.ctrlInfo.lsdqFull := lsDq.io.dqFull
150

151
  val enableDetailedRegfilePortsPerf = true
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
  val intPortsNeeded = intDispatch.io.enqIQCtrl.map(enq => PopCount((0 until 2).map(i => enq.bits.needRfRPort(i, 0))))
  val fpPortsNeeded = fpDispatch.io.enqIQCtrl.map(enq => PopCount((0 until 3).map(i => enq.bits.needRfRPort(i, 1))))
  val lsPortsNeededInt = lsDispatch.io.enqIQCtrl.map(enq => PopCount((0 until 2).map(i => enq.bits.needRfRPort(i, 0))))
  val lsPortsNeededFp = lsDispatch.io.enqIQCtrl.map(enq => PopCount((0 until 2).map(i => enq.bits.needRfRPort(i, 1))))
  def get_active_ports(enq: Seq[Bool], ports: Seq[UInt]) = {
    enq.zip(ports).map{ case (e, p) => Mux(e, p, 0.U)}.reduce(_ +& _)
  }
  val intActivePorts = get_active_ports(intDispatch.io.enqIQCtrl.map(_.valid), intPortsNeeded)
  val fpActivePorts = get_active_ports(fpDispatch.io.enqIQCtrl.map(_.valid), fpPortsNeeded)
  val lsActivePortsInt = get_active_ports(lsDispatch.io.enqIQCtrl.map(_.valid), lsPortsNeededInt)
  val lsActivePortsFp = get_active_ports(lsDispatch.io.enqIQCtrl.map(_.valid), lsPortsNeededFp)
  val activePortsIntAll = intActivePorts + lsActivePortsInt
  val activePortsFpAll = fpActivePorts + lsActivePortsFp
  XSPerfAccumulate("int_rf_active_ports_int", intActivePorts)
  XSPerfAccumulate("int_rf_active_ports_ls", lsActivePortsInt)
  XSPerfAccumulate("int_rf_active_ports_all", activePortsIntAll)
  XSPerfAccumulate("fp_rf_active_ports_fp", fpActivePorts)
  XSPerfAccumulate("fp_rf_active_ports_ls", lsActivePortsFp)
  XSPerfAccumulate("fp_rf_active_ports_all", activePortsFpAll)
171 172 173 174 175 176 177 178
  if (enableDetailedRegfilePortsPerf) {
    XSPerfHistogram("int_rf_active_ports_all", activePortsIntAll, true.B, 0, 14+1, 1)
    XSPerfHistogram("fp_rf_active_ports_all", activePortsFpAll, true.B, 0, 14+1, 1)
    XSPerfHistogram("int_rf_active_ports_int", intActivePorts, true.B, 0, 8+1, 1)
    XSPerfHistogram("int_rf_active_ports_ls", lsActivePortsInt, true.B, 0, 6+1, 1)
    XSPerfHistogram("fp_rf_active_ports_fp", fpActivePorts, true.B, 0, 12+1, 1)
    XSPerfHistogram("fp_rf_active_ports_ls", lsActivePortsFp, true.B, 0, 2+1, 1)
  }
179
}