1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4import chisel3.util._ 5import org.chipsalliance.cde.config.Parameters 6import top.{ArgParser, Generator} 7import xiangshan.{HasXSParameter, XSCoreParamsKey, XSTileKey} 8import xiangshan.backend.fu.NewCSR.CSRDefines.{PrivMode, VirtMode} 9import xiangshan.backend.fu.NewCSR.CSREvents.{CSREvents, EventUpdatePrivStateOutput, MretEventSinkBundle, SretEventSinkBundle, TrapEntryEventInput, TrapEntryHSEventSinkBundle, TrapEntryMEventSinkBundle, TrapEntryVSEventSinkBundle} 10 11object CSRConfig { 12 final val GEILEN = 63 13 14 final val ASIDLEN = 16 // the length of ASID of XS implementation 15 16 final val ASIDMAX = 16 // the max value of ASIDLEN defined by spec 17 18 final val HIIDWidth = 12 // support Hvictl[27:16](IID) 19 20 final val VMIDLEN = 14 // the length of VMID of XS implementation 21 22 final val VMIDMAX = 14 // the max value of VMIDLEN defined by spec 23 24 // the width of VGEIN 25 final val VGEINWidth = 6 26 27 final val VaddrMaxWidth = 41 // only Sv39 and Sv39x4 28 29 final val XLEN = 64 // Todo: use XSParams 30} 31 32class NewCSR(implicit val p: Parameters) extends Module 33 with HasXSParameter 34 with MachineLevel 35 with SupervisorLevel 36 with HypervisorLevel 37 with VirtualSupervisorLevel 38 with Unprivileged 39 with CSRAIA 40 with HasExternalInterruptBundle 41 with HasInstCommitBundle 42 with SupervisorMachineAliasConnect 43 with CSREvents 44{ 45 46 import CSRConfig._ 47 48 val io = IO(new Bundle { 49 val w = Flipped(ValidIO(new Bundle { 50 val addr = UInt(12.W) 51 val data = UInt(64.W) 52 })) 53 val rAddr = Input(UInt(12.W)) 54 val rData = Output(UInt(64.W)) 55 val trap = Flipped(ValidIO(new Bundle { 56 val toPRVM = PrivMode() 57 val toV = VirtMode() 58 val tpc = UInt(VaddrMaxWidth.W) 59 val isInterrupt = Bool() 60 val trapVec = UInt(64.W) 61 val isCrossPageIPF = Bool() 62 })) 63 val fromMem = Input(new Bundle { 64 val excpVA = UInt(VaddrMaxWidth.W) 65 val excpGPA = UInt(VaddrMaxWidth.W) // Todo: use guest physical address width 66 }) 67 val tret = Flipped(ValidIO(new Bundle { 68 val toPRVM = PrivMode() 69 val toV = VirtMode() 70 })) 71 val out = new Bundle { 72 val targetPc = UInt(VaddrMaxWidth.W) 73 } 74 }) 75 76 val toAIA = IO(Output(new CSRToAIABundle)) 77 val fromAIA = IO(Flipped(Output(new AIAToCSRBundle))) 78 79 dontTouch(toAIA) 80 dontTouch(fromAIA) 81 toAIA := DontCare 82 83 val addr = io.w.bits.addr 84 val data = io.w.bits.data 85 val wen = io.w.valid 86 87 val PRVM = RegInit(PrivMode(0), PrivMode.M) 88 val V = RegInit(VirtMode(0), VirtMode.Off) 89 90 val trap = io.trap.valid 91 val trapToPRVM = io.trap.bits.toPRVM 92 val trapToV = io.trap.bits.toV 93 val trapToM = trapToPRVM === PrivMode.M 94 val trapToHS = trapToPRVM === PrivMode.S && trapToV === VirtMode.Off 95 val trapToHU = trapToPRVM === PrivMode.U && trapToV === VirtMode.Off 96 val trapToVS = trapToPRVM === PrivMode.S && trapToV === VirtMode.On 97 val trapToVU = trapToPRVM === PrivMode.U && trapToV === VirtMode.On 98 99 val tret = io.tret.valid 100 val tretPRVM = io.tret.bits.toPRVM 101 val tretV = io.tret.bits.toV 102 val isSret = tret && tretPRVM === PrivMode.S 103 val isMret = tret && tretPRVM === PrivMode.M 104 105 var csrRwMap = machineLevelCSRMap ++ supervisorLevelCSRMap ++ hypervisorCSRMap ++ virtualSupervisorCSRMap ++ unprivilegedCSRMap ++ aiaCSRMap 106 107 val csrMods = machineLevelCSRMods ++ supervisorLevelCSRMods ++ hypervisorCSRMods ++ virtualSupervisorCSRMods ++ unprivilegedCSRMods ++ aiaCSRMods 108 109 for ((id, (wBundle, _)) <- csrRwMap) { 110 wBundle.wen := wen && addr === id.U 111 wBundle.wdata := data 112 } 113 io.rData := Mux1H(csrRwMap.map { case (id, (_, rBundle)) => 114 (io.rAddr === id.U) -> rBundle.asUInt 115 }) 116 117 csrMods.foreach { mod => 118 mod match { 119 case m: HypervisorBundle => 120 m.hstatus := hstatus.regOut 121 m.hvip := hvip.regOut 122 m.hideleg := hideleg.regOut 123 m.hedeleg := hedeleg.regOut 124 m.hgeip := hgeip.regOut 125 m.hgeie := hgeie.regOut 126 m.hip := hip.regOut 127 m.hie := hie.regOut 128 case _ => 129 } 130 mod match { 131 case m: HasMachineInterruptBundle => 132 m.mvien := mvien.regOut 133 m.mvip := mvip.regOut 134 m.mip := mip.regOut 135 m.mie := mie.regOut 136 case _ => 137 } 138 mod match { 139 case m: HasMachineDelegBundle => 140 m.mideleg := mideleg.regOut 141 m.medeleg := medeleg.regOut 142 case _ => 143 } 144 mod match { 145 case m: HasMachineCounterControlBundle => 146 m.mcountinhibit := mcountinhibit.regOut 147 case _ => 148 } 149 mod match { 150 case m: HasExternalInterruptBundle => 151 m.platformIRP := this.platformIRP 152 case _ => 153 } 154 mod match { 155 case m: HasInstCommitBundle => 156 m.commitValid := this.commitValid 157 m.commitInstNum := this.commitInstNum 158 case _ => 159 } 160 mod match { 161 case m: TrapEntryMEventSinkBundle => 162 m.trapToM := trapEntryMEvent.out 163 case _ => 164 } 165 mod match { 166 case m: TrapEntryHSEventSinkBundle => 167 m.trapToHS := trapEntryHSEvent.out 168 case _ => 169 } 170 mod match { 171 case m: TrapEntryVSEventSinkBundle => 172 m.trapToVS := trapEntryVSEvent.out 173 case _ => 174 } 175 mod match { 176 case m: MretEventSinkBundle => 177 m.retFromM := mretEvent.out 178 case _ => 179 } 180 mod match { 181 case m: SretEventSinkBundle => 182 m.retFromS := sretEvent.out 183 case _ => 184 } 185 } 186 187 csrMods.foreach { mod => 188 mod.commonIn.status := mstatus.mstatus 189 mod.commonIn.prvm := PRVM 190 mod.commonIn.v := V 191 mod.commonIn.hstatus := hstatus.rdata 192 println(s"${mod.modName}: ") 193 println(mod.dumpFields) 194 } 195 196 trapEntryMEvent.valid := trapToM 197 trapEntryHSEvent.valid := trapToHS 198 trapEntryVSEvent.valid := trapToVS 199 200 Seq(trapEntryMEvent, trapEntryHSEvent, trapEntryVSEvent).foreach { mod => 201 mod.in match { case in: TrapEntryEventInput => 202 in.causeNO := DontCare 203 in.trapPc := io.trap.bits.tpc 204 in.isCrossPageIPF := io.trap.bits.isCrossPageIPF 205 206 in.iMode.PRVM := PRVM 207 in.iMode.V := V 208 in.dMode.PRVM := Mux(mstatus.rdata.MPRV.asBool, mstatus.rdata.MPP, PRVM) 209 in.dMode.V := Mux(mstatus.rdata.MPRV.asBool, mstatus.rdata.MPV, V) 210 211 in.privState.PRVM := PRVM 212 in.privState.V := V 213 in.mstatus := mstatus.regOut 214 in.hstatus := hstatus.regOut 215 in.sstatus := mstatus.sstatus 216 in.vsstatus := vsstatus.regOut 217 in.satp := satp.rdata 218 in.vsatp := vsatp.rdata 219 220 in.memExceptionVAddr := io.fromMem.excpVA 221 in.memExceptionGPAddr := io.fromMem.excpGPA 222 } 223 } 224 225 mretEvent.valid := isMret 226 mretEvent.in match { 227 case in => 228 in.mstatus := mstatus.regOut 229 in.mepc := mepc.regOut 230 } 231 232 sretEvent.valid := isSret 233 sretEvent.in match { 234 case in => 235 in.privState.PRVM := PRVM 236 in.privState.V := V 237 in.sstatus := mstatus.sstatus 238 in.hstatus := hstatus.regOut 239 in.vsstatus := vsstatus.regOut 240 in.sepc := sepc.regOut 241 in.vsepc := vsepc.regOut 242 } 243 244 PRVM := MuxCase( 245 PRVM, 246 events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map { 247 x => x.out match { 248 case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.PRVM) 249 } 250 } 251 ) 252 253 V := MuxCase( 254 V, 255 events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map { 256 x => x.out match { 257 case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.V) 258 } 259 } 260 ) 261 262 io.out.targetPc := Mux1H(Seq( 263 mretEvent.out.targetPc.valid -> mretEvent.out.targetPc.bits.asUInt 264 )) 265} 266 267trait SupervisorMachineAliasConnect { self: NewCSR with MachineLevel with SupervisorLevel => 268 mip.fromMvip := mvip.toMip 269 mip.fromSip := sip.toMip 270 mie.fromSie := sie.toMie 271} 272 273object NewCSRMain extends App { 274 val (config, firrtlOpts, firtoolOpts) = ArgParser.parse( 275 args :+ "--disable-always-basic-diff" :+ "--dump-fir" :+ "--fpga-platform" :+ "--target" :+ "verilog") 276 277 val defaultConfig = config.alterPartial({ 278 // Get XSCoreParams and pass it to the "small module" 279 case XSCoreParamsKey => config(XSTileKey).head 280 }) 281 282 Generator.execute( 283 firrtlOpts :+ "--full-stacktrace" :+ "--target-dir" :+ "backend", 284 new NewCSR()(defaultConfig), 285 firtoolOpts 286 ) 287 288 println("done") 289}