XSCore.scala 20.7 KB
Newer Older
L
Lemover 已提交
1 2
/***************************************************************************************
* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
Y
Yinan Xu 已提交
3
* Copyright (c) 2020-2021 Peng Cheng Laboratory
L
Lemover 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16
*
* 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.
***************************************************************************************/

L
LinJiawei 已提交
17 18
package xiangshan

L
linjiawei 已提交
19
import chipsalliance.rocketchip.config
20
import chipsalliance.rocketchip.config.Parameters
21 22
import chisel3._
import chisel3.util._
23
import freechips.rocketchip.diplomacy.{BundleBridgeSource, LazyModule, LazyModuleImp}
J
Jiawei Lin 已提交
24
import freechips.rocketchip.interrupts.{IntSinkNode, IntSinkPortSimple}
L
LinJiawei 已提交
25
import freechips.rocketchip.tile.HasFPUParameters
J
Jiawei Lin 已提交
26
import freechips.rocketchip.tilelink.TLBuffer
27 28
import huancun.mbist.{MBISTInterface, MBISTPipeline}
import huancun.utils.{DFTResetSignals, ModuleNode, ResetGen, ResetGenNode, SRAMTemplate}
J
Jiawei Lin 已提交
29
import system.HasSoCParameter
L
LinJiawei 已提交
30
import utils._
31 32 33 34 35 36
import xiangshan.backend._
import xiangshan.backend.exu.{ExuConfig, Wb2Ctrl, WbArbiterWrapper}
import xiangshan.cache.mmu._
import xiangshan.frontend._

import scala.collection.mutable.ListBuffer
L
LinJiawei 已提交
37

38
abstract class XSModule(implicit val p: Parameters) extends MultiIOModule
L
LinJiawei 已提交
39
  with HasXSParameter
40
  with HasFPUParameters {
L
LinJiawei 已提交
41 42
  def io: Record
}
L
LinJiawei 已提交
43

44
//remove this trait after impl module logic
45 46
trait NeedImpl {
  this: RawModule =>
47
  override protected def IO[T <: Data](iodef: T): T = {
L
LinJiawei 已提交
48
    println(s"[Warn]: (${this.name}) please reomve 'NeedImpl' after implement this module")
49 50 51 52 53 54
    val io = chisel3.experimental.IO(iodef)
    io <> DontCare
    io
  }
}

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
class WritebackSourceParams(
  var exuConfigs: Seq[Seq[ExuConfig]] = Seq()
 ) {
  def length: Int = exuConfigs.length
  def ++(that: WritebackSourceParams): WritebackSourceParams = {
    new WritebackSourceParams(exuConfigs ++ that.exuConfigs)
  }
}

trait HasWritebackSource {
  val writebackSourceParams: Seq[WritebackSourceParams]
  final def writebackSource(sourceMod: HasWritebackSourceImp): Seq[Seq[Valid[ExuOutput]]] = {
    require(sourceMod.writebackSource.isDefined, "should not use Valid[ExuOutput]")
    val source = sourceMod.writebackSource.get
    require(source.length == writebackSourceParams.length, "length mismatch between sources")
    for ((s, p) <- source.zip(writebackSourceParams)) {
      require(s.length == p.length, "params do not match with the exuOutput")
    }
    source
  }
  final def writebackSource1(sourceMod: HasWritebackSourceImp): Seq[Seq[DecoupledIO[ExuOutput]]] = {
    require(sourceMod.writebackSource1.isDefined, "should not use DecoupledIO[ExuOutput]")
    val source = sourceMod.writebackSource1.get
    require(source.length == writebackSourceParams.length, "length mismatch between sources")
    for ((s, p) <- source.zip(writebackSourceParams)) {
      require(s.length == p.length, "params do not match with the exuOutput")
    }
    source
  }
  val writebackSourceImp: HasWritebackSourceImp
}

