XSCore.scala 11.5 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.
***************************************************************************************/

L
LinJiawei 已提交
16 17 18 19 20
package xiangshan

import chisel3._
import chisel3.util._
import xiangshan.backend._
21
import xiangshan.backend.fu.HasExceptionNO
22
import xiangshan.backend.exu.Wb
G
GouLingrui 已提交
23
import xiangshan.frontend._
24 25 26
import xiangshan.mem._
import xiangshan.cache.{DCacheParameters, L1plusCacheWrapper, L1plusCacheParameters, PTWWrapper, PTWRepeater, PTWFilter}
import xiangshan.cache.prefetch._
L
linjiawei 已提交
27
import chipsalliance.rocketchip.config
28
import chipsalliance.rocketchip.config.Parameters
29
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp}
L
LinJiawei 已提交
30
import freechips.rocketchip.tile.HasFPUParameters
31
import system.{HasSoCParameter, L1CacheErrorInfo}
L
LinJiawei 已提交
32
import utils._
L
LinJiawei 已提交
33

34
abstract class XSModule(implicit val p: Parameters) extends MultiIOModule
L
LinJiawei 已提交
35 36
  with HasXSParameter
  with HasExceptionNO
37
  with HasFPUParameters {
L
LinJiawei 已提交
38 39
  def io: Record
}
L
LinJiawei 已提交
40

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

52
abstract class XSBundle(implicit val p: Parameters) extends Bundle
L
LinJiawei 已提交
53 54
  with HasXSParameter

L
LinJiawei 已提交
55
case class EnviromentParameters
L
LinJiawei 已提交
56 57
(
  FPGAPlatform: Boolean = true,
Y
Yinan Xu 已提交
58
  EnableDebug: Boolean = false,
Z
zoujr 已提交
59
  EnablePerfDebug: Boolean = true,
60
  DualCore: Boolean = false
L
LinJiawei 已提交
61 62
)

63
abstract class XSCoreBase()(implicit p: config.Parameters) extends LazyModule
64
  with HasXSParameter
65
{
Y
Yinan Xu 已提交
66
  // outer facing nodes
J
jinyue110 已提交
67
  val frontend = LazyModule(new Frontend())
68 69
  val l1pluscache = LazyModule(new L1plusCacheWrapper())
  val ptw = LazyModule(new PTWWrapper())
70
  val memBlock = LazyModule(new MemBlock)
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
  // 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)
  // one RS every 2 MDUs
  val schedulePorts = Seq(
    // exuCfg, numDeq, intFastWakeupTarget, fpFastWakeupTarget
    (AluExeUnitCfg, exuParameters.AluCnt, Seq(0, 1, 2, 5, 6, 7, 8), Seq()),
    (MulDivExeUnitCfg, exuParameters.MduCnt, Seq(0, 1, 2, 5, 6, 7, 8), Seq()),
    (JumpExeUnitCfg, 1, Seq(), Seq()),
    (FmacExeUnitCfg, exuParameters.FmacCnt, Seq(), Seq(3, 4)),
    (FmiscExeUnitCfg, exuParameters.FmiscCnt, Seq(), Seq(3, 4)),
    (LdExeUnitCfg, 1, Seq(0, 5, 6), Seq()),
    (LdExeUnitCfg, 1, Seq(0, 5, 6), Seq()),
    (StExeUnitCfg, 1, Seq(), Seq()),
    (StExeUnitCfg, 1, Seq(), Seq())
  )
  // allow mdu and fmisc to have 2*numDeq enqueue ports
  val intDpPorts = (0 until exuParameters.AluCnt).map(i => {
    if (i < exuParameters.JmpCnt) Seq((0, i), (1, i), (2, i))
    else if (i < 2*exuParameters.MduCnt) Seq((0, i), (1, i))
    else Seq((0, i))
  })
  val fpDpPorts = (0 until exuParameters.FmacCnt).map(i => {
    if (i < 2*exuParameters.FmiscCnt) Seq((3, i), (4, i))
    else Seq((4, i))
  })
  val lsDpPorts = Seq(
    Seq((5, 0)),
    Seq((6, 0)),
    Seq((7, 0)),
    Seq((8, 0))
  )
  val dispatchPorts = intDpPorts ++ fpDpPorts ++ lsDpPorts

  val scheduler = LazyModule(new Scheduler(schedulePorts, dispatchPorts))

111 112 113 114 115
}

