xref: /XiangShan/src/main/scala/xiangshan/XSDts.scala (revision 6cd53fde72619778af882e2095e35de49cb82f06)
1/***************************************************************************************
2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3* Copyright (c) 2020-2021 Peng Cheng Laboratory
4*
5* XiangShan is licensed under Mulan PSL v2.
6* You can use this software according to the terms and conditions of the Mulan PSL v2.
7* You may obtain a copy of Mulan PSL v2 at:
8*          http://license.coscl.org.cn/MulanPSL2
9*
10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13*
14* See the Mulan PSL v2 for more details.
15***************************************************************************************/
16
17// See LICENSE.SiFive for license details.
18
19package xiangshan
20
21import freechips.rocketchip.diplomacy._
22
23trait HasXSDts {
24  this: XSCore =>
25
26  val device: SimpleDevice = new SimpleDevice("cpu", Seq("ICT,xiangshan", "riscv")) {
27    override def parent: Some[Device] = Some(ResourceAnchors.cpus)
28
29    def cpuProperties: PropertyMap = Map(
30      "device_type" -> "cpu".asProperty,
31      "status" -> "okay".asProperty,
32      "clock-frequency" -> 0.asProperty,
33      "riscv,isa" -> "rv64imafdcvh".asProperty, // deprecated
34      "riscv,isa-base" -> ISABase.asProperty,
35      "riscv,isa-extensions" -> ISAExtensions.map(ResourceString),
36      "timebase-frequency" -> 1000000.asProperty
37    )
38
39    def tileProperties: PropertyMap = {
40      val dcache = if(coreParams.dcacheParametersOpt.nonEmpty) Map(
41        "d-cache-block-size" -> dcacheParameters.blockBytes.asProperty,
42        "d-cache-sets" -> dcacheParameters.nSets.asProperty,
43        "d-cache-size" -> (dcacheParameters.nSets * dcacheParameters.nWays * dcacheParameters.blockBytes).asProperty
44      ) else Map()
45
46      val icache = Map(
47        "i-cache-block-size" -> icacheParameters.blockBytes.asProperty,
48        "i-cache-sets" -> icacheParameters.nSets.asProperty,
49        "i-cache-size" -> (icacheParameters.nSets * icacheParameters.nWays * icacheParameters.blockBytes).asProperty
50      )
51
52      val dtlb = Map(
53        "d-tlb-size" -> (ldtlbParams.NSets * ldtlbParams.NWays).asProperty,
54        "d-tlb-sets" -> 1.asProperty
55      )
56
57      val itlb = Map(
58        "i-tlb-size" -> (itlbParams.NSets * itlbParams.NWays).asProperty,
59        "i-tlb-sets" -> 1.asProperty
60      )
61
62      val mmu = Map(
63        "tlb-split" -> Nil,
64        "mmu-type" -> s"riscv,sv$VAddrBits".asProperty
65      )
66
67      val pmp = Nil
68
69      dcache ++ icache ++ dtlb ++ itlb ++ mmu ++ pmp
70    }
71
72    def nextLevelCacheProperty: PropertyOption = {
73      if(coreParams.dcacheParametersOpt.nonEmpty){
74        val outer = memBlock.inner.dcache.clientNode.edges.out.flatMap(_.manager.managers)
75          .filter(_.supportsAcquireB)
76          .flatMap(_.resources.headOption)
77          .map(_.owner.label)
78          .distinct
79        if (outer.isEmpty) None
80        else Some("next-level-cache" -> outer.map(l => ResourceReference(l)).toList)
81      } else None
82    }
83
84    override def describe(resources: ResourceBindings): Description = {
85      val Description(name, mapping) = super.describe(resources)
86      Description(name, mapping ++ cpuProperties ++ nextLevelCacheProperty ++ tileProperties)
87    }
88  }
89
90  val intcDevice = new DeviceSnippet {
91    override def parent = Some(device)
92    def describe(): Description = {
93      Description("interrupt-controller", Map(
94        "compatible"           -> "riscv,cpu-intc".asProperty,
95        "interrupt-controller" -> Nil,
96        "#interrupt-cells"     -> 1.asProperty))
97    }
98  }
99
100  ResourceBinding {
101    Resource(device, "reg").bind(ResourceAddress(coreParams.HartId))
102    val int_resources = (
103      memBlock.inner.clint_int_sink.edges.in.flatMap(_.source.sources) ++
104      memBlock.inner.plic_int_sink.edges.in.flatMap(_.source.sources) ++
105      memBlock.inner.debug_int_sink.edges.in.flatMap(_.source.sources) ++
106      memBlock.inner.nmi_int_sink.edges.in.flatMap(_.source.sources)
107      ).flatMap {
108      s =>
109        (s.range.start until s.range.`end`).map(_ => s.resources)
110    }
111    val int_ids = Seq(
112      3,    // msip  [clint]
113      7,    // mtip  [clint]
114      11,   // meip  [plic]
115      9,    // seip  [plic]
116      65535, // debug [debug]
117      31,   // nmi_31 [nmi]
118      43    // nmi_43 [nmi]
119    )
120    assert(int_resources.size == int_ids.size)
121    for((resources, id) <- int_resources.zip(int_ids)){
122      for(r <- resources){
123        r.bind(intcDevice, ResourceInt(id))
124      }
125    }
126  }
127}
128