trait HasWritebackSourceImp {
  def writebackSource: Option[Seq[Seq[Valid[ExuOutput]]]] = None
  def writebackSource1: Option[Seq[Seq[DecoupledIO[ExuOutput]]]] = None
}

trait HasWritebackSink {
  // Caches all sources. The selected source will be the one with smallest length.
  var writebackSinks = ListBuffer.empty[(Seq[HasWritebackSource], Seq[Int])]
  def addWritebackSink(source: Seq[HasWritebackSource], index: Option[Seq[Int]] = None): HasWritebackSink = {
    val realIndex = if (index.isDefined) index.get else Seq.fill(source.length)(0)
    writebackSinks += ((source, realIndex))
    this
  }

  def writebackSinksParams: Seq[WritebackSourceParams] = {
    writebackSinks.map{ case (s, i) => s.zip(i).map(x => x._1.writebackSourceParams(x._2)).reduce(_ ++ _) }
  }
  final def writebackSinksMod(
     thisMod: Option[HasWritebackSource] = None,
     thisModImp: Option[HasWritebackSourceImp] = None
   ): Seq[Seq[HasWritebackSourceImp]] = {
    require(thisMod.isDefined == thisModImp.isDefined)
    writebackSinks.map(_._1.map(source =>
      if (thisMod.isDefined && source == thisMod.get) thisModImp.get else source.writebackSourceImp)
    )
  }
  final def writebackSinksImp(
    thisMod: Option[HasWritebackSource] = None,
    thisModImp: Option[HasWritebackSourceImp] = None
  ): Seq[Seq[ValidIO[ExuOutput]]] = {
    val sourceMod = writebackSinksMod(thisMod, thisModImp)
    writebackSinks.zip(sourceMod).map{ case ((s, i), m) =>
      s.zip(i).zip(m).flatMap(x => x._1._1.writebackSource(x._2)(x._1._2))
    }
  }
  def selWritebackSinks(func: WritebackSourceParams => Int): Int = {
    writebackSinksParams.zipWithIndex.minBy(params => func(params._1))._2
  }
  def generateWritebackIO(
    thisMod: Option[HasWritebackSource] = None,
    thisModImp: Option[HasWritebackSourceImp] = None
   ): Unit
}

131
abstract class XSBundle(implicit val p: Parameters) extends Bundle
L
LinJiawei 已提交
132 133
  with HasXSParameter

梁森 Liang Sen 已提交
134
abstract class XSCoreBase(val parentName:String = "Unknown")(implicit p: config.Parameters) extends LazyModule
135
  with HasXSParameter with HasExuWbHelper
