FloatBlock.scala 5.6 KB
Newer Older
1 2 3 4 5
package xiangshan.backend

import chisel3._
import chisel3.util._
import xiangshan._
6
import utils._
7 8
import xiangshan.backend.regfile.Regfile
import xiangshan.backend.exu._
9
import xiangshan.backend.issue.{ReservationStation}
10 11 12


class FpBlockToCtrlIO extends XSBundle {
L
LinJiawei 已提交
13
  val wbRegs = Vec(NRFpWritePorts, ValidIO(new ExuOutput))
14 15 16
  val numExist = Vec(exuParameters.FpExuCnt, Output(UInt(log2Ceil(IssQueSize).W)))
}

L
LinJiawei 已提交
17 18
class FloatBlock
(
19 20 21 22 23 24
  fastWakeUpIn: Seq[ExuConfig],
  slowWakeUpIn: Seq[ExuConfig],
  fastFpOut: Seq[ExuConfig],
  slowFpOut: Seq[ExuConfig],
  fastIntOut: Seq[ExuConfig],
  slowIntOut: Seq[ExuConfig]
Y
Yinan Xu 已提交
25
) extends XSModule with HasExeBlockHelper {
26 27 28
  val io = IO(new Bundle {
    val fromCtrlBlock = Flipped(new CtrlToFpBlockIO)
    val toCtrlBlock = new FpBlockToCtrlIO
29
    val toMemBlock = new FpBlockToMemBlockIO
Y
Yinan Xu 已提交
30

31 32 33
    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 已提交
34 35 36

    // from csr
    val frm = Input(UInt(3.W))
Y
Yinan Xu 已提交
37
  })
L
LinJiawei 已提交
38 39

  val redirect = io.fromCtrlBlock.redirect
40
  val flush = io.fromCtrlBlock.flush
L
LinJiawei 已提交
41 42 43 44 45 46 47 48 49 50 51

  val fpRf = Module(new Regfile(
    numReadPorts = NRFpReadPorts,
    numWirtePorts = NRFpWritePorts,
    hasZero = false,
    len = XLEN + 1
  ))

  val fmacExeUnits = Array.tabulate(exuParameters.FmacCnt)(_ => Module(new FmacExeUnit))
  val fmiscExeUnits = Array.tabulate(exuParameters.FmiscCnt)(_ => Module(new FmiscExeUnit))

L
LinJiawei 已提交
52 53 54
  fmacExeUnits.foreach(_.frm := io.frm)
  fmiscExeUnits.foreach(_.frm := io.frm)

L
LinJiawei 已提交
55 56 57 58 59 60 61 62
  val exeUnits = fmacExeUnits ++ fmiscExeUnits

  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)

63 64
  // val readPortIndex = RegNext(io.fromCtrlBlock.readPortIndex)
  val readPortIndex = Seq(0, 1, 2, 3, 2, 3)