class XSCore()(implicit p: config.Parameters) extends XSCoreBase
  with HasXSDts
{
L
linjiawei 已提交
116 117 118
  lazy val module = new XSCoreImp(this)
}

119
class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer)
120
  with HasXSParameter
121
  with HasSoCParameter
122
  with HasExeBlockHelper {
Y
Yinan Xu 已提交
123
  val io = IO(new Bundle {
124
    val hartId = Input(UInt(64.W))
Y
Yinan Xu 已提交
125
    val externalInterrupt = new ExternalInterruptIO
126
    val l2_pf_enable = Output(Bool())
L
ljw 已提交
127
    val l1plus_error, icache_error, dcache_error = Output(new L1CacheErrorInfo)
Y
Yinan Xu 已提交
128
  })
129

Z
ZhangZifei 已提交
130
  println(s"FPGAPlatform:${env.FPGAPlatform} EnableDebug:${env.EnableDebug}")
W
William Wang 已提交
131
  AddressSpace.checkMemmap()
132
  AddressSpace.printMemmap()
Z
ZhangZifei 已提交
133

L
LinJiawei 已提交
134
  // to fast wake up fp, mem rs
135 136
  val intBlockFastWakeUp = intExuConfigs.filter(_.hasCertainLatency)
  val intBlockSlowWakeUp = intExuConfigs.filter(_.hasUncertainlatency)
L
LinJiawei 已提交
137

138
  val ctrlBlock = Module(new CtrlBlock)
139

140 141
  val integerBlock = Module(new IntegerBlock)
  val floatBlock = Module(new FloatBlock)
L
linjiawei 已提交
142

J
jinyue110 已提交
143
  val frontend = outer.frontend.module
144
  val memBlock = outer.memBlock.module
J
jinyue110 已提交
145
  val l1pluscache = outer.l1pluscache.module
L
linjiawei 已提交
146
  val ptw = outer.ptw.module
147
  val scheduler = outer.scheduler.module
L
linjiawei 已提交
148

149 150
  val allWriteback = integerBlock.io.writeback ++ floatBlock.io.writeback ++ memBlock.io.writeback
  val intConfigs = exuConfigs.filter(_.writeIntRf)
151
  val intArbiter = Module(new Wb(intConfigs, NRIntWritePorts, isFp = false))
152
  val intWriteback = allWriteback.zip(exuConfigs).filter(_._2.writeIntRf).map(_._1)
153 154 155 156 157 158 159 160 161 162 163 164
  // set default value for ready
  integerBlock.io.writeback.map(_.ready := true.B)
  floatBlock.io.writeback.map(_.ready := true.B)
  memBlock.io.writeback.map(_.ready := true.B)
  intArbiter.io.in.zip(intWriteback).foreach { case (arb, wb) =>
    arb.valid := wb.valid && !wb.bits.uop.ctrl.fpWen
    arb.bits := wb.bits
    when (arb.valid) {
      wb.ready := arb.ready
    }
  }

165 166
  val fpArbiter = Module(new Wb(exuConfigs.filter(_.writeFpRf), NRFpWritePorts, isFp = true))
  val fpWriteback = allWriteback.zip(exuConfigs).filter(_._2.writeFpRf).map(_._1)
167 168 169 170 171 172 173 174
  fpArbiter.io.in.zip(fpWriteback).foreach{ case (arb, wb) =>
    arb.valid := wb.valid && wb.bits.uop.ctrl.fpWen
    arb.bits := wb.bits
    when (arb.valid) {
      wb.ready := arb.ready
    }
  }

L
ljw 已提交
175 176
  io.l1plus_error <> l1pluscache.io.error
  io.icache_error <> frontend.io.error
177 178
  io.dcache_error <> memBlock.io.error

179
  frontend.io.backend <> ctrlBlock.io.frontend
Y
Yinan Xu 已提交
180 181
  frontend.io.sfence <> integerBlock.io.fenceio.sfence
  frontend.io.tlbCsr <> integerBlock.io.csrio.tlb
182
  frontend.io.csrCtrl <> integerBlock.io.csrio.customCtrl
J
jinyue110 已提交
183

L
Lingrui98 已提交
184 185 186 187
  frontend.io.icacheMemAcq <> l1pluscache.io.req
  l1pluscache.io.resp <> frontend.io.icacheMemGrant
  l1pluscache.io.flush := frontend.io.l1plusFlush
  frontend.io.fencei := integerBlock.io.fenceio.fencei
188

189
  ctrlBlock.io.csrCtrl <> integerBlock.io.csrio.customCtrl
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
  ctrlBlock.io.exuRedirect <> integerBlock.io.exuRedirect
  ctrlBlock.io.stIn <> memBlock.io.stIn
  ctrlBlock.io.stOut <> memBlock.io.stOut
  ctrlBlock.io.memoryViolation <> memBlock.io.memoryViolation
  ctrlBlock.io.enqLsq <> memBlock.io.enqLsq
  // TODO
  ctrlBlock.io.writeback <> VecInit(intArbiter.io.out ++ fpArbiter.io.out)

  scheduler.io.redirect <> ctrlBlock.io.redirect
  scheduler.io.flush <> ctrlBlock.io.flush
  scheduler.io.allocate <> ctrlBlock.io.enqIQ
  scheduler.io.issue <> integerBlock.io.issue ++ floatBlock.io.issue ++ memBlock.io.issue
  // TODO arbiter
  scheduler.io.writeback <> VecInit(intArbiter.io.out ++ fpArbiter.io.out)

  scheduler.io.replay <> memBlock.io.replay
  scheduler.io.rsIdx <> memBlock.io.rsIdx
  scheduler.io.isFirstIssue <> memBlock.io.isFirstIssue
  scheduler.io.stData <> memBlock.io.stData
  scheduler.io.otherFastWakeup <> memBlock.io.otherFastWakeup
  scheduler.io.jumpPc <> ctrlBlock.io.jumpPc
  scheduler.io.jalr_target <> ctrlBlock.io.jalr_target
  scheduler.io.stIssuePtr <> memBlock.io.stIssuePtr
  scheduler.io.debug_fp_rat <> ctrlBlock.io.debug_fp_rat
  scheduler.io.debug_int_rat <> ctrlBlock.io.debug_int_rat
  scheduler.io.readIntRf <> ctrlBlock.io.readIntRf
  scheduler.io.readFpRf <> ctrlBlock.io.readFpRf

  integerBlock.io.redirect <> ctrlBlock.io.redirect
  integerBlock.io.flush <> ctrlBlock.io.flush
220
  integerBlock.io.csrio.hartId <> io.hartId
221 222
  integerBlock.io.csrio.perf <> DontCare
  integerBlock.io.csrio.perf.retiredInstr <> ctrlBlock.io.roqio.toCSR.perfinfo.retiredInstr
223 224 225 226
  integerBlock.io.csrio.perf.ctrlInfo <> ctrlBlock.io.perfInfo.ctrlInfo
  integerBlock.io.csrio.perf.memInfo <> memBlock.io.memInfo
  integerBlock.io.csrio.perf.frontendInfo <> frontend.io.frontendInfo

227 228 229 230
  integerBlock.io.csrio.fpu.fflags <> ctrlBlock.io.roqio.toCSR.fflags
  integerBlock.io.csrio.fpu.isIllegal := false.B
  integerBlock.io.csrio.fpu.dirty_fs <> ctrlBlock.io.roqio.toCSR.dirty_fs
  integerBlock.io.csrio.fpu.frm <> floatBlock.io.frm
Y
Yinan Xu 已提交
231
  integerBlock.io.csrio.exception <> ctrlBlock.io.roqio.exception
L
LinJiawei 已提交
232
  integerBlock.io.csrio.isXRet <> ctrlBlock.io.roqio.toCSR.isXRet
233
  integerBlock.io.csrio.trapTarget <> ctrlBlock.io.roqio.toCSR.trapTarget
Y
Yinan Xu 已提交
234
  integerBlock.io.csrio.interrupt <> ctrlBlock.io.roqio.toCSR.intrBitSet
Y
Yinan Xu 已提交
235 236
  integerBlock.io.csrio.memExceptionVAddr <> memBlock.io.lsqio.exceptionAddr.vaddr
  integerBlock.io.csrio.externalInterrupt <> io.externalInterrupt
237

238 239 240
  floatBlock.io.redirect <> ctrlBlock.io.redirect
  floatBlock.io.flush <> ctrlBlock.io.flush

Y
Yinan Xu 已提交
241 242 243
  integerBlock.io.fenceio.sfence <> memBlock.io.sfence
  integerBlock.io.fenceio.sbuffer <> memBlock.io.fenceToSbuffer

244 245
  memBlock.io.redirect <> ctrlBlock.io.redirect
  memBlock.io.flush <> ctrlBlock.io.flush
246
  memBlock.io.csrCtrl <> integerBlock.io.csrio.customCtrl
247
  memBlock.io.tlbCsr <> integerBlock.io.csrio.tlb
248
  memBlock.io.lsqio.roq <> ctrlBlock.io.roqio.lsq
249 250 251
  memBlock.io.lsqio.exceptionAddr.lsIdx.lqIdx := ctrlBlock.io.roqio.exception.bits.uop.lqIdx
  memBlock.io.lsqio.exceptionAddr.lsIdx.sqIdx := ctrlBlock.io.roqio.exception.bits.uop.sqIdx
  memBlock.io.lsqio.exceptionAddr.isStore := CommitType.lsInstIsStore(ctrlBlock.io.roqio.exception.bits.uop.ctrl.commitType)
252

253
  val itlbRepeater = Module(new PTWRepeater())
254 255 256 257 258
  val dtlbRepeater = if (usePTWRepeater) {
    Module(new PTWRepeater(LoadPipelineWidth + StorePipelineWidth))
  } else {
    Module(new PTWFilter(LoadPipelineWidth + StorePipelineWidth, PtwMissQueueSize))
  }
259 260 261 262
  itlbRepeater.io.tlb <> frontend.io.ptw
  dtlbRepeater.io.tlb <> memBlock.io.ptw
  itlbRepeater.io.sfence <> integerBlock.io.fenceio.sfence
  dtlbRepeater.io.sfence <> integerBlock.io.fenceio.sfence
263 264
  ptw.io.tlb(0) <> itlbRepeater.io.ptw
  ptw.io.tlb(1) <> dtlbRepeater.io.ptw
Y
Yinan Xu 已提交
265
  ptw.io.sfence <> integerBlock.io.fenceio.sfence
266
  ptw.io.csr <> integerBlock.io.csrio.tlb
267

268 269
  // if l2 prefetcher use stream prefetch, it should be placed in XSCore
  assert(l2PrefetcherParameters._type == "bop")
270
  io.l2_pf_enable := integerBlock.io.csrio.customCtrl.l2_pf_enable
271

272
  val l1plus_reset_gen = Module(new ResetGen(1, !debugOpts.FPGAPlatform))
273 274
  l1pluscache.reset := l1plus_reset_gen.io.out

275
  val ptw_reset_gen = Module(new ResetGen(2, !debugOpts.FPGAPlatform))
276 277 278 279
  ptw.reset := ptw_reset_gen.io.out
  itlbRepeater.reset := ptw_reset_gen.io.out
  dtlbRepeater.reset := ptw_reset_gen.io.out

280
  val memBlock_reset_gen = Module(new ResetGen(3, !debugOpts.FPGAPlatform))
281 282
  memBlock.reset := memBlock_reset_gen.io.out

283
  val intBlock_reset_gen = Module(new ResetGen(4, !debugOpts.FPGAPlatform))
284 285
  integerBlock.reset := intBlock_reset_gen.io.out

286
  val fpBlock_reset_gen = Module(new ResetGen(5, !debugOpts.FPGAPlatform))
287 288
  floatBlock.reset := fpBlock_reset_gen.io.out

289
  val ctrlBlock_reset_gen = Module(new ResetGen(6, !debugOpts.FPGAPlatform))
290 291
  ctrlBlock.reset := ctrlBlock_reset_gen.io.out

292
  val frontend_reset_gen = Module(new ResetGen(7, !debugOpts.FPGAPlatform))
293
  frontend.reset := frontend_reset_gen.io.out
L
LinJiawei 已提交
294
}