136
{
J
Jiawei Lin 已提交
137 138 139
  // interrupt sinks
  val clint_int_sink = IntSinkNode(IntSinkPortSimple(1, 2))
  val debug_int_sink = IntSinkNode(IntSinkPortSimple(1, 1))
140
  val plic_int_sink = IntSinkNode(IntSinkPortSimple(2, 1))
Y
Yinan Xu 已提交
141
  // outer facing nodes
梁森 Liang Sen 已提交
142 143
  val frontend = LazyModule(new Frontend(parentName = parentName + "frontend_"))
  val ptw = LazyModule(new PTWWrapper(parentName = parentName + "ptw_"))
J
Jiawei Lin 已提交
144
  val ptw_to_l2_buffer = LazyModule(new TLBuffer)
145
  val csrOut = BundleBridgeSource(Some(() => new DistributedCSRIO()))
146

J
Jiawei Lin 已提交
147 148
  ptw_to_l2_buffer.node := ptw.node

149 150 151
  val wbArbiter = LazyModule(new WbArbiterWrapper(exuConfigs, NRIntWritePorts, NRFpWritePorts))
  val intWbPorts = wbArbiter.intWbPorts
  val fpWbPorts = wbArbiter.fpWbPorts
152

153 154 155 156 157 158
  // TODO: better RS organization
  // generate rs according to number of function units
  require(exuParameters.JmpCnt == 1)
  require(exuParameters.MduCnt <= exuParameters.AluCnt && exuParameters.MduCnt > 0)
  require(exuParameters.FmiscCnt <= exuParameters.FmacCnt && exuParameters.FmiscCnt > 0)
  require(exuParameters.LduCnt == 2 && exuParameters.StuCnt == 2)
159

160 161 162
  // one RS every 2 MDUs
  val schedulePorts = Seq(
    // exuCfg, numDeq, intFastWakeupTarget, fpFastWakeupTarget
163
    Seq(
164
      (AluExeUnitCfg, exuParameters.AluCnt, Seq(AluExeUnitCfg, LdExeUnitCfg, StaExeUnitCfg), Seq()),
165
      (MulDivExeUnitCfg, exuParameters.MduCnt, Seq(AluExeUnitCfg, MulDivExeUnitCfg), Seq()),
166 167 168 169
      (JumpCSRExeUnitCfg, 1, Seq(), Seq()),
      (LdExeUnitCfg, exuParameters.LduCnt, Seq(AluExeUnitCfg, LdExeUnitCfg), Seq()),
      (StaExeUnitCfg, exuParameters.StuCnt, Seq(), Seq()),
      (StdExeUnitCfg, exuParameters.StuCnt, Seq(), Seq())
170 171 172 173 174
    ),
    Seq(
      (FmacExeUnitCfg, exuParameters.FmacCnt, Seq(), Seq(FmacExeUnitCfg, FmiscExeUnitCfg)),
      (FmiscExeUnitCfg, exuParameters.FmiscCnt, Seq(), Seq())
    )
175
  )
176 177 178 179 180 181 182 183 184 185 186 187 188 189

  // should do outer fast wakeup ports here
  val otherFastPorts = schedulePorts.zipWithIndex.map { case (sche, i) =>
    val otherCfg = schedulePorts.zipWithIndex.filter(_._2 != i).map(_._1).reduce(_ ++ _)
    val outerPorts = sche.map(cfg => {
      // exe units from this scheduler need fastUops from exeunits
      val outerWakeupInSche = sche.filter(_._1.wakeupFromExu)
      val intraIntScheOuter = outerWakeupInSche.filter(_._3.contains(cfg._1)).map(_._1)
      val intraFpScheOuter = outerWakeupInSche.filter(_._4.contains(cfg._1)).map(_._1)
      // exe units from other schedulers need fastUop from outside
      val otherIntSource = otherCfg.filter(_._3.contains(cfg._1)).map(_._1)
      val otherFpSource = otherCfg.filter(_._4.contains(cfg._1)).map(_._1)
      val intSource = findInWbPorts(intWbPorts, intraIntScheOuter ++ otherIntSource)
      val fpSource = findInWbPorts(fpWbPorts, intraFpScheOuter ++ otherFpSource)
190
      getFastWakeupIndex(cfg._1, intSource, fpSource, intWbPorts.length).sorted
191 192 193 194 195
    })
    println(s"inter-scheduler wakeup sources for $i: $outerPorts")
    outerPorts
  }

196
  // allow mdu and fmisc to have 2*numDeq enqueue ports
197 198
  val intDpPorts = (0 until exuParameters.AluCnt).map(i => {
    if (i < exuParameters.JmpCnt) Seq((0, i), (1, i), (2, i))
199
    else if (i < 2 * exuParameters.MduCnt) Seq((0, i), (1, i))
200 201 202
    else Seq((0, i))
  })
  val lsDpPorts = Seq(
203 204 205 206 207
    Seq((3, 0)),
    Seq((3, 1)),
    Seq((4, 0)),
    Seq((4, 1))
  ) ++ (0 until exuParameters.StuCnt).map(i => Seq((5, i)))
208
  val fpDpPorts = (0 until exuParameters.FmacCnt).map(i => {
209
    if (i < 2 * exuParameters.FmiscCnt) Seq((0, i), (1, i))
210 211 212
    else Seq((0, i))
  })

213
  val dispatchPorts = Seq(intDpPorts ++ lsDpPorts, fpDpPorts)
214

215 216 217 218 219
  val outIntRfReadPorts = Seq(0, 0)
  val outFpRfReadPorts = Seq(0, 2)
  val hasIntRf = Seq(true, false)
  val hasFpRf = Seq(false, true)
  val exuBlocks = schedulePorts.zip(dispatchPorts).zip(otherFastPorts).zipWithIndex.map {
220 221
    case (((sche, disp), other), i) =>
      LazyModule(new ExuBlock(sche, disp, intWbPorts, fpWbPorts, other, outIntRfReadPorts(i), outFpRfReadPorts(i), hasIntRf(i), hasFpRf(i)))
222
  }
223

梁森 Liang Sen 已提交
224
  val memBlock = LazyModule(new MemBlock(parentName = parentName + "memblock_")(p.alter((site, here, up) => {
225
    case XSCoreParamsKey => up(XSCoreParamsKey).copy(
226
      IssQueSize = exuBlocks.head.scheduler.memRsEntries.max
227 228
    )
  })))
229 230 231

  val wb2Ctrl = LazyModule(new Wb2Ctrl(exuConfigs))
  wb2Ctrl.addWritebackSink(exuBlocks :+ memBlock)
232 233
  val dpExuConfigs = exuBlocks.flatMap(_.scheduler.dispatch2.map(_.configs))
  val ctrlBlock = LazyModule(new CtrlBlock(dpExuConfigs))
234 235
  val writebackSources = Seq(Seq(wb2Ctrl), Seq(wbArbiter))
  writebackSources.foreach(s => ctrlBlock.addWritebackSink(s))
236 237
}