L
LinJiawei 已提交
65 66 67 68 69 70 71 72 73 74
  val reservedStations = exeUnits.map(_.config).zipWithIndex.map({ case (cfg, i) =>
    var certainLatency = -1
    if (cfg.hasCertainLatency) {
      certainLatency = cfg.latency.latencyVal.get
    }

    val readFpRf = cfg.readFpRf

    val inBlockWbData = exeUnits.filter(e => e.config.hasCertainLatency && readFpRf).map(_.io.toFp.bits.data)
    val writeBackData = inBlockWbData ++ io.wakeUpIn.fast.map(_.bits.data)
75
    val fastPortsCnt = writeBackData.length
L
LinJiawei 已提交
76 77

    val inBlockListenPorts = exeUnits.filter(e => e.config.hasUncertainlatency && readFpRf).map(_.io.toFp)
78 79
    val slowPorts = inBlockListenPorts ++ io.wakeUpIn.slow
    val slowPortsCnt = slowPorts.length
L
LinJiawei 已提交
80

81 82
    println(s"${i}: exu:${cfg.name} fastPortsCnt: ${fastPortsCnt} " +
      s"slowPorts: ${slowPortsCnt} " +
L
LinJiawei 已提交
83 84 85
      s"delay:${certainLatency}"
    )

86
    val rs = Module(new ReservationStation(cfg, fastPortsCnt, slowPortsCnt, fixedDelay = certainLatency, fastWakeup = certainLatency >= 0, feedback = false))
L
LinJiawei 已提交
87

88
    rs.io.redirect <> redirect // TODO: remove it
Z
ZhangZifei 已提交
89
    rs.io.flush <> flush // TODO: remove it
90 91
    rs.io.numExist <> io.toCtrlBlock.numExist(i)
    rs.io.fromDispatch <> io.fromCtrlBlock.enqIqCtrl(i)
92

93
    rs.io.srcRegValue := DontCare
94 95 96
    val src1Value = VecInit((0 until 4).map(i => fpRf.io.readPorts(i * 3).data))
    val src2Value = VecInit((0 until 4).map(i => fpRf.io.readPorts(i * 3 + 1).data))
    val src3Value = VecInit((0 until 4).map(i => fpRf.io.readPorts(i * 3 + 2).data))
97 98 99 100 101 102 103

    rs.io.srcRegValue(0) := src1Value(readPortIndex(i))
    rs.io.srcRegValue(1) := src2Value(readPortIndex(i))
    if (cfg.fpSrcCnt > 2) rs.io.srcRegValue(2) := src3Value(readPortIndex(i))

    rs.io.fastDatas <> writeBackData
    for ((x, y) <- rs.io.slowPorts.zip(slowPorts)) {
L
LinJiawei 已提交
104 105 106 107 108
      x.valid := y.fire()
      x.bits := y.bits
    }

    exeUnits(i).io.redirect <> redirect
109
    exeUnits(i).io.flush <> flush
110
    exeUnits(i).io.fromFp <> rs.io.deq
111
    // rs.io.memfeedback := DontCare
L
LinJiawei 已提交
112

113
    rs.suggestName(s"rs_${cfg.name}")
L
LinJiawei 已提交
114

115
    rs
L
LinJiawei 已提交
116 117 118 119 120 121
  })

  for(rs <- reservedStations){
    val inBlockUops = reservedStations.filter(x =>
      x.exuCfg.hasCertainLatency && x.exuCfg.writeFpRf
    ).map(x => {
122 123
      val raw = WireInit(x.io.fastUopOut)
      raw.valid := x.io.fastUopOut.valid && raw.bits.ctrl.fpWen
L
LinJiawei 已提交
124 125
      raw
    })
126
    rs.io.fastUopsIn <> inBlockUops ++  io.wakeUpIn.fastUops
L
LinJiawei 已提交
127 128 129 130
  }

  io.wakeUpFpOut.fastUops <> reservedStations.filter(
    rs => fpFastFilter(rs.exuCfg)
131
  ).map(_.io.fastUopOut).map(fpValid)
L
LinJiawei 已提交
132 133 134 135 136 137 138 139 140 141 142

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

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

  io.wakeUpIntOut.fastUops <> reservedStations.filter(
    rs => intFastFilter(rs.exuCfg)
143
  ).map(_.io.fastUopOut).map(intValid)
L
LinJiawei 已提交
144 145 146 147 148 149 150 151 152 153

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

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


L
LinJiawei 已提交
154
  // read fp rf from ctrl block
Y
Yinan Xu 已提交
155
  fpRf.io.readPorts.zipWithIndex.map{ case (r, i) => r.addr := io.fromCtrlBlock.readRf(i) }
156
  (0 until exuParameters.StuCnt).foreach(i => io.toMemBlock.readFpRf(i).data := fpRf.io.readPorts(i + 12).data)
L
LinJiawei 已提交
157
  // write fp rf arbiter
L
LinJiawei 已提交
158
  val fpWbArbiter = Module(new Wb(
L
LinJiawei 已提交
159 160 161
    (exeUnits.map(_.config) ++ fastWakeUpIn ++ slowWakeUpIn),
    NRFpWritePorts,
    isFp = true
L
LinJiawei 已提交
162 163 164 165 166 167 168 169 170 171 172 173 174
  ))
  fpWbArbiter.io.in <> exeUnits.map(_.io.toFp) ++ io.wakeUpIn.fast ++ io.wakeUpIn.slow

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

  fpRf.io.writePorts.zip(fpWbArbiter.io.out).foreach{
    case (rf, wb) =>
      rf.wen := wb.valid && wb.bits.uop.ctrl.fpWen
      rf.addr := wb.bits.uop.pdest
      rf.data := wb.bits.data
  }

Z
ZhangZifei 已提交
175
}