IntegerBlock.scala 7.3 KB
Newer Older
1 2 3 4 5
package xiangshan.backend

import chisel3._
import chisel3.util._
import xiangshan._
L
LinJiawei 已提交
6 7
import xiangshan.backend.exu.Exu.{jumpExeUnitCfg, ldExeUnitCfg, stExeUnitCfg}
import xiangshan.backend.exu.{AluExeUnit, ExuConfig, JumpExeUnit, MulDivExeUnit, Wb}
L
LinJiawei 已提交
8
import xiangshan.backend.fu.FenceToSbuffer
L
LinJiawei 已提交
9 10
import xiangshan.backend.issue.ReservationStationNew
import xiangshan.backend.regfile.Regfile
Y
Yinan Xu 已提交
11
import xiangshan.backend.fu.fpu.Fflags
12

L
LinJiawei 已提交
13 14 15 16 17 18 19 20 21
class WakeUpBundle(numFast: Int, numSlow: Int) extends XSBundle {
  val fastUops = Vec(numFast, Flipped(ValidIO(new MicroOp)))
  val fast = Vec(numFast, Flipped(DecoupledIO(new ExuOutput))) //one cycle later than fastUops
  val slow = Vec(numSlow, Flipped(DecoupledIO(new ExuOutput)))

  override def cloneType = (new WakeUpBundle(numFast, numSlow)).asInstanceOf[this.type]

}

22
class IntBlockToCtrlIO extends XSBundle {
L
LinJiawei 已提交
23 24 25 26 27
  // write back regfile signals after arbiter
  // used to update busytable and roq state
  val wbRegs = Vec(NRIntWritePorts, ValidIO(new ExuOutput))
  // write back to brq
  val exuRedirect = Vec(exuParameters.AluCnt+exuParameters.JmpCnt, ValidIO(new ExuOutput))
28 29 30
  val numExist = Vec(exuParameters.IntExuCnt, Output(UInt(log2Ceil(IssQueSize).W)))
}

L
LinJiawei 已提交
31 32 33 34 35 36 37 38 39 40 41 42 43
trait HasExeBlockHelper {
  def fpFastFilter(cfg: ExuConfig): Boolean = {
    cfg.hasCertainLatency && cfg.writeFpRf
  }
  def fpSlowFilter(cfg: ExuConfig): Boolean = {
    cfg.hasUncertainlatency && cfg.writeFpRf
  }
  def intFastFilter(cfg: ExuConfig): Boolean = {
    cfg.hasCertainLatency && cfg.writeIntRf
  }
  def intSlowFilter(cfg: ExuConfig): Boolean = {
    cfg.hasUncertainlatency && cfg.writeIntRf
  }
44 45 46 47 48 49 50 51 52 53
  def fpValid(x: ValidIO[MicroOp]): ValidIO[MicroOp] = {
	val uop = WireInit(x)
	uop.valid := x.valid && x.bits.ctrl.fpWen
	uop
  }
  def intValid(x: ValidIO[MicroOp]): ValidIO[MicroOp] = {
	val uop = WireInit(x)
	uop.valid := x.valid && x.bits.ctrl.rfWen
	uop
  }
L
LinJiawei 已提交
54 55
}