梁森 Liang Sen 已提交
238
class XSCore(parentName:String = "Unknown")(implicit p: config.Parameters) extends XSCoreBase(parentName = parentName)
239 240
  with HasXSDts
{
L
linjiawei 已提交
241 242 243
  lazy val module = new XSCoreImp(this)
}

244
class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer)
245
  with HasXSParameter
246
  with HasSoCParameter {
Y
Yinan Xu 已提交
247
  val io = IO(new Bundle {
248
    val hartId = Input(UInt(64.W))
Y
Yinan Xu 已提交
249
    val cpu_halt = Output(Bool())
250
    val l2_pf_enable = Output(Bool())
251
    val perfEvents = Input(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent))
J
Jiawei Lin 已提交
252
    val beu_errors = Output(new XSL1BusErrors())
253
    val dfx_reset = Input(new DFTResetSignals())
Y
Yinan Xu 已提交
254
  })
255

Z
ZhangZifei 已提交
256 257
  println(s"FPGAPlatform:${env.FPGAPlatform} EnableDebug:${env.EnableDebug}")

J
jinyue110 已提交
258
  val frontend = outer.frontend.module
259 260
  val ctrlBlock = outer.ctrlBlock.module
  val wb2Ctrl = outer.wb2Ctrl.module
261
  val memBlock = outer.memBlock.module
L
linjiawei 已提交
262
  val ptw = outer.ptw.module
J
Jiawei Lin 已提交
263
  val ptw_to_l2_buffer = outer.ptw_to_l2_buffer.module
264 265
  val exuBlocks = outer.exuBlocks.map(_.module)

266
  frontend.io.hartId  := io.hartId
J
Jiawei Lin 已提交
267 268 269 270 271
  ctrlBlock.io.hartId := io.hartId
  exuBlocks.foreach(_.io.hartId := io.hartId)
  memBlock.io.hartId := io.hartId
  outer.wbArbiter.module.io.hartId := io.hartId

Y
Yinan Xu 已提交
272 273
  io.cpu_halt := ctrlBlock.io.cpu_halt

274
  outer.wbArbiter.module.io.redirect <> ctrlBlock.io.redirect
275
  val allWriteback = exuBlocks.flatMap(_.io.fuWriteback) ++ memBlock.io.writeback
276
  require(exuConfigs.length == allWriteback.length, s"${exuConfigs.length} != ${allWriteback.length}")
