xref: /XiangShan/src/main/scala/xiangshan/Parameters.scala (revision cc4fb544f95de5754d971801930fd5e3a32ddc6e)
1c6d43980SLemover/***************************************************************************************
2c6d43980SLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3f320e0f0SYinan Xu* Copyright (c) 2020-2021 Peng Cheng Laboratory
4c6d43980SLemover*
5c6d43980SLemover* XiangShan is licensed under Mulan PSL v2.
6c6d43980SLemover* You can use this software according to the terms and conditions of the Mulan PSL v2.
7c6d43980SLemover* You may obtain a copy of Mulan PSL v2 at:
8c6d43980SLemover*          http://license.coscl.org.cn/MulanPSL2
9c6d43980SLemover*
10c6d43980SLemover* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11c6d43980SLemover* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12c6d43980SLemover* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13c6d43980SLemover*
14c6d43980SLemover* See the Mulan PSL v2 for more details.
15c6d43980SLemover***************************************************************************************/
16c6d43980SLemover
172225d46eSJiawei Linpackage xiangshan
182225d46eSJiawei Lin
192225d46eSJiawei Linimport chipsalliance.rocketchip.config.{Field, Parameters}
202225d46eSJiawei Linimport chisel3._
212225d46eSJiawei Linimport chisel3.util._
2298c71602SJiawei Linimport huancun._
233b739f49SXuan Huimport system.SoCParamsKey
24730cfbc0SXuan Huimport xiangshan.backend.datapath.RdConfig._
25730cfbc0SXuan Huimport xiangshan.backend.datapath.WbConfig._
263b739f49SXuan Huimport xiangshan.backend.dispatch.DispatchParameters
27730cfbc0SXuan Huimport xiangshan.backend.exu.ExeUnitParams
28730cfbc0SXuan Huimport xiangshan.backend.fu.FuConfig._
29730cfbc0SXuan Huimport xiangshan.backend.issue.{IntScheduler, IssueBlockParams, MemScheduler, SchdBlockParams, SchedulerType, VfScheduler}
30730cfbc0SXuan Huimport xiangshan.backend.regfile.{IntPregParams, PregParams, VfPregParams}
31730cfbc0SXuan Huimport xiangshan.backend.BackendParams
323b739f49SXuan Huimport xiangshan.cache.DCacheParameters
33a1ea7f76SJiawei Linimport xiangshan.cache.prefetch._
34a1ea7f76SJiawei Linimport xiangshan.frontend.{BasePredictor, BranchPredictionResp, FTB, FakePredictor, RAS, Tage, ITTage, Tage_SC, FauFTB}
3560f966c8SGuokai Chenimport xiangshan.frontend.icache.ICacheParameters
363b739f49SXuan Huimport xiangshan.cache.mmu.{L2TLBParameters, TLBParameters}
373b739f49SXuan Huimport xiangshan.frontend._
383b739f49SXuan Huimport xiangshan.frontend.icache.ICacheParameters
393b739f49SXuan Hu
40d4aca96cSlqreimport freechips.rocketchip.diplomacy.AddressSet
412f30d658SYinan Xuimport system.SoCParamsKey
4298c71602SJiawei Linimport huancun._
4398c71602SJiawei Linimport huancun.debug._
4415ee59e4Swakafaimport coupledL2._
45289fc2f9SLinJiaweiimport xiangshan.mem.prefetch.{PrefetcherParams, SMSParams}
46289fc2f9SLinJiawei
47dd6c0695SLingrui98import scala.math.min
4834ab1ae9SJiawei Lin
4934ab1ae9SJiawei Lincase object XSTileKey extends Field[Seq[XSCoreParameters]]
5034ab1ae9SJiawei Lin
512225d46eSJiawei Lincase object XSCoreParamsKey extends Field[XSCoreParameters]
522225d46eSJiawei Lin
532225d46eSJiawei Lincase class XSCoreParameters
542225d46eSJiawei Lin(
552225d46eSJiawei Lin  HasPrefetch: Boolean = false,
562225d46eSJiawei Lin  HartId: Int = 0,
572225d46eSJiawei Lin  XLEN: Int = 64,
58deb6421eSHaojin Tang  VLEN: Int = 128,
59a8db15d8Sfdy  ELEN: Int = 64,
602225d46eSJiawei Lin  HasMExtension: Boolean = true,
612225d46eSJiawei Lin  HasCExtension: Boolean = true,
622225d46eSJiawei Lin  HasDiv: Boolean = true,
632225d46eSJiawei Lin  HasICache: Boolean = true,
642225d46eSJiawei Lin  HasDCache: Boolean = true,
652225d46eSJiawei Lin  AddrBits: Int = 64,
662225d46eSJiawei Lin  VAddrBits: Int = 39,
672225d46eSJiawei Lin  HasFPU: Boolean = true,
6835d1557aSZiyue Zhang  HasVPU: Boolean = true,
69ad3ba452Szhanglinjuan  HasCustomCSRCacheOp: Boolean = true,
702225d46eSJiawei Lin  FetchWidth: Int = 8,
7145f497a4Shappy-lx  AsidLength: Int = 16,
722225d46eSJiawei Lin  EnableBPU: Boolean = true,
732225d46eSJiawei Lin  EnableBPD: Boolean = true,
742225d46eSJiawei Lin  EnableRAS: Boolean = true,
752225d46eSJiawei Lin  EnableLB: Boolean = false,
762225d46eSJiawei Lin  EnableLoop: Boolean = true,
77e0f3968cSzoujr  EnableSC: Boolean = true,
782225d46eSJiawei Lin  EnbaleTlbDebug: Boolean = false,
792225d46eSJiawei Lin  EnableJal: Boolean = false,
8011d0c81dSLingrui98  EnableFauFTB: Boolean = true,
81f2aabf0dSLingrui98  UbtbGHRLength: Int = 4,
82c7fabd05SSteve Gou  // HistoryLength: Int = 512,
832f7b35ceSLingrui98  EnableGHistDiff: Boolean = true,
84ab0200c8SEaston Man  EnableCommitGHistDiff: Boolean = true,
85edc18578SLingrui98  UbtbSize: Int = 256,
86b37e4b45SLingrui98  FtbSize: Int = 2048,
87ba4cf515SLingrui98  RasSize: Int = 32,
882225d46eSJiawei Lin  CacheLineSize: Int = 512,
89b37e4b45SLingrui98  FtbWays: Int = 4,
90dd6c0695SLingrui98  TageTableInfos: Seq[Tuple3[Int,Int,Int]] =
91dd6c0695SLingrui98  //       Sets  Hist   Tag
9251e26c03SLingrui98    // Seq(( 2048,    2,    8),
9351e26c03SLingrui98    //     ( 2048,    9,    8),
9451e26c03SLingrui98    //     ( 2048,   13,    8),
9551e26c03SLingrui98    //     ( 2048,   20,    8),
9651e26c03SLingrui98    //     ( 2048,   26,    8),
9751e26c03SLingrui98    //     ( 2048,   44,    8),
9851e26c03SLingrui98    //     ( 2048,   73,    8),
9951e26c03SLingrui98    //     ( 2048,  256,    8)),
10051e26c03SLingrui98    Seq(( 4096,    8,    8),
10151e26c03SLingrui98        ( 4096,   13,    8),
10251e26c03SLingrui98        ( 4096,   32,    8),
10351e26c03SLingrui98        ( 4096,  119,    8)),
104dd6c0695SLingrui98  ITTageTableInfos: Seq[Tuple3[Int,Int,Int]] =
105dd6c0695SLingrui98  //      Sets  Hist   Tag
10603c81005SLingrui98    Seq(( 256,    4,    9),
107527dc111SLingrui98        ( 256,    8,    9),
1083581d7d3SLingrui98        ( 512,   13,    9),
109527dc111SLingrui98        ( 512,   16,    9),
110f2aabf0dSLingrui98        ( 512,   32,    9)),
11182dc6ff8SLingrui98  SCNRows: Int = 512,
11282dc6ff8SLingrui98  SCNTables: Int = 4,
113dd6c0695SLingrui98  SCCtrBits: Int = 6,
11482dc6ff8SLingrui98  SCHistLens: Seq[Int] = Seq(0, 4, 10, 16),
115dd6c0695SLingrui98  numBr: Int = 2,
116bf358e08SLingrui98  branchPredictor: Function2[BranchPredictionResp, Parameters, Tuple2[Seq[BasePredictor], BranchPredictionResp]] =
117bf358e08SLingrui98    ((resp_in: BranchPredictionResp, p: Parameters) => {
11816a1cc4bSzoujr      val ftb = Module(new FTB()(p))
119c5e28a9aSLingrui98      val ubtb =Module(new FauFTB()(p))
1204813e060SLingrui98      // val bim = Module(new BIM()(p))
121bf358e08SLingrui98      val tage = Module(new Tage_SC()(p))
1224cd08aa8SLingrui98      val ras = Module(new RAS()(p))
12360f966c8SGuokai Chen      val ittage = Module(new ITTage()(p))
1244813e060SLingrui98      val preds = Seq(ubtb, tage, ftb, ittage, ras)
12516a1cc4bSzoujr      preds.map(_.io := DontCare)
12616a1cc4bSzoujr
12716a1cc4bSzoujr      // ubtb.io.resp_in(0)  := resp_in
12816a1cc4bSzoujr      // bim.io.resp_in(0)   := ubtb.io.resp
12916a1cc4bSzoujr      // btb.io.resp_in(0)   := bim.io.resp
13016a1cc4bSzoujr      // tage.io.resp_in(0)  := btb.io.resp
13116a1cc4bSzoujr      // loop.io.resp_in(0)  := tage.io.resp
1324813e060SLingrui98      ubtb.io.in.bits.resp_in(0) := resp_in
133c2d1ec7dSLingrui98      tage.io.in.bits.resp_in(0) := ubtb.io.out
134c2d1ec7dSLingrui98      ftb.io.in.bits.resp_in(0)  := tage.io.out
135c2d1ec7dSLingrui98      ittage.io.in.bits.resp_in(0)  := ftb.io.out
136c2d1ec7dSLingrui98      ras.io.in.bits.resp_in(0) := ittage.io.out
13716a1cc4bSzoujr
138c2d1ec7dSLingrui98      (preds, ras.io.out)
13916a1cc4bSzoujr    }),
1402225d46eSJiawei Lin  IBufSize: Int = 48,
1412225d46eSJiawei Lin  DecodeWidth: Int = 6,
1422225d46eSJiawei Lin  RenameWidth: Int = 6,
1432225d46eSJiawei Lin  CommitWidth: Int = 6,
14465df1368Sczw  MaxUopSize: Int = 65,
1455df4db2aSLingrui98  FtqSize: Int = 64,
1462225d46eSJiawei Lin  EnableLoadFastWakeUp: Boolean = true, // NOTE: not supported now, make it false
147a8db15d8Sfdy  IntLogicRegs: Int = 32,
148d91483a6Sfdy  FpLogicRegs: Int = 33,
149189ec863SzhanglyGit  VecLogicRegs: Int = 32 + 1 + 15, // 15: tmp, 1: vconfig
150189ec863SzhanglyGit  VCONFIG_IDX: Int = 32,
1517154d65eSYinan Xu  NRPhyRegs: Int = 192,
15273faecdcSXuan Hu  IntPhyRegs: Int = 192,
15373faecdcSXuan Hu  VfPhyRegs: Int = 192,
154e4f69d78Ssfencevma  VirtualLoadQueueSize: Int = 80,
155e4f69d78Ssfencevma  LoadQueueRARSize: Int = 80,
156e4f69d78Ssfencevma  LoadQueueRAWSize: Int = 64, // NOTE: make sure that LoadQueueRAWSize is power of 2.
157e4f69d78Ssfencevma  RollbackGroupSize: Int = 8,
158e4f69d78Ssfencevma  LoadQueueReplaySize: Int = 80,
159e4f69d78Ssfencevma  LoadUncacheBufferSize: Int = 20,
160e4f69d78Ssfencevma  LoadQueueNWriteBanks: Int = 8, // NOTE: make sure that LoadQueueRARSize/LoadQueueRAWSize is divided by LoadQueueNWriteBanks
1612b4e8253SYinan Xu  StoreQueueSize: Int = 64,
162e4f69d78Ssfencevma  StoreQueueNWriteBanks: Int = 8, // NOTE: make sure that StoreQueueSize is divided by StoreQueueNWriteBanks
163e4f69d78Ssfencevma  StoreQueueForwardWithMask: Boolean = true,
164cea88ff8SWilliam Wang  VlsQueueSize: Int = 8,
1657154d65eSYinan Xu  RobSize: Int = 256,
166a8db15d8Sfdy  RabSize: Int = 256,
1672225d46eSJiawei Lin  dpParams: DispatchParameters = DispatchParameters(
1682225d46eSJiawei Lin    IntDqSize = 16,
1692225d46eSJiawei Lin    FpDqSize = 16,
1702225d46eSJiawei Lin    LsDqSize = 16,
1713b739f49SXuan Hu    IntDqDeqWidth = 6,
1723b739f49SXuan Hu    FpDqDeqWidth = 6,
1733b739f49SXuan Hu    LsDqDeqWidth = 6,
1742225d46eSJiawei Lin  ),
1753b739f49SXuan Hu  intPreg: PregParams = IntPregParams(
17672d89280SXuan Hu    numEntries = 64,
1773b739f49SXuan Hu    numRead = 14,
1783b739f49SXuan Hu    numWrite = 8,
1792225d46eSJiawei Lin  ),
1803b739f49SXuan Hu  vfPreg: VfPregParams = VfPregParams(
18172d89280SXuan Hu    numEntries = 64,
1823b739f49SXuan Hu    numRead = 14,
1833b739f49SXuan Hu    numWrite = 8,
1843b739f49SXuan Hu  ),
185289fc2f9SLinJiawei  prefetcher: Option[PrefetcherParams] = Some(SMSParams()),
1862225d46eSJiawei Lin  LoadPipelineWidth: Int = 2,
1872225d46eSJiawei Lin  StorePipelineWidth: Int = 2,
188cea88ff8SWilliam Wang  VecMemSrcInWidth: Int = 2,
189cea88ff8SWilliam Wang  VecMemInstWbWidth: Int = 1,
190cea88ff8SWilliam Wang  VecMemDispatchWidth: Int = 1,
1912225d46eSJiawei Lin  StoreBufferSize: Int = 16,
19205f23f57SWilliam Wang  StoreBufferThreshold: Int = 7,
19346f74b57SHaojin Tang  EnsbufferWidth: Int = 2,
19437225120Ssfencevma  UncacheBufferSize: Int = 4,
195c837faaaSWilliam Wang  EnableLoadToLoadForward: Boolean = true,
196a98b054bSWilliam Wang  EnableFastForward: Boolean = false,
197beabc72dSWilliam Wang  EnableLdVioCheckAfterReset: Boolean = true,
198026615fcSWilliam Wang  EnableSoftPrefetchAfterReset: Boolean = true,
199026615fcSWilliam Wang  EnableCacheErrorAfterReset: Boolean = true,
200144422dcSMaxpicca-Li  EnableDCacheWPU: Boolean = false,
2016786cfb7SWilliam Wang  EnableAccurateLoadError: Boolean = true,
202e32bafbaSbugGenerator  EnableUncacheWriteOutstanding: Boolean = false,
20345f497a4Shappy-lx  MMUAsidLen: Int = 16, // max is 16, 0 is not supported now
20462dfd6c3Shappy-lx  ReSelectLen: Int = 7, // load replay queue replay select counter len
205a0301c0dSLemover  itlbParameters: TLBParameters = TLBParameters(
206a0301c0dSLemover    name = "itlb",
207a0301c0dSLemover    fetchi = true,
208a0301c0dSLemover    useDmode = false,
209fa086d5eSLemover    normalNWays = 32,
210a0301c0dSLemover    normalReplacer = Some("plru"),
211fa086d5eSLemover    superNWays = 4,
212f1fe8698SLemover    superReplacer = Some("plru")
213a0301c0dSLemover  ),
21434f9624dSguohongyu  itlbPortNum: Int = 2 + ICacheParameters().prefetchPipeNum + 1,
21534f9624dSguohongyu  ipmpPortNum: Int = 2 + ICacheParameters().prefetchPipeNum + 1,
216a0301c0dSLemover  ldtlbParameters: TLBParameters = TLBParameters(
217a0301c0dSLemover    name = "ldtlb",
21806082082SLemover    normalNSets = 64,
219a0301c0dSLemover    normalNWays = 1,
220a0301c0dSLemover    normalAssociative = "sa",
221a0301c0dSLemover    normalReplacer = Some("setplru"),
22206082082SLemover    superNWays = 16,
223a0301c0dSLemover    normalAsVictim = true,
22453b8f1a7SLemover    outReplace = false,
2255b7ef044SLemover    partialStaticPMP = true,
226f1fe8698SLemover    outsideRecvFlush = true,
2275cf62c1aSLemover    saveLevel = true
228a0301c0dSLemover  ),
229a0301c0dSLemover  sttlbParameters: TLBParameters = TLBParameters(
230a0301c0dSLemover    name = "sttlb",
23106082082SLemover    normalNSets = 64,
232a0301c0dSLemover    normalNWays = 1,
233a0301c0dSLemover    normalAssociative = "sa",
234a0301c0dSLemover    normalReplacer = Some("setplru"),
23506082082SLemover    superNWays = 16,
236a0301c0dSLemover    normalAsVictim = true,
23753b8f1a7SLemover    outReplace = false,
2385b7ef044SLemover    partialStaticPMP = true,
239f1fe8698SLemover    outsideRecvFlush = true,
2405cf62c1aSLemover    saveLevel = true
241a0301c0dSLemover  ),
242c8309e8aSHaoyuan Feng  pftlbParameters: TLBParameters = TLBParameters(
243c8309e8aSHaoyuan Feng    name = "pftlb",
244c8309e8aSHaoyuan Feng    normalNSets = 64,
245c8309e8aSHaoyuan Feng    normalNWays = 1,
246c8309e8aSHaoyuan Feng    normalAssociative = "sa",
247c8309e8aSHaoyuan Feng    normalReplacer = Some("setplru"),
248c8309e8aSHaoyuan Feng    superNWays = 16,
249c8309e8aSHaoyuan Feng    normalAsVictim = true,
250c8309e8aSHaoyuan Feng    outReplace = false,
251c8309e8aSHaoyuan Feng    partialStaticPMP = true,
252c8309e8aSHaoyuan Feng    outsideRecvFlush = true,
253c8309e8aSHaoyuan Feng    saveLevel = true
254c8309e8aSHaoyuan Feng  ),
255bf08468cSLemover  refillBothTlb: Boolean = false,
256a0301c0dSLemover  btlbParameters: TLBParameters = TLBParameters(
257a0301c0dSLemover    name = "btlb",
258a0301c0dSLemover    normalNSets = 1,
259a0301c0dSLemover    normalNWays = 64,
260a0301c0dSLemover    superNWays = 4,
261a0301c0dSLemover  ),
2625854c1edSLemover  l2tlbParameters: L2TLBParameters = L2TLBParameters(),
2632225d46eSJiawei Lin  NumPerfCounters: Int = 16,
26405f23f57SWilliam Wang  icacheParameters: ICacheParameters = ICacheParameters(
26505f23f57SWilliam Wang    tagECC = Some("parity"),
26605f23f57SWilliam Wang    dataECC = Some("parity"),
26705f23f57SWilliam Wang    replacer = Some("setplru"),
2681d8f4dcbSJay    nMissEntries = 2,
2697052722fSJay    nProbeEntries = 2,
270cb93f2f2Sguohongyu    nPrefetchEntries = 12,
271b1ded4e8Sguohongyu    nPrefBufferEntries = 64,
272a108d429SJay    hasPrefetch = true,
27305f23f57SWilliam Wang  ),
2744f94c0c6SJiawei Lin  dcacheParametersOpt: Option[DCacheParameters] = Some(DCacheParameters(
27505f23f57SWilliam Wang    tagECC = Some("secded"),
27605f23f57SWilliam Wang    dataECC = Some("secded"),
27705f23f57SWilliam Wang    replacer = Some("setplru"),
27805f23f57SWilliam Wang    nMissEntries = 16,
279300ded30SWilliam Wang    nProbeEntries = 8,
280300ded30SWilliam Wang    nReleaseEntries = 18
2814f94c0c6SJiawei Lin  )),
28215ee59e4Swakafa  L2CacheParamsOpt: Option[L2Param] = Some(L2Param(
283a1ea7f76SJiawei Lin    name = "l2",
284a1ea7f76SJiawei Lin    ways = 8,
285a1ea7f76SJiawei Lin    sets = 1024, // default 512KB L2
28615ee59e4Swakafa    prefetch = Some(coupledL2.prefetch.PrefetchReceiverParams())
2874f94c0c6SJiawei Lin  )),
288d5be5d19SJiawei Lin  L2NBanks: Int = 1,
289a1ea7f76SJiawei Lin  usePTWRepeater: Boolean = false,
290e0374b1cSHaoyuan Feng  softTLB: Boolean = false, // dpi-c l1tlb debug only
291e0374b1cSHaoyuan Feng  softPTW: Boolean = false, // dpi-c l2tlb debug only
2925afdf73cSHaoyuan Feng  softPTWDelay: Int = 1
2932225d46eSJiawei Lin){
294b52d4755SXuan Hu  def vlWidth = log2Up(VLEN) + 1
295b52d4755SXuan Hu
296c7fabd05SSteve Gou  val allHistLens = SCHistLens ++ ITTageTableInfos.map(_._2) ++ TageTableInfos.map(_._2) :+ UbtbGHRLength
297c7fabd05SSteve Gou  val HistoryLength = allHistLens.max + numBr * FtqSize + 9 // 256 for the predictor configs now
298c7fabd05SSteve Gou
2993b739f49SXuan Hu  def intSchdParams = {
3003b739f49SXuan Hu    implicit val schdType: SchedulerType = IntScheduler()
3013b739f49SXuan Hu    val pregBits = intPreg.addrWidth
3023b739f49SXuan Hu    val numRfRead = intPreg.numRead
3033b739f49SXuan Hu    val numRfWrite = intPreg.numWrite
3043b739f49SXuan Hu    SchdBlockParams(Seq(
3053b739f49SXuan Hu      IssueBlockParams(Seq(
306730cfbc0SXuan Hu        ExeUnitParams(Seq(AluCfg, MulCfg, BkuCfg), Seq(IntWB(port = 0, 0)), Seq(Seq(IntRD(0, 2)), Seq(IntRD(1, 2)))),
307730cfbc0SXuan Hu        ExeUnitParams(Seq(AluCfg, MulCfg, BkuCfg), Seq(IntWB(port = 1, 0)), Seq(Seq(IntRD(0, 1)), Seq(IntRD(1, 1)))),
3083b739f49SXuan Hu      ), numEntries = 8, pregBits = pregBits, numWakeupFromWB = numRfWrite, numEnq = 2),
3093b739f49SXuan Hu      IssueBlockParams(Seq(
310730cfbc0SXuan Hu        ExeUnitParams(Seq(DivCfg), Seq(IntWB(port = 2, 0)), Seq(Seq(IntRD(4, 0)), Seq(IntRD(5, 0)))),
311730cfbc0SXuan Hu        ExeUnitParams(Seq(DivCfg), Seq(IntWB(port = 3, 0)), Seq(Seq(IntRD(6, 0)), Seq(IntRD(7, 0)))),
3123b739f49SXuan Hu      ), numEntries = 8, pregBits = pregBits, numWakeupFromWB = numRfWrite, numEnq = 2),
3133b739f49SXuan Hu      IssueBlockParams(Seq(
314d91483a6Sfdy        ExeUnitParams(Seq(BrhCfg, JmpCfg, CsrCfg, FenceCfg), Seq(IntWB(port = 4, 0)), Seq(Seq(IntRD(2, 1)), Seq(IntRD(3, 1)))),
315d91483a6Sfdy        ExeUnitParams(Seq(BrhCfg), Seq(), Seq(Seq(IntRD(6, 1)), Seq(IntRD(4, 1)))),
3163b739f49SXuan Hu      ), numEntries = 8, pregBits = pregBits, numWakeupFromWB = numRfWrite, numEnq = 2),
3173b739f49SXuan Hu      IssueBlockParams(Seq(
318a8db15d8Sfdy        ExeUnitParams(Seq(I2fCfg, VSetRiWiCfg, VSetRiWvfCfg), Seq(VecWB(port = 6, Int.MaxValue), IntWB(port = 7, 0)), Seq(Seq(IntRD(6, 0)), Seq(IntRD(7, 0)))),
3193b739f49SXuan Hu      ), numEntries = 8, pregBits = pregBits, numWakeupFromWB = numRfWrite, numEnq = 2)
3203b739f49SXuan Hu    ),
3213b739f49SXuan Hu      numPregs = intPreg.numEntries,
3223b739f49SXuan Hu      numRfReadWrite = Some((numRfRead, numRfWrite)),
3233b739f49SXuan Hu      numDeqOutside = 0,
3243b739f49SXuan Hu      schdType = schdType,
3253b739f49SXuan Hu      rfDataWidth = intPreg.dataCfg.dataWidth,
3263b739f49SXuan Hu      numUopIn = dpParams.IntDqDeqWidth,
3273b739f49SXuan Hu    )
3283b739f49SXuan Hu  }
3293b739f49SXuan Hu  def vfSchdParams = {
3303b739f49SXuan Hu    implicit val schdType: SchedulerType = VfScheduler()
3313b739f49SXuan Hu    val pregBits = vfPreg.addrWidth
3323b739f49SXuan Hu    val numRfRead = vfPreg.numRead
3333b739f49SXuan Hu    val numRfWrite = vfPreg.numWrite
3343b739f49SXuan Hu    SchdBlockParams(Seq(
3353b739f49SXuan Hu      IssueBlockParams(Seq(
336e2e5f6b0SXuan Hu        ExeUnitParams(Seq(VialuCfg), Seq(VecWB(port = 0, 0)), Seq(Seq(VfRD(1, 0)), Seq(VfRD(2, 0)), Seq(VfRD(3, 0)), Seq(VfRD(4, 0)), Seq(VfRD(5, 0)))),
3372ee1e93dSXuan Hu        ExeUnitParams(Seq(VimacCfg), Seq(VecWB(port = 0, 0)), Seq(Seq(VfRD(1, 0)), Seq(VfRD(2, 0)), Seq(VfRD(3, 0)), Seq(VfRD(4, 0)), Seq(VfRD(5, 0)))),
33835d005dfSXuan Hu      ), numEntries = 8, pregBits = pregBits, numWakeupFromWB = numRfWrite, numEnq = 2),
3393b739f49SXuan Hu      IssueBlockParams(Seq(
34035d005dfSXuan Hu        ExeUnitParams(Seq(FmacCfg), Seq(VecWB(port = 1, 0)), Seq(Seq(VfRD(7, 0)), Seq(VfRD(8, 0)), Seq(VfRD(9, 0)))),
34135d005dfSXuan Hu        ExeUnitParams(Seq(F2fCfg, F2iCfg, FDivSqrtCfg, VSetRvfWvfCfg), Seq(VecWB(port = 2, 0), IntWB(port = 7, 0)), Seq(Seq(VfRD(10, 0)), Seq(VfRD(11, 0)))),
34235d005dfSXuan Hu      ), numEntries = 8, pregBits = pregBits, numWakeupFromWB = numRfWrite, numEnq = 2),
3433b739f49SXuan Hu    ),
3443b739f49SXuan Hu      numPregs = vfPreg.numEntries,
3453b739f49SXuan Hu      numRfReadWrite = Some((numRfRead, numRfWrite)),
3463b739f49SXuan Hu      numDeqOutside = 0,
3473b739f49SXuan Hu      schdType = schdType,
3483b739f49SXuan Hu      rfDataWidth = vfPreg.dataCfg.dataWidth,
3493b739f49SXuan Hu      numUopIn = dpParams.FpDqDeqWidth,
3503b739f49SXuan Hu    )
3513b739f49SXuan Hu  }
3523b739f49SXuan Hu  def memSchdParams = {
3533b739f49SXuan Hu    implicit val schdType: SchedulerType = MemScheduler()
3543b739f49SXuan Hu    val pregBits = vfPreg.addrWidth max intPreg.addrWidth
3553b739f49SXuan Hu    val rfDataWidth = 64
3562225d46eSJiawei Lin
3573b739f49SXuan Hu    SchdBlockParams(Seq(
3583b739f49SXuan Hu      IssueBlockParams(Seq(
359730cfbc0SXuan Hu        ExeUnitParams(Seq(LduCfg), Seq(IntWB(5, 0), VecWB(4, 0)), Seq(Seq(IntRD(8, 0)))),
360730cfbc0SXuan Hu        ExeUnitParams(Seq(LduCfg), Seq(IntWB(6, 0), VecWB(5, 0)), Seq(Seq(IntRD(9, 0)))),
361141a6449SXuan Hu      ), numEntries = 8, pregBits = pregBits, numWakeupFromWB = 16, numEnq = 2),
3623b739f49SXuan Hu      IssueBlockParams(Seq(
3637000dd3dSfdy        ExeUnitParams(Seq(StaCfg, MouCfg), Seq(IntWB(5, 1)), Seq(Seq(IntRD(10, 0)))),
3647000dd3dSfdy        ExeUnitParams(Seq(StaCfg, MouCfg), Seq(IntWB(6, 1)), Seq(Seq(IntRD(11, 0)))),
365141a6449SXuan Hu      ), numEntries = 8, pregBits = pregBits, numWakeupFromWB = 16, numEnq = 2),
3663b739f49SXuan Hu      IssueBlockParams(Seq(
3677000dd3dSfdy        ExeUnitParams(Seq(StdCfg, MoudCfg), Seq(), Seq(Seq(IntRD(12, 0), VfRD(12, 0)))),
3687000dd3dSfdy        ExeUnitParams(Seq(StdCfg, MoudCfg), Seq(), Seq(Seq(IntRD(13, 0), VfRD(13, 0)))),
369141a6449SXuan Hu      ), numEntries = 8, pregBits = pregBits, numWakeupFromWB = 16, numEnq = 2),
3704ee69032SzhanglyGit      IssueBlockParams(Seq(
3714ee69032SzhanglyGit        ExeUnitParams(Seq(VlduCfg), Seq(VecWB(6, 0)), Seq(Seq(VfRD(0, 0)), Seq(VfRD(1, 0)), Seq(VfRD(2, 0)), Seq(VfRD(3, 0)), Seq(VfRD(4, 0)))),
3724ee69032SzhanglyGit        ExeUnitParams(Seq(VlduCfg), Seq(VecWB(7, 0)), Seq(Seq(VfRD(5, 0)), Seq(VfRD(6, 0)), Seq(VfRD(7, 0)), Seq(VfRD(8, 0)), Seq(VfRD(9, 0)))),
3734ee69032SzhanglyGit      ), numEntries = 8, pregBits = pregBits, numWakeupFromWB = 16, numEnq = 2),
3743b739f49SXuan Hu    ),
375141a6449SXuan Hu      numPregs = intPreg.numEntries max vfPreg.numEntries,
3763b739f49SXuan Hu      numRfReadWrite = None,
3773b739f49SXuan Hu      numDeqOutside = 0,
3783b739f49SXuan Hu      schdType = schdType,
3793b739f49SXuan Hu      rfDataWidth = rfDataWidth,
3803b739f49SXuan Hu      numUopIn = dpParams.LsDqDeqWidth,
3813b739f49SXuan Hu    )
3823b739f49SXuan Hu  }
3832225d46eSJiawei Lin
384730cfbc0SXuan Hu  def backendParams: BackendParams = backend.BackendParams(Map(
3853b739f49SXuan Hu    IntScheduler() -> intSchdParams,
3863b739f49SXuan Hu    VfScheduler() -> vfSchdParams,
3873b739f49SXuan Hu    MemScheduler() -> memSchdParams,
3883b739f49SXuan Hu  ), Seq(
3893b739f49SXuan Hu    intPreg,
3903b739f49SXuan Hu    vfPreg,
3913b739f49SXuan Hu  ))
3922225d46eSJiawei Lin}
3932225d46eSJiawei Lin
3942225d46eSJiawei Lincase object DebugOptionsKey extends Field[DebugOptions]
3952225d46eSJiawei Lin
3962225d46eSJiawei Lincase class DebugOptions
3972225d46eSJiawei Lin(
3981545277aSYinan Xu  FPGAPlatform: Boolean = false,
3991545277aSYinan Xu  EnableDifftest: Boolean = false,
400cbe9a847SYinan Xu  AlwaysBasicDiff: Boolean = true,
4011545277aSYinan Xu  EnableDebug: Boolean = false,
4022225d46eSJiawei Lin  EnablePerfDebug: Boolean = true,
403eb163ef0SHaojin Tang  UseDRAMSim: Boolean = false,
404047e34f9SMaxpicca-Li  EnableConstantin: Boolean = false,
405eb163ef0SHaojin Tang  EnableTopDown: Boolean = false
4062225d46eSJiawei Lin)
4072225d46eSJiawei Lin
4082225d46eSJiawei Lintrait HasXSParameter {
4092225d46eSJiawei Lin
4102225d46eSJiawei Lin  implicit val p: Parameters
4112225d46eSJiawei Lin
4122f30d658SYinan Xu  val PAddrBits = p(SoCParamsKey).PAddrBits // PAddrBits is Phyical Memory addr bits
4132f30d658SYinan Xu
4142225d46eSJiawei Lin  val coreParams = p(XSCoreParamsKey)
4152225d46eSJiawei Lin  val env = p(DebugOptionsKey)
4162225d46eSJiawei Lin
4172225d46eSJiawei Lin  val XLEN = coreParams.XLEN
418deb6421eSHaojin Tang  val VLEN = coreParams.VLEN
419a8db15d8Sfdy  val ELEN = coreParams.ELEN
4202225d46eSJiawei Lin  val minFLen = 32
4212225d46eSJiawei Lin  val fLen = 64
4222225d46eSJiawei Lin  def xLen = XLEN
4232225d46eSJiawei Lin
4242225d46eSJiawei Lin  val HasMExtension = coreParams.HasMExtension
4252225d46eSJiawei Lin  val HasCExtension = coreParams.HasCExtension
4262225d46eSJiawei Lin  val HasDiv = coreParams.HasDiv
4272225d46eSJiawei Lin  val HasIcache = coreParams.HasICache
4282225d46eSJiawei Lin  val HasDcache = coreParams.HasDCache
4292225d46eSJiawei Lin  val AddrBits = coreParams.AddrBits // AddrBits is used in some cases
4302225d46eSJiawei Lin  val VAddrBits = coreParams.VAddrBits // VAddrBits is Virtual Memory addr bits
43145f497a4Shappy-lx  val AsidLength = coreParams.AsidLength
432a760aeb0Shappy-lx  val ReSelectLen = coreParams.ReSelectLen
4332225d46eSJiawei Lin  val AddrBytes = AddrBits / 8 // unused
4342225d46eSJiawei Lin  val DataBits = XLEN
4352225d46eSJiawei Lin  val DataBytes = DataBits / 8
4362225d46eSJiawei Lin  val HasFPU = coreParams.HasFPU
4370ba52110SZiyue Zhang  val HasVPU = coreParams.HasVPU
438ad3ba452Szhanglinjuan  val HasCustomCSRCacheOp = coreParams.HasCustomCSRCacheOp
4392225d46eSJiawei Lin  val FetchWidth = coreParams.FetchWidth
4402225d46eSJiawei Lin  val PredictWidth = FetchWidth * (if (HasCExtension) 2 else 1)
4412225d46eSJiawei Lin  val EnableBPU = coreParams.EnableBPU
4422225d46eSJiawei Lin  val EnableBPD = coreParams.EnableBPD // enable backing predictor(like Tage) in BPUStage3
4432225d46eSJiawei Lin  val EnableRAS = coreParams.EnableRAS
4442225d46eSJiawei Lin  val EnableLB = coreParams.EnableLB
4452225d46eSJiawei Lin  val EnableLoop = coreParams.EnableLoop
4462225d46eSJiawei Lin  val EnableSC = coreParams.EnableSC
4472225d46eSJiawei Lin  val EnbaleTlbDebug = coreParams.EnbaleTlbDebug
4482225d46eSJiawei Lin  val HistoryLength = coreParams.HistoryLength
44986d9c530SLingrui98  val EnableGHistDiff = coreParams.EnableGHistDiff
450ab0200c8SEaston Man  val EnableCommitGHistDiff = coreParams.EnableCommitGHistDiff
451f2aabf0dSLingrui98  val UbtbGHRLength = coreParams.UbtbGHRLength
452b37e4b45SLingrui98  val UbtbSize = coreParams.UbtbSize
45311d0c81dSLingrui98  val EnableFauFTB = coreParams.EnableFauFTB
454b37e4b45SLingrui98  val FtbSize = coreParams.FtbSize
455b37e4b45SLingrui98  val FtbWays = coreParams.FtbWays
4562225d46eSJiawei Lin  val RasSize = coreParams.RasSize
45716a1cc4bSzoujr
458bf358e08SLingrui98  def getBPDComponents(resp_in: BranchPredictionResp, p: Parameters) = {
459bf358e08SLingrui98    coreParams.branchPredictor(resp_in, p)
46016a1cc4bSzoujr  }
461dd6c0695SLingrui98  val numBr = coreParams.numBr
462dd6c0695SLingrui98  val TageTableInfos = coreParams.TageTableInfos
463cb4f77ceSLingrui98  val TageBanks = coreParams.numBr
464dd6c0695SLingrui98  val SCNRows = coreParams.SCNRows
465dd6c0695SLingrui98  val SCCtrBits = coreParams.SCCtrBits
46634ed6fbcSLingrui98  val SCHistLens = coreParams.SCHistLens
46734ed6fbcSLingrui98  val SCNTables = coreParams.SCNTables
468dd6c0695SLingrui98
46934ed6fbcSLingrui98  val SCTableInfos = Seq.fill(SCNTables)((SCNRows, SCCtrBits)) zip SCHistLens map {
47034ed6fbcSLingrui98    case ((n, cb), h) => (n, cb, h)
471dd6c0695SLingrui98  }
472dd6c0695SLingrui98  val ITTageTableInfos = coreParams.ITTageTableInfos
473dd6c0695SLingrui98  type FoldedHistoryInfo = Tuple2[Int, Int]
474dd6c0695SLingrui98  val foldedGHistInfos =
4754813e060SLingrui98    (TageTableInfos.map{ case (nRows, h, t) =>
476dd6c0695SLingrui98      if (h > 0)
4774813e060SLingrui98        Set((h, min(log2Ceil(nRows/numBr), h)), (h, min(h, t)), (h, min(h, t-1)))
478dd6c0695SLingrui98      else
479dd6c0695SLingrui98        Set[FoldedHistoryInfo]()
4804813e060SLingrui98    }.reduce(_++_).toSet ++
48134ed6fbcSLingrui98    SCTableInfos.map{ case (nRows, _, h) =>
482dd6c0695SLingrui98      if (h > 0)
483e992912cSLingrui98        Set((h, min(log2Ceil(nRows/TageBanks), h)))
484dd6c0695SLingrui98      else
485dd6c0695SLingrui98        Set[FoldedHistoryInfo]()
48634ed6fbcSLingrui98    }.reduce(_++_).toSet ++
487dd6c0695SLingrui98    ITTageTableInfos.map{ case (nRows, h, t) =>
488dd6c0695SLingrui98      if (h > 0)
489dd6c0695SLingrui98        Set((h, min(log2Ceil(nRows), h)), (h, min(h, t)), (h, min(h, t-1)))
490dd6c0695SLingrui98      else
491dd6c0695SLingrui98        Set[FoldedHistoryInfo]()
492527dc111SLingrui98    }.reduce(_++_) ++
493527dc111SLingrui98      Set[FoldedHistoryInfo]((UbtbGHRLength, log2Ceil(UbtbSize)))
494527dc111SLingrui98    ).toList
49516a1cc4bSzoujr
496c7fabd05SSteve Gou
497c7fabd05SSteve Gou
4982225d46eSJiawei Lin  val CacheLineSize = coreParams.CacheLineSize
4992225d46eSJiawei Lin  val CacheLineHalfWord = CacheLineSize / 16
5002225d46eSJiawei Lin  val ExtHistoryLength = HistoryLength + 64
5012225d46eSJiawei Lin  val IBufSize = coreParams.IBufSize
5022225d46eSJiawei Lin  val DecodeWidth = coreParams.DecodeWidth
5032225d46eSJiawei Lin  val RenameWidth = coreParams.RenameWidth
5042225d46eSJiawei Lin  val CommitWidth = coreParams.CommitWidth
505d91483a6Sfdy  val MaxUopSize = coreParams.MaxUopSize
5062225d46eSJiawei Lin  val FtqSize = coreParams.FtqSize
5072225d46eSJiawei Lin  val EnableLoadFastWakeUp = coreParams.EnableLoadFastWakeUp
508d91483a6Sfdy  val IntLogicRegs = coreParams.IntLogicRegs
509d91483a6Sfdy  val FpLogicRegs = coreParams.FpLogicRegs
510d91483a6Sfdy  val VecLogicRegs = coreParams.VecLogicRegs
511fe60541bSXuan Hu  val VCONFIG_IDX = coreParams.VCONFIG_IDX
5122225d46eSJiawei Lin  val NRPhyRegs = coreParams.NRPhyRegs
5132225d46eSJiawei Lin  val PhyRegIdxWidth = log2Up(NRPhyRegs)
51473faecdcSXuan Hu  val IntPhyRegs = coreParams.IntPhyRegs
51573faecdcSXuan Hu  val VfPhyRegs = coreParams.VfPhyRegs
51673faecdcSXuan Hu  val IntPregIdxWidth = log2Up(IntPhyRegs)
51773faecdcSXuan Hu  val VfPregIdxWidth = log2Up(VfPhyRegs)
5189aca92b9SYinan Xu  val RobSize = coreParams.RobSize
519a8db15d8Sfdy  val RabSize = coreParams.RabSize
52070224bf6SYinan Xu  val IntRefCounterWidth = log2Ceil(RobSize)
521e4f69d78Ssfencevma  val VirtualLoadQueueSize = coreParams.VirtualLoadQueueSize
522e4f69d78Ssfencevma  val LoadQueueRARSize = coreParams.LoadQueueRARSize
523e4f69d78Ssfencevma  val LoadQueueRAWSize = coreParams.LoadQueueRAWSize
524e4f69d78Ssfencevma  val RollbackGroupSize = coreParams.RollbackGroupSize
525e4f69d78Ssfencevma  val LoadQueueReplaySize = coreParams.LoadQueueReplaySize
526e4f69d78Ssfencevma  val LoadUncacheBufferSize = coreParams.LoadUncacheBufferSize
5270a992150SWilliam Wang  val LoadQueueNWriteBanks = coreParams.LoadQueueNWriteBanks
5282225d46eSJiawei Lin  val StoreQueueSize = coreParams.StoreQueueSize
5290a992150SWilliam Wang  val StoreQueueNWriteBanks = coreParams.StoreQueueNWriteBanks
530e4f69d78Ssfencevma  val StoreQueueForwardWithMask = coreParams.StoreQueueForwardWithMask
531cea88ff8SWilliam Wang  val VlsQueueSize = coreParams.VlsQueueSize
5322225d46eSJiawei Lin  val dpParams = coreParams.dpParams
5333b739f49SXuan Hu
5343b739f49SXuan Hu  def backendParams: BackendParams = coreParams.backendParams
535351e22f2SXuan Hu  def MemIQSizeMax = backendParams.memSchdParams.get.issueBlockParams.map(_.numEntries).max
536351e22f2SXuan Hu  def IQSizeMax = backendParams.allSchdParams.map(_.issueBlockParams.map(_.numEntries).max).max
5372225d46eSJiawei Lin  val LoadPipelineWidth = coreParams.LoadPipelineWidth
5382225d46eSJiawei Lin  val StorePipelineWidth = coreParams.StorePipelineWidth
539cea88ff8SWilliam Wang  val VecMemSrcInWidth = coreParams.VecMemSrcInWidth
540cea88ff8SWilliam Wang  val VecMemInstWbWidth = coreParams.VecMemInstWbWidth
541cea88ff8SWilliam Wang  val VecMemDispatchWidth = coreParams.VecMemDispatchWidth
5422225d46eSJiawei Lin  val StoreBufferSize = coreParams.StoreBufferSize
54305f23f57SWilliam Wang  val StoreBufferThreshold = coreParams.StoreBufferThreshold
54446f74b57SHaojin Tang  val EnsbufferWidth = coreParams.EnsbufferWidth
54537225120Ssfencevma  val UncacheBufferSize = coreParams.UncacheBufferSize
54664886eefSWilliam Wang  val EnableLoadToLoadForward = coreParams.EnableLoadToLoadForward
5473db2cf75SWilliam Wang  val EnableFastForward = coreParams.EnableFastForward
54867682d05SWilliam Wang  val EnableLdVioCheckAfterReset = coreParams.EnableLdVioCheckAfterReset
549026615fcSWilliam Wang  val EnableSoftPrefetchAfterReset = coreParams.EnableSoftPrefetchAfterReset
550026615fcSWilliam Wang  val EnableCacheErrorAfterReset = coreParams.EnableCacheErrorAfterReset
551144422dcSMaxpicca-Li  val EnableDCacheWPU = coreParams.EnableDCacheWPU
5526786cfb7SWilliam Wang  val EnableAccurateLoadError = coreParams.EnableAccurateLoadError
55337225120Ssfencevma  val EnableUncacheWriteOutstanding = coreParams.EnableUncacheWriteOutstanding
55445f497a4Shappy-lx  val asidLen = coreParams.MMUAsidLen
555a0301c0dSLemover  val BTLBWidth = coreParams.LoadPipelineWidth + coreParams.StorePipelineWidth
556bf08468cSLemover  val refillBothTlb = coreParams.refillBothTlb
557a0301c0dSLemover  val itlbParams = coreParams.itlbParameters
558a0301c0dSLemover  val ldtlbParams = coreParams.ldtlbParameters
559a0301c0dSLemover  val sttlbParams = coreParams.sttlbParameters
560c8309e8aSHaoyuan Feng  val pftlbParams = coreParams.pftlbParameters
561a0301c0dSLemover  val btlbParams = coreParams.btlbParameters
5625854c1edSLemover  val l2tlbParams = coreParams.l2tlbParameters
5632225d46eSJiawei Lin  val NumPerfCounters = coreParams.NumPerfCounters
5642225d46eSJiawei Lin
5652225d46eSJiawei Lin  val instBytes = if (HasCExtension) 2 else 4
5662225d46eSJiawei Lin  val instOffsetBits = log2Ceil(instBytes)
5672225d46eSJiawei Lin
56805f23f57SWilliam Wang  val icacheParameters = coreParams.icacheParameters
5694f94c0c6SJiawei Lin  val dcacheParameters = coreParams.dcacheParametersOpt.getOrElse(DCacheParameters())
5702225d46eSJiawei Lin
571b899def8SWilliam Wang  // dcache block cacheline when lr for LRSCCycles - LRSCBackOff cycles
572b899def8SWilliam Wang  // for constrained LR/SC loop
573b899def8SWilliam Wang  val LRSCCycles = 64
574b899def8SWilliam Wang  // for lr storm
575b899def8SWilliam Wang  val LRSCBackOff = 8
5762225d46eSJiawei Lin
5772225d46eSJiawei Lin  // cache hierarchy configurations
5782225d46eSJiawei Lin  val l1BusDataWidth = 256
5792225d46eSJiawei Lin
580de169c67SWilliam Wang  // load violation predict
581de169c67SWilliam Wang  val ResetTimeMax2Pow = 20 //1078576
582de169c67SWilliam Wang  val ResetTimeMin2Pow = 10 //1024
583de169c67SWilliam Wang  // wait table parameters
584de169c67SWilliam Wang  val WaitTableSize = 1024
585de169c67SWilliam Wang  val MemPredPCWidth = log2Up(WaitTableSize)
586de169c67SWilliam Wang  val LWTUse2BitCounter = true
587de169c67SWilliam Wang  // store set parameters
588de169c67SWilliam Wang  val SSITSize = WaitTableSize
589de169c67SWilliam Wang  val LFSTSize = 32
590de169c67SWilliam Wang  val SSIDWidth = log2Up(LFSTSize)
591de169c67SWilliam Wang  val LFSTWidth = 4
592de169c67SWilliam Wang  val StoreSetEnable = true // LWT will be disabled if SS is enabled
593*cc4fb544Ssfencevma  val LFSTEnable = false
594*cc4fb544Ssfencevma
595cd365d4cSrvcoresjw  val PCntIncrStep: Int = 6
596cd365d4cSrvcoresjw  val numPCntHc: Int = 25
597cd365d4cSrvcoresjw  val numPCntPtw: Int = 19
598cd365d4cSrvcoresjw
599cd365d4cSrvcoresjw  val numCSRPCntFrontend = 8
600cd365d4cSrvcoresjw  val numCSRPCntCtrl     = 8
601cd365d4cSrvcoresjw  val numCSRPCntLsu      = 8
602cd365d4cSrvcoresjw  val numCSRPCntHc       = 5
6032225d46eSJiawei Lin}
604