L
LinJiawei 已提交
56 57
class IntegerBlock
(
L
LinJiawei 已提交
58 59 60 61 62 63
  fastWakeUpIn: Seq[ExuConfig],
  slowWakeUpIn: Seq[ExuConfig],
  fastFpOut: Seq[ExuConfig],
  slowFpOut: Seq[ExuConfig],
  fastIntOut: Seq[ExuConfig],
  slowIntOut: Seq[ExuConfig]
Y
Yinan Xu 已提交
64
) extends XSModule with HasExeBlockHelper
L
LinJiawei 已提交
65
{
66 67 68
  val io = IO(new Bundle {
    val fromCtrlBlock = Flipped(new CtrlToIntBlockIO)
    val toCtrlBlock = new IntBlockToCtrlIO
L
LinJiawei 已提交
69

L
LinJiawei 已提交
70 71 72
    val wakeUpIn = new WakeUpBundle(fastWakeUpIn.size, slowWakeUpIn.size)
    val wakeUpFpOut = Flipped(new WakeUpBundle(fastFpOut.size, slowFpOut.size))
    val wakeUpIntOut = Flipped(new WakeUpBundle(fastIntOut.size, slowIntOut.size))
L
LinJiawei 已提交
73

Y
Yinan Xu 已提交
74 75 76
    val csrio = new Bundle {
      val fflags = Input(new Fflags) // from roq
      val dirty_fs = Input(Bool()) // from roq
Y
Yinan Xu 已提交
77
      val frm = Output(UInt(3.W)) // to float
Y
Yinan Xu 已提交
78 79 80 81 82 83 84 85 86
      val exception = Flipped(ValidIO(new MicroOp)) // from roq
      val isInterrupt = Input(Bool()) // from roq
      val trapTarget = Output(UInt(VAddrBits.W)) // to roq
      val interrupt = Output(Bool()) // to roq
      val memExceptionVAddr = Input(UInt(VAddrBits.W)) // from lsq
      val externalInterrupt = new ExternalInterruptIO  // from outside
      val tlb = Output(new TlbCsrBundle) // from tlb
    }
    val fenceio = new Bundle {
Y
Yinan Xu 已提交
87 88 89
      val sfence = Output(new SfenceBundle) // to front,mem
      val fencei = Output(Bool())           // to icache
      val sbuffer = new FenceToSbuffer      // to mem
Y
Yinan Xu 已提交
90
    }
91
  })
L
LinJiawei 已提交
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113

  val redirect = io.fromCtrlBlock.redirect

  val intRf = Module(new Regfile(
    numReadPorts = NRIntReadPorts,
    numWirtePorts = NRIntWritePorts,
    hasZero = true,
    len = XLEN
  ))

  val aluExeUnits = Array.tabulate(exuParameters.AluCnt)(_ => Module(new AluExeUnit))
  val jmpExeUnit = Module(new JumpExeUnit)
  val mduExeUnits = Array.tabulate(exuParameters.MduCnt)(_ => Module(new MulDivExeUnit))

  val exeUnits = jmpExeUnit +: (aluExeUnits ++ mduExeUnits)

  def needWakeup(cfg: ExuConfig): Boolean =
    (cfg.readIntRf && cfg.writeIntRf) || (cfg.readFpRf && cfg.writeFpRf)

  def needData(a: ExuConfig, b: ExuConfig): Boolean =
    (a.readIntRf && b.writeIntRf) || (a.readFpRf && b.writeFpRf)

Y
Yinan Xu 已提交
114
  val reservationStations = exeUnits.map(_.config).zipWithIndex.map({ case (cfg, i) =>
L
LinJiawei 已提交
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
    var certainLatency = -1
    if (cfg.hasCertainLatency) {
      certainLatency = cfg.latency.latencyVal.get
    }

    val readIntRf = cfg.readIntRf

    val inBlockWbData = exeUnits.filter(e => e.config.hasCertainLatency && readIntRf).map(_.io.toInt.bits.data)
    val writeBackData = inBlockWbData ++ io.wakeUpIn.fast.map(_.bits.data)
    val wakeupCnt = writeBackData.length

    val inBlockListenPorts = exeUnits.filter(e => e.config.hasUncertainlatency && readIntRf).map(_.io.toInt)
    val extraListenPorts = inBlockListenPorts ++ io.wakeUpIn.slow
    val extraListenPortsCnt = extraListenPorts.length

    val feedback = (cfg == ldExeUnitCfg) || (cfg == stExeUnitCfg)

    println(s"${i}: exu:${cfg.name} wakeupCnt: ${wakeupCnt} extraListenPorts: ${extraListenPortsCnt} delay:${certainLatency} feedback:${feedback}")

    val rs = Module(new ReservationStationNew(
      cfg, wakeupCnt, extraListenPortsCnt, fixedDelay = certainLatency, feedback = feedback
    ))

    rs.io.redirect <> redirect
    rs.io.numExist <> io.toCtrlBlock.numExist(i)
    rs.io.enqCtrl <> io.fromCtrlBlock.enqIqCtrl(i)
    rs.io.enqData <> io.fromCtrlBlock.enqIqData(i)

    rs.io.writeBackedData <> writeBackData
    for ((x, y) <- rs.io.extraListenPorts.zip(extraListenPorts)) {
      x.valid := y.fire()
      x.bits := y.bits
    }

    exeUnits(i).io.redirect <> redirect
    exeUnits(i).io.fromInt <> rs.io.deq
    rs.io.tlbFeedback := DontCare

    rs.suggestName(s"rs_${cfg.name}")

    rs
  })

Y
Yinan Xu 已提交
158 159
  for(rs <- reservationStations){
    val inBlockUops = reservationStations.filter(x =>
L
LinJiawei 已提交
160 161 162 163 164 165 166 167 168
      x.exuCfg.hasCertainLatency && x.exuCfg.writeIntRf
    ).map(x => {
      val raw = WireInit(x.io.selectedUop)
      raw.valid := x.io.selectedUop.valid && raw.bits.ctrl.rfWen
      raw
    })
    rs.io.broadcastedUops <> inBlockUops ++ io.wakeUpIn.fastUops
  }

Y
Yinan Xu 已提交
169
  io.wakeUpFpOut.fastUops <> reservationStations.filter(
L
LinJiawei 已提交
170
    rs => fpFastFilter(rs.exuCfg)
171
  ).map(_.io.selectedUop).map(fpValid)
L
LinJiawei 已提交
172 173 174 175 176 177 178 179 180

  io.wakeUpFpOut.fast <> exeUnits.filter(
    x => fpFastFilter(x.config)
  ).map(_.io.toFp)

  io.wakeUpFpOut.slow <> exeUnits.filter(
    x => fpSlowFilter(x.config)
  ).map(_.io.toFp)

Y
Yinan Xu 已提交
181
  io.wakeUpIntOut.fastUops <> reservationStations.filter(
L
LinJiawei 已提交
182
    rs => intFastFilter(rs.exuCfg)
183
  ).map(_.io.selectedUop).map(intValid)
L
LinJiawei 已提交
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201

  io.wakeUpIntOut.fast <> exeUnits.filter(
    x => intFastFilter(x.config)
  ).map(_.io.toInt)

  io.wakeUpIntOut.slow <> exeUnits.filter(
    x => intSlowFilter(x.config)
  ).map(_.io.toInt)

  // send misprediction to brq
  io.toCtrlBlock.exuRedirect.zip(
    exeUnits.filter(_.config.hasRedirect).map(_.io.toInt)
  ).foreach{
    case (x, y) =>
      x.valid := y.fire() && y.bits.redirectValid
      x.bits := y.bits
  }

Y
Yinan Xu 已提交
202 203
  jmpExeUnit.csrio <> io.csrio
  jmpExeUnit.fenceio <> io.fenceio
L
LinJiawei 已提交
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222

  // read int rf from ctrl block
  intRf.io.readPorts <> io.fromCtrlBlock.readRf
  // write int rf arbiter
  val intWbArbiter = Module(new Wb(
    (exeUnits.map(_.config) ++ fastWakeUpIn ++ slowWakeUpIn).map(_.wbIntPriority),
    NRIntWritePorts
  ))
  intWbArbiter.io.in <> exeUnits.map(_.io.toInt) ++ io.wakeUpIn.fast ++ io.wakeUpIn.slow

  // set busytable and update roq
  io.toCtrlBlock.wbRegs <> intWbArbiter.io.out

  intRf.io.writePorts.zip(intWbArbiter.io.out).foreach{
    case (rf, wb) =>
      rf.wen := wb.valid && wb.bits.uop.ctrl.rfWen
      rf.addr := wb.bits.uop.pdest
      rf.data := wb.bits.data
  }
223
}