277 278
  outer.wbArbiter.module.io.in <> allWriteback
  val rfWriteback = outer.wbArbiter.module.io.out
279

280
  // memblock error exception writeback, 1 cycle after normal writeback
281
  wb2Ctrl.io.s3_delayed_load_error <> memBlock.io.s3_delayed_load_error
282

283 284 285
  wb2Ctrl.io.redirect <> ctrlBlock.io.redirect
  outer.wb2Ctrl.generateWritebackIO()

286 287
  io.beu_errors.icache <> frontend.io.error.toL1BusErrorUnitInfo()
  io.beu_errors.dcache <> memBlock.io.error.toL1BusErrorUnitInfo()
288

289 290 291 292 293
  require(exuBlocks.count(_.fuConfigs.map(_._1).contains(JumpCSRExeUnitCfg)) == 1)
  val csrFenceMod = exuBlocks.filter(_.fuConfigs.map(_._1).contains(JumpCSRExeUnitCfg)).head
  val csrioIn = csrFenceMod.io.fuExtra.csrio.get
  val fenceio = csrFenceMod.io.fuExtra.fenceio.get

294
  frontend.io.backend <> ctrlBlock.io.frontend
295 296 297 298
  frontend.io.sfence <> fenceio.sfence
  frontend.io.tlbCsr <> csrioIn.tlb
  frontend.io.csrCtrl <> csrioIn.customCtrl
  frontend.io.fencei := fenceio.fencei
299

300 301
  ctrlBlock.io.csrCtrl <> csrioIn.customCtrl
  val redirectBlocks = exuBlocks.reverse.filter(_.fuConfigs.map(_._1).map(_.hasRedirect).reduce(_ || _))
302
  ctrlBlock.io.exuRedirect <> redirectBlocks.flatMap(_.io.fuExtra.exuRedirect)
303 304
  ctrlBlock.io.stIn <> memBlock.io.stIn
  ctrlBlock.io.memoryViolation <> memBlock.io.memoryViolation
Y
Yinan Xu 已提交
305
  exuBlocks.head.io.scheExtra.enqLsq.get <> memBlock.io.enqLsq
306 307 308 309 310 311
  exuBlocks.foreach(b => {
    b.io.scheExtra.lcommit := ctrlBlock.io.robio.lsq.lcommit
    b.io.scheExtra.scommit := memBlock.io.sqDeq
    b.io.scheExtra.lqCancelCnt := memBlock.io.lqCancelCnt
    b.io.scheExtra.sqCancelCnt := memBlock.io.sqCancelCnt
  })
312 313
  val sourceModules = outer.writebackSources.map(_.map(_.module.asInstanceOf[HasWritebackSourceImp]))
  outer.ctrlBlock.generateWritebackIO()
314

Y
Yinan Xu 已提交
315 316
  val allFastUop = exuBlocks.flatMap(b => b.io.fastUopOut.dropRight(b.numOutFu)) ++ memBlock.io.otherFastWakeup
  require(allFastUop.length == exuConfigs.length, s"${allFastUop.length} != ${exuConfigs.length}")
317 318
  val intFastUop = allFastUop.zip(exuConfigs).filter(_._2.writeIntRf).map(_._1)
  val fpFastUop = allFastUop.zip(exuConfigs).filter(_._2.writeFpRf).map(_._1)
319 320
  val intFastUop1 = outer.wbArbiter.intConnections.map(c => intFastUop(c.head))
  val fpFastUop1 = outer.wbArbiter.fpConnections.map(c => fpFastUop(c.head))
321 322
  val allFastUop1 = intFastUop1 ++ fpFastUop1

323
  ctrlBlock.io.dispatch <> exuBlocks.flatMap(_.io.in)
