xref: /XiangShan/src/main/scala/xiangshan/XSCore.scala (revision 398001c43b2c2cf0935ac22384a45e5d458d799d)
1package xiangshan
2
3import chisel3._
4import chisel3.util._
5import bus.simplebus._
6import noop.{Cache, CacheConfig, HasExceptionNO, TLB, TLBConfig}
7import xiangshan.backend._
8import xiangshan.backend.dispatch.DP1Parameters
9import xiangshan.backend.exu.ExuParameters
10import xiangshan.frontend._
11import xiangshan.mem._
12import utils._
13
14trait HasXSParameter {
15  val XLEN = 64
16  val HasMExtension = true
17  val HasCExtension = true
18  val HasDiv = true
19  val HasIcache = true
20  val HasDcache = true
21  val EnableStoreQueue = false
22  val AddrBits = 64 // AddrBits is used in some cases
23  val VAddrBits = 39 // VAddrBits is Virtual Memory addr bits
24  val PAddrBits = 32 // PAddrBits is Phyical Memory addr bits
25  val AddrBytes = AddrBits / 8 // unused
26  val DataBits = XLEN
27  val DataBytes = DataBits / 8
28  val CacheLineSize = 512
29  val SbufferSize = 16
30  val HasFPU = true
31  val FetchWidth = 8
32  val PredictWidth = FetchWidth * 2
33  val EnableBPU = true
34  val EnableBPD = false // enable backing predictor(like Tage) in BPUStage3
35  val HistoryLength = 64
36  val BtbSize = 256
37  // val BtbWays = 4
38  val BtbBanks = PredictWidth
39  // val BtbSets = BtbSize / BtbWays
40  val JbtacSize = 1024
41  val JbtacBanks = 8
42  val RasSize = 16
43  val IBufSize = 64
44  val DecodeWidth = 6
45  val RenameWidth = 6
46  val CommitWidth = 6
47  val BrqSize = 16
48  val IssQueSize = 8
49  val BrTagWidth = log2Up(BrqSize)
50  val NRPhyRegs = 128
51  val PhyRegIdxWidth = log2Up(NRPhyRegs)
52  val NRReadPorts = 14
53  val NRWritePorts = 8
54  val RoqSize = 32
55  val MoqSize = 16 // 64
56  val InnerRoqIdxWidth = log2Up(RoqSize)
57  val RoqIdxWidth = InnerRoqIdxWidth + 1
58  val InnerMoqIdxWidth = log2Up(MoqSize)
59  val MoqIdxWidth = InnerMoqIdxWidth + 1
60  val IntDqDeqWidth = 4
61  val FpDqDeqWidth = 4
62  val LsDqDeqWidth = 4
63  val dp1Paremeters = DP1Parameters(
64    IntDqSize = 16,
65    FpDqSize = 16,
66    LsDqSize = 16
67  )
68  val exuParameters = ExuParameters(
69    JmpCnt = 1,
70    AluCnt = 4,
71    MulCnt = 1,
72    MduCnt = 1,
73    FmacCnt = 0,
74    FmiscCnt = 0,
75    FmiscDivSqrtCnt = 0,
76    LduCnt = 0,
77    StuCnt = 1
78  )
79}
80
81trait HasXSLog { this: Module =>
82  implicit val moduleName: String = this.name
83}
84
85abstract class XSModule extends Module
86  with HasXSParameter
87  with HasExceptionNO
88  with HasXSLog
89
90//remove this trait after impl module logic
91trait NeedImpl { this: Module =>
92  override protected def IO[T <: Data](iodef: T): T = {
93    val io = chisel3.experimental.IO(iodef)
94    io <> DontCare
95    io
96  }
97}
98
99abstract class XSBundle extends Bundle
100  with HasXSParameter
101  with HasTageParameter
102
103case class XSConfig
104(
105  FPGAPlatform: Boolean = true,
106  EnableDebug: Boolean = true
107)
108
109object AddressSpace extends HasXSParameter {
110  // (start, size)
111  // address out of MMIO will be considered as DRAM
112  def mmio = List(
113    (0x30000000L, 0x10000000L),  // internal devices, such as CLINT and PLIC
114    (0x40000000L, 0x40000000L) // external devices
115  )
116
117  def isMMIO(addr: UInt): Bool = mmio.map(range => {
118    require(isPow2(range._2))
119    val bits = log2Up(range._2)
120    (addr ^ range._1.U)(PAddrBits-1, bits) === 0.U
121  }).reduce(_ || _)
122}
123
124
125class XSCore(implicit p: XSConfig) extends XSModule {
126  val io = IO(new Bundle {
127    val imem = new SimpleBusC
128    val dmem = new SimpleBusC
129    val mmio = new SimpleBusUC
130    val frontend = Flipped(new SimpleBusUC())
131  })
132
133  io.imem <> DontCare
134
135  val dmemXbar = Module(new SimpleBusCrossbarNto1(3))
136
137  val front = Module(new Frontend)
138  val backend = Module(new Backend)
139  val mem = Module(new MemPipeline)
140
141  mem.io := DontCare // FIXME
142
143  front.io.backend <> backend.io.frontend
144
145  backend.io.memMMU.imem <> DontCare
146
147  val dtlb = TLB(
148    in = backend.io.dmem,
149    mem = dmemXbar.io.in(1),
150    flush = false.B,
151    csrMMU = backend.io.memMMU.dmem
152  )(TLBConfig(name = "dtlb", totalEntry = 64))
153  dmemXbar.io.in(0) <> dtlb.io.out
154  dmemXbar.io.in(2) <> io.frontend
155
156  io.dmem <> Cache(
157    in = dmemXbar.io.out,
158    mmio = Seq(io.mmio),
159    flush = "b00".U,
160    empty = dtlb.io.cacheEmpty,
161    enable = HasDcache
162  )(CacheConfig(name = "dcache"))
163
164  XSDebug("(req valid, ready | resp valid, ready) \n")
165  XSDebug("c-mem(%x %x %x| %x %x) c-coh(%x %x %x| %x %x) cache (%x %x %x| %x %x) tlb (%x %x %x| %x %x)\n",
166    io.dmem.mem.req.valid,
167    io.dmem.mem.req.ready,
168    io.dmem.mem.req.bits.addr,
169    io.dmem.mem.resp.valid,
170    io.dmem.mem.resp.ready,
171    io.dmem.coh.req.valid,
172    io.dmem.coh.req.ready,
173    io.dmem.coh.req.bits.addr,
174    io.dmem.coh.resp.valid,
175    io.dmem.coh.resp.ready,
176    dmemXbar.io.out.req.valid,
177    dmemXbar.io.out.req.ready,
178    dmemXbar.io.out.req.bits.addr,
179    dmemXbar.io.out.resp.valid,
180    dmemXbar.io.out.resp.ready,
181    backend.io.dmem.req.valid,
182    backend.io.dmem.req.ready,
183    backend.io.dmem.req.bits.addr,
184    backend.io.dmem.resp.valid,
185    backend.io.dmem.resp.ready
186  )
187}
188