1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4import chisel3.util._ 5import freechips.rocketchip.rocket.CSRs 6import utility.GatedValidRegNext 7import xiangshan.backend.fu.NewCSR.CSRDefines.{CSRROField => RO, CSRRWField => RW, CSRWARLField => WARL} 8import xiangshan.backend.fu.NewCSR.CSRFunc._ 9import xiangshan.backend.fu.vector.Bundles._ 10import xiangshan.backend.fu.NewCSR.CSRConfig._ 11import xiangshan.backend.fu.fpu.Bundles.{Fflags, Frm} 12import xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast._ 13 14import scala.collection.immutable.SeqMap 15 16trait Unprivileged { self: NewCSR with MachineLevel with SupervisorLevel => 17 18 val fcsr = Module(new CSRModule("Fcsr", new CSRBundle { 19 val NX = WARL(0, wNoFilter) 20 val UF = WARL(1, wNoFilter) 21 val OF = WARL(2, wNoFilter) 22 val DZ = WARL(3, wNoFilter) 23 val NV = WARL(4, wNoFilter) 24 val FRM = WARL(7, 5, wNoFilter).withReset(0.U) 25 }) with HasRobCommitBundle { 26 val wAliasFflags = IO(Input(new CSRAddrWriteBundle(new CSRFFlagsBundle))) 27 val wAliasFfm = IO(Input(new CSRAddrWriteBundle(new CSRFrmBundle))) 28 val fflags = IO(Output(Fflags())) 29 val frm = IO(Output(Frm())) 30 val fflagsRdata = IO(Output(Fflags())) 31 val frmRdata = IO(Output(Frm())) 32 33 for (wAlias <- Seq(wAliasFflags, wAliasFfm)) { 34 for ((name, field) <- wAlias.wdataFields.elements) { 35 reg.elements(name).asInstanceOf[CSREnumType].addOtherUpdate( 36 wAlias.wen && field.asInstanceOf[CSREnumType].isLegal, 37 field.asInstanceOf[CSREnumType] 38 ) 39 } 40 } 41 42 // write connection 43 reconnectReg() 44 45 when (robCommit.fflags.valid) { 46 reg.NX := robCommit.fflags.bits(0) || reg.NX 47 reg.UF := robCommit.fflags.bits(1) || reg.UF 48 reg.OF := robCommit.fflags.bits(2) || reg.OF 49 reg.DZ := robCommit.fflags.bits(3) || reg.DZ 50 reg.NV := robCommit.fflags.bits(4) || reg.NV 51 } 52 53 // read connection 54 fflags := reg.asUInt(4, 0) 55 frm := reg.FRM.asUInt 56 57 fflagsRdata := fflags.asUInt 58 frmRdata := frm.asUInt 59 }).setAddr(CSRs.fcsr) 60 61 // vec 62 val vstart = Module(new CSRModule("Vstart", new CSRBundle { 63 // vstart is not a WARL CSR. 64 // Since we need to judge whether flush pipe by vstart being not 0 in DecodeStage, vstart must be initialized to some value at reset. 65 val vstart = RW(VlWidth - 2, 0).withReset(0.U) // hold [0, 128) 66 }) with HasRobCommitBundle { 67 // Todo make The use of vstart values greater than the largest element index for the current SEW setting is reserved. 68 // Not trap 69 when (wen) { 70 reg.vstart := this.w.wdata(VlWidth - 2, 0) 71 }.elsewhen (robCommit.vsDirty && !robCommit.vstart.valid) { 72 reg.vstart := 0.U 73 }.elsewhen (robCommit.vstart.valid) { 74 reg.vstart := robCommit.vstart.bits 75 }.otherwise { 76 reg := reg 77 } 78 }) 79 .setAddr(CSRs.vstart) 80 81 val vcsr = Module(new CSRModule("Vcsr", new CSRBundle { 82 val VXSAT = RW( 0) 83 val VXRM = RW(2, 1) 84 }) with HasRobCommitBundle { 85 val wAliasVxsat = IO(Input(new CSRAddrWriteBundle(new CSRBundle { 86 val VXSAT = RW(0) 87 }))) 88 val wAliasVxrm = IO(Input(new CSRAddrWriteBundle(new CSRBundle { 89 val VXRM = RW(1, 0) 90 }))) 91 val vxsat = IO(Output(Vxsat())) 92 val vxrm = IO(Output(Vxrm())) 93 94 for (wAlias <- Seq(wAliasVxsat, wAliasVxrm)) { 95 for ((name, field) <- wAlias.wdataFields.elements) { 96 reg.elements(name).asInstanceOf[CSREnumType].addOtherUpdate( 97 wAlias.wen && field.asInstanceOf[CSREnumType].isLegal, 98 field.asInstanceOf[CSREnumType] 99 ) 100 } 101 } 102 103 // write connection 104 reconnectReg() 105 106 when(robCommit.vxsat.valid) { 107 reg.VXSAT := reg.VXSAT.asBool || robCommit.vxsat.bits.asBool 108 } 109 110 // read connection 111 vxsat := reg.VXSAT.asUInt 112 vxrm := reg.VXRM.asUInt 113 }).setAddr(CSRs.vcsr) 114 115 val vl = Module(new CSRModule("Vl", new CSRBundle { 116 val VL = RO(VlWidth - 1, 0).withReset(0.U) 117 })) 118 .setAddr(CSRs.vl) 119 120 val vtype = Module(new CSRModule("Vtype", new CSRVTypeBundle) with HasRobCommitBundle { 121 when(robCommit.vtype.valid) { 122 reg := robCommit.vtype.bits 123 } 124 }) 125 .setAddr(CSRs.vtype) 126 127 val vlenb = Module(new CSRModule("Vlenb", new CSRBundle { 128 val VLENB = VlenbField(63, 0).withReset(VlenbField.init) 129 })) 130 .setAddr(CSRs.vlenb) 131 132 val cycle = Module(new CSRModule("cycle", new CSRBundle { 133 val cycle = RO(63, 0) 134 }) with HasMHPMSink with HasDebugStopBundle { 135 when(unprivCountUpdate) { 136 reg := mHPM.cycle 137 }.otherwise{ 138 reg := reg 139 } 140 regOut := Mux(debugModeStopCount, reg.asUInt, mHPM.cycle) 141 }) 142 .setAddr(CSRs.cycle) 143 144 val time = Module(new CSRModule("time", new CSRBundle { 145 val time = RO(63, 0) 146 }) with HasMHPMSink with HasDebugStopBundle { 147 val updated = IO(Output(Bool())) 148 val stime = IO(Output(UInt(64.W))) 149 val vstime = IO(Output(UInt(64.W))) 150 151 val stimeTmp = mHPM.time.bits 152 val vstimeTmp = mHPM.time.bits + htimedelta 153 154 // Update when rtc clock tick and not dcsr.STOPTIME 155 // or virtual mode changed 156 // Note: we delay a cycle and use `v` for better timing 157 val virtModeChanged = RegNext(nextV =/= v, false.B) 158 when(mHPM.time.valid && !debugModeStopTime || virtModeChanged) { 159 reg.time := Mux(v, vstimeTmp, stimeTmp) 160 }.otherwise { 161 reg := reg 162 } 163 164 updated := GatedValidRegNext(mHPM.time.valid && !debugModeStopTime) 165 stime := stimeTmp 166 vstime := vstimeTmp 167 }) 168 .setAddr(CSRs.time) 169 170 val instret = Module(new CSRModule("instret", new CSRBundle { 171 val instret = RO(63, 0) 172 }) with HasMHPMSink with HasDebugStopBundle { 173 when(unprivCountUpdate) { 174 reg := mHPM.instret 175 }.otherwise{ 176 reg := reg 177 } 178 regOut := Mux(debugModeStopCount, reg.asUInt, mHPM.instret) 179 }) 180 .setAddr(CSRs.instret) 181 182 val hpmcounters: Seq[CSRModule[_]] = (3 to 0x1F).map(num => 183 Module(new CSRModule(s"Hpmcounter$num", new CSRBundle { 184 val hpmcounter = RO(63, 0).withReset(0.U) 185 }) with HasMHPMSink with HasDebugStopBundle { 186 when(unprivCountUpdate) { 187 reg := mHPM.hpmcounters(num - 3) 188 }.otherwise{ 189 reg := reg 190 } 191 regOut := Mux(debugModeStopCount, reg.asUInt, mHPM.hpmcounters(num - 3)) 192 }).setAddr(CSRs.cycle + num) 193 ) 194 195 val unprivilegedCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap( 196 CSRs.fflags -> (fcsr.wAliasFflags -> fcsr.fflagsRdata), 197 CSRs.frm -> (fcsr.wAliasFfm -> fcsr.frmRdata), 198 CSRs.fcsr -> (fcsr.w -> fcsr.rdata), 199 CSRs.vstart -> (vstart.w -> vstart.rdata), 200 CSRs.vxsat -> (vcsr.wAliasVxsat -> vcsr.vxsat), 201 CSRs.vxrm -> (vcsr.wAliasVxrm -> vcsr.vxrm), 202 CSRs.vcsr -> (vcsr.w -> vcsr.rdata), 203 CSRs.vl -> (vl.w -> vl.rdata), 204 CSRs.vtype -> (vtype.w -> vtype.rdata), 205 CSRs.vlenb -> (vlenb.w -> vlenb.rdata), 206 CSRs.cycle -> (cycle.w -> cycle.rdata), 207 CSRs.time -> (time.w -> time.rdata), 208 CSRs.instret -> (instret.w -> instret.rdata), 209 ) ++ hpmcounters.map(counter => (counter.addr -> (counter.w -> counter.rdata))) 210 211 val unprivilegedCSRMods: Seq[CSRModule[_]] = Seq( 212 fcsr, 213 vcsr, 214 vstart, 215 vl, 216 vtype, 217 vlenb, 218 cycle, 219 time, 220 instret, 221 ) ++ hpmcounters 222 223 val unprivilegedCSROutMap: SeqMap[Int, UInt] = SeqMap( 224 CSRs.fflags -> fcsr.fflags.asUInt, 225 CSRs.frm -> fcsr.frm.asUInt, 226 CSRs.fcsr -> fcsr.rdata.asUInt, 227 CSRs.vstart -> vstart.rdata.asUInt, 228 CSRs.vxsat -> vcsr.vxsat.asUInt, 229 CSRs.vxrm -> vcsr.vxrm.asUInt, 230 CSRs.vcsr -> vcsr.rdata.asUInt, 231 CSRs.vl -> vl.rdata.asUInt, 232 CSRs.vtype -> vtype.rdata.asUInt, 233 CSRs.vlenb -> vlenb.rdata.asUInt, 234 CSRs.cycle -> cycle.rdata, 235 CSRs.time -> time.rdata, 236 CSRs.instret -> instret.rdata, 237 ) ++ hpmcounters.map(counter => (counter.addr -> counter.rdata)) 238} 239 240class CSRVTypeBundle extends CSRBundle { 241 // vtype's vill is initialized to 1, when executing vector instructions 242 // which depend on vtype, will raise illegal instruction exception 243 val VILL = RO( 63).withReset(1.U) 244 val VMA = RO( 7).withReset(0.U) 245 val VTA = RO( 6).withReset(0.U) 246 val VSEW = RO(5, 3).withReset(0.U) 247 val VLMUL = RO(2, 0).withReset(0.U) 248} 249 250class CSRFrmBundle extends CSRBundle { 251 val FRM = WARL(2, 0, wNoFilter) 252} 253 254class CSRFFlagsBundle extends CSRBundle { 255 val NX = WARL(0, wNoFilter) 256 val UF = WARL(1, wNoFilter) 257 val OF = WARL(2, wNoFilter) 258 val DZ = WARL(3, wNoFilter) 259 val NV = WARL(4, wNoFilter) 260} 261 262object VlenbField extends CSREnum with ROApply { 263 val init = Value((VLEN / 8).U) 264} 265 266trait HasMHPMSink { self: CSRModule[_] => 267 val mHPM = IO(Input(new Bundle { 268 val cycle = UInt(64.W) 269 // ValidIO is used to update time reg 270 val time = ValidIO(UInt(64.W)) 271 val instret = UInt(64.W) 272 val hpmcounters = Vec(perfCntNum, UInt(XLEN.W)) 273 })) 274 val v = IO(Input(Bool())) 275 val nextV = IO(Input(Bool())) 276 val htimedelta = IO(Input(UInt(64.W))) 277} 278 279trait HasDebugStopBundle { self: CSRModule[_] => 280 val debugModeStopCount = IO(Input(Bool())) 281 val debugModeStopTime = IO(Input(Bool())) 282 val unprivCountUpdate = IO(Input(Bool())) 283}