324 325 326 327 328
  ctrlBlock.io.rsReady := exuBlocks.flatMap(_.io.scheExtra.rsReady)
  ctrlBlock.io.enqLsq <> memBlock.io.enqLsq
  ctrlBlock.io.sqDeq := memBlock.io.sqDeq
  ctrlBlock.io.lqCancelCnt := memBlock.io.lqCancelCnt
  ctrlBlock.io.sqCancelCnt := memBlock.io.sqCancelCnt
329 330

  exuBlocks(0).io.scheExtra.fpRfReadIn.get <> exuBlocks(1).io.scheExtra.fpRfReadOut.get
331
  exuBlocks(0).io.scheExtra.fpStateReadIn.get <> exuBlocks(1).io.scheExtra.fpStateReadOut.get
332

L
LinJiawei 已提交
333 334 335 336 337 338 339
  for((c, e) <- ctrlBlock.io.ld_pc_read.zip(exuBlocks(0).io.issue.get)){
    // read load pc at load s0
    c.ptr := e.bits.uop.cf.ftqPtr
    c.offset := e.bits.uop.cf.ftqOffset
  }
  // return load pc at load s2
  memBlock.io.loadPc <> VecInit(ctrlBlock.io.ld_pc_read.map(_.data))
340
  memBlock.io.issue <> exuBlocks(0).io.issue.get
341 342
  // By default, instructions do not have exceptions when they enter the function units.
  memBlock.io.issue.map(_.bits.uop.clearExceptions())
343
  exuBlocks(0).io.scheExtra.loadFastMatch.get <> memBlock.io.loadFastMatch
344
  exuBlocks(0).io.scheExtra.loadFastImm.get <> memBlock.io.loadFastImm
345

346
  val stdIssue = exuBlocks(0).io.issue.get.takeRight(exuParameters.StuCnt)
347 348
  exuBlocks.map(_.io).foreach { exu =>
    exu.redirect <> ctrlBlock.io.redirect
349
    exu.allocPregs <> ctrlBlock.io.allocPregs
350 351 352 353 354 355 356
    exu.rfWriteback <> rfWriteback
    exu.fastUopIn <> allFastUop1
    exu.scheExtra.jumpPc <> ctrlBlock.io.jumpPc
    exu.scheExtra.jalr_target <> ctrlBlock.io.jalr_target
    exu.scheExtra.stIssuePtr <> memBlock.io.stIssuePtr
    exu.scheExtra.debug_fp_rat <> ctrlBlock.io.debug_fp_rat
    exu.scheExtra.debug_int_rat <> ctrlBlock.io.debug_int_rat
H
Haojin Tang 已提交
357 358
    exu.scheExtra.lqFull := memBlock.io.lqFull
    exu.scheExtra.sqFull := memBlock.io.sqFull
359 360
    exu.scheExtra.memWaitUpdateReq.staIssue.zip(memBlock.io.stIn).foreach{case (sink, src) => {
      sink.bits := src.bits
361
      sink.valid := src.valid
362 363 364 365 366
    }}
    exu.scheExtra.memWaitUpdateReq.stdIssue.zip(stdIssue).foreach{case (sink, src) => {
      sink.valid := src.valid
      sink.bits := src.bits
    }}
367
  }
368 369
  XSPerfHistogram("fastIn_count", PopCount(allFastUop1.map(_.valid)), true.B, 0, allFastUop1.length, 1)
  XSPerfHistogram("wakeup_count", PopCount(rfWriteback.map(_.valid)), true.B, 0, rfWriteback.length, 1)
370

371 372 373 374
  ctrlBlock.perfinfo.perfEventsEu0 := exuBlocks(0).getPerf.dropRight(outer.exuBlocks(0).scheduler.numRs)
  ctrlBlock.perfinfo.perfEventsEu1 := exuBlocks(1).getPerf.dropRight(outer.exuBlocks(1).scheduler.numRs)
  memBlock.io.perfEventsPTW  := ptw.getPerf
  ctrlBlock.perfinfo.perfEventsRs  := outer.exuBlocks.flatMap(b => b.module.getPerf.takeRight(b.scheduler.numRs))
375

376 377
  csrioIn.hartId <> io.hartId
  csrioIn.perf <> DontCare
Y
Yinan Xu 已提交
378
  csrioIn.perf.retiredInstr <> ctrlBlock.io.robio.toCSR.perfinfo.retiredInstr
379 380 381 382
  csrioIn.perf.ctrlInfo <> ctrlBlock.io.perfInfo.ctrlInfo
  csrioIn.perf.memInfo <> memBlock.io.memInfo
  csrioIn.perf.frontendInfo <> frontend.io.frontendInfo

383 384 385
  csrioIn.perf.perfEventsFrontend <> frontend.getPerf
  csrioIn.perf.perfEventsCtrl     <> ctrlBlock.getPerf
  csrioIn.perf.perfEventsLsu      <> memBlock.getPerf
386 387
  csrioIn.perf.perfEventsHc       <> io.perfEvents

Y
Yinan Xu 已提交
388
  csrioIn.fpu.fflags <> ctrlBlock.io.robio.toCSR.fflags
389
  csrioIn.fpu.isIllegal := false.B
Y
Yinan Xu 已提交
390
  csrioIn.fpu.dirty_fs <> ctrlBlock.io.robio.toCSR.dirty_fs
391
  csrioIn.fpu.frm <> exuBlocks(1).io.fuExtra.frm.get
Y
Yinan Xu 已提交
392 393 394 395
  csrioIn.exception <> ctrlBlock.io.robio.exception
  csrioIn.isXRet <> ctrlBlock.io.robio.toCSR.isXRet
  csrioIn.trapTarget <> ctrlBlock.io.robio.toCSR.trapTarget
  csrioIn.interrupt <> ctrlBlock.io.robio.toCSR.intrBitSet
Y
Yinan Xu 已提交
396
  csrioIn.wfi_event <> ctrlBlock.io.robio.toCSR.wfiEvent
397
  csrioIn.memExceptionVAddr <> memBlock.io.lsqio.exceptionAddr.vaddr
J
Jiawei Lin 已提交
398 399 400 401

  csrioIn.externalInterrupt.msip := outer.clint_int_sink.in.head._1(0)
  csrioIn.externalInterrupt.mtip := outer.clint_int_sink.in.head._1(1)
  csrioIn.externalInterrupt.meip := outer.plic_int_sink.in.head._1(0)
402
  csrioIn.externalInterrupt.seip := outer.plic_int_sink.in.last._1(0)
J
Jiawei Lin 已提交
403
  csrioIn.externalInterrupt.debug := outer.debug_int_sink.in.head._1(0)
404

405 406 407 408
  csrioIn.distributedUpdate(0).w.valid := memBlock.io.csrUpdate.w.valid
  csrioIn.distributedUpdate(0).w.bits := memBlock.io.csrUpdate.w.bits
  csrioIn.distributedUpdate(1).w.valid := frontend.io.csrUpdate.w.valid
  csrioIn.distributedUpdate(1).w.bits := frontend.io.csrUpdate.w.bits
409

410 411
  fenceio.sfence <> memBlock.io.sfence
  fenceio.sbuffer <> memBlock.io.fenceToSbuffer
Y
Yinan Xu 已提交
412

413
  memBlock.io.redirect <> ctrlBlock.io.redirect
414
  memBlock.io.rsfeedback <> exuBlocks(0).io.scheExtra.feedback.get
415 416
  memBlock.io.csrCtrl <> csrioIn.customCtrl
  memBlock.io.tlbCsr <> csrioIn.tlb
Y
Yinan Xu 已提交
417 418
  memBlock.io.lsqio.rob <> ctrlBlock.io.robio.lsq
  memBlock.io.lsqio.exceptionAddr.isStore := CommitType.lsInstIsStore(ctrlBlock.io.robio.exception.bits.uop.ctrl.commitType)
419

420 421
  val itlbRepeater1 = PTWRepeater(frontend.io.ptw, fenceio.sfence, csrioIn.tlb)
  val itlbRepeater2 = PTWRepeater(itlbRepeater1.io.ptw, ptw.io.tlb(0), fenceio.sfence, csrioIn.tlb)
422 423
  val dtlbRepeater1  = PTWFilter(memBlock.io.ptw, fenceio.sfence, csrioIn.tlb, l2tlbParams.filterSize)
  val dtlbRepeater2  = PTWRepeaterNB(passReady = false, dtlbRepeater1.io.ptw, ptw.io.tlb(1), fenceio.sfence, csrioIn.tlb)
424
  ptw.io.sfence <> fenceio.sfence
L
Lemover 已提交
425 426
  ptw.io.csr.tlb <> csrioIn.tlb
  ptw.io.csr.distribute_csr <> csrioIn.customCtrl.distribute_csr
427
  ptw.io.csr.prefercache <> csrioIn.customCtrl.ptw_prefercache_enable
428

429
  // if l2 prefetcher use stream prefetch, it should be placed in XSCore
430
  io.l2_pf_enable := csrioIn.customCtrl.l2_pf_enable
431

梁森 Liang Sen 已提交
432 433 434 435 436
  val mbistPipeline = if(coreParams.hasMbist && coreParams.hasShareBus) {
    Some(Module(new MBISTPipeline(Int.MaxValue,s"MBIST_Core")))
  } else {
    None
  }
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454

  val coreMbistIntf = if (coreParams.hasMbist && coreParams.hasShareBus) {
    val params = mbistPipeline.get.bd.params
    val node = mbistPipeline.get.node
    val intf = Some(Module(new MBISTInterface(
      params = Seq(params),
      ids = Seq(node.children.flatMap(_.array_id)),
      name = s"MBIST_intf_core",
      pipelineNum = 1
    )))
    intf.get.toPipeline.head <> mbistPipeline.get.io.mbist.get
    mbistPipeline.get.genCSV(intf.get.info, "MBIST_Core")
    intf.get.mbist := DontCare
    dontTouch(intf.get.mbist)
    //TODO: add mbist controller connections here
    intf
  } else {
    None
梁森 Liang Sen 已提交
455
  }
456

梁森 Liang Sen 已提交
457
  val sigFromSrams = if(coreParams.hasMbist) Some(SRAMTemplate.genBroadCastBundleTop()) else None
458
  val dft = if(coreParams.hasMbist) Some(IO(sigFromSrams.get.cloneType)) else None
梁森 Liang Sen 已提交
459
  if(coreParams.hasMbist) {
460 461
    dft.get <> sigFromSrams.get
    dontTouch(dft.get)
梁森 Liang Sen 已提交
462
  }
463
  // Modules are reset one by one
J
Jiawei Lin 已提交
464 465 466 467 468 469 470 471 472 473 474 475
  val resetTree = ResetGenNode(
    Seq(
      ModuleNode(memBlock), ModuleNode(dtlbRepeater1),
      ResetGenNode(Seq(
        ModuleNode(itlbRepeater2),
        ModuleNode(ptw),
        ModuleNode(dtlbRepeater2),
        ModuleNode(ptw_to_l2_buffer),
      )),
      ResetGenNode(Seq(
        ModuleNode(exuBlocks.head),
        ResetGenNode(
476
          exuBlocks.tail.map(m => ModuleNode(m)) :+ ModuleNode(outer.wbArbiter.module) :+ ModuleNode(wb2Ctrl)
J
Jiawei Lin 已提交
477 478 479 480 481 482 483 484 485
        ),
        ResetGenNode(Seq(
          ModuleNode(ctrlBlock),
          ResetGenNode(Seq(
            ModuleNode(frontend), ModuleNode(itlbRepeater1)
          ))
        ))
      ))
    )
486
  )
J
Jiawei Lin 已提交
487

488
  ResetGen(resetTree, reset, Some(io.dfx_reset), !debugOpts.FPGAPlatform)
J
Jiawei Lin 已提交
489

L
LinJiawei 已提交
490
}