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 // write connection 34 this.wfn(reg)(Seq(wAliasFflags, wAliasFfm)) 35 36 when (robCommit.fflags.valid) { 37 reg.NX := robCommit.fflags.bits(0) || reg.NX 38 reg.UF := robCommit.fflags.bits(1) || reg.UF 39 reg.OF := robCommit.fflags.bits(2) || reg.OF 40 reg.DZ := robCommit.fflags.bits(3) || reg.DZ 41 reg.NV := robCommit.fflags.bits(4) || reg.NV 42 } 43 44 // read connection 45 fflags := reg.asUInt(4, 0) 46 frm := reg.FRM.asUInt 47 48 fflagsRdata := fflags.asUInt 49 frmRdata := frm.asUInt 50 }).setAddr(CSRs.fcsr) 51 52 // vec 53 val vstart = Module(new CSRModule("Vstart", new CSRBundle { 54 // vstart is not a WARL CSR. 55 // Since we need to judge whether flush pipe by vstart being not 0 in DecodeStage, vstart must be initialized to some value at reset. 56 val vstart = RW(VlWidth - 2, 0).withReset(0.U) // hold [0, 128) 57 }) with HasRobCommitBundle { 58 // Todo make The use of vstart values greater than the largest element index for the current SEW setting is reserved. 59 // Not trap 60 when (wen) { 61 reg.vstart := this.w.wdata(VlWidth - 2, 0) 62 }.elsewhen (robCommit.vsDirty && !robCommit.vstart.valid) { 63 reg.vstart := 0.U 64 }.elsewhen (robCommit.vstart.valid) { 65 reg.vstart := robCommit.vstart.bits 66 }.otherwise { 67 reg := reg 68 } 69 }) 70 .setAddr(CSRs.vstart) 71 72 val vcsr = Module(new CSRModule("Vcsr", new CSRBundle { 73 val VXSAT = RW( 0) 74 val VXRM = RW(2, 1) 75 }) with HasRobCommitBundle { 76 val wAliasVxsat = IO(Input(new CSRAddrWriteBundle(new CSRBundle { 77 val VXSAT = RW(0) 78 }))) 79 val wAlisaVxrm = IO(Input(new CSRAddrWriteBundle(new CSRBundle { 80 val VXRM = RW(1, 0) 81 }))) 82 val vxsat = IO(Output(Vxsat())) 83 val vxrm = IO(Output(Vxrm())) 84 85 // write connection 86 this.wfn(reg)(Seq(wAliasVxsat, wAlisaVxrm)) 87 88 when(robCommit.vxsat.valid) { 89 reg.VXSAT := reg.VXSAT.asBool || robCommit.vxsat.bits.asBool 90 } 91 92 // read connection 93 vxsat := reg.VXSAT.asUInt 94 vxrm := reg.VXRM.asUInt 95 }).setAddr(CSRs.vcsr) 96 97 val vl = Module(new CSRModule("Vl", new CSRBundle { 98 val VL = RO(VlWidth - 1, 0).withReset(0.U) 99 })) 100 .setAddr(CSRs.vl) 101 102 val vtype = Module(new CSRModule("Vtype", new CSRVTypeBundle) with HasRobCommitBundle { 103 when(robCommit.vtype.valid) { 104 reg := robCommit.vtype.bits 105 } 106 }) 107 .setAddr(CSRs.vtype) 108 109 val vlenb = Module(new CSRModule("Vlenb", new CSRBundle { 110 val VLENB = VlenbField(63, 0).withReset(VlenbField.init) 111 })) 112 .setAddr(CSRs.vlenb) 113 114 val cycle = Module(new CSRModule("cycle", new CSRBundle { 115 val cycle = RO(63, 0) 116 }) with HasMHPMSink { 117 regOut.cycle := mHPM.cycle 118 }) 119 .setAddr(CSRs.cycle) 120 121 val time = Module(new CSRModule("time", new CSRBundle { 122 val time = RO(63, 0) 123 }) with HasMHPMSink { 124 val updated = IO(Output(Bool())) 125 val stime = IO(Output(UInt(64.W))) 126 val vstime = IO(Output(UInt(64.W))) 127 128 val stimeTmp = mHPM.time.bits 129 val vstimeTmp = mHPM.time.bits + htimedelta 130 131 when (mHPM.time.valid) { 132 reg.time := Mux(v, vstimeTmp, stimeTmp) 133 } 134 135 updated := GatedValidRegNext(mHPM.time.valid) 136 stime := stimeTmp 137 vstime := vstimeTmp 138 }) 139 .setAddr(CSRs.time) 140 141 val instret = Module(new CSRModule("instret", new CSRBundle { 142 val instret = RO(63, 0) 143 }) with HasMHPMSink { 144 regOut.instret := mHPM.instret 145 }) 146 .setAddr(CSRs.instret) 147 148 val hpmcounters: Seq[CSRModule[_]] = (3 to 0x1F).map(num => 149 Module(new CSRModule(s"Hpmcounter$num", new CSRBundle { 150 val hpmcounter = RO(63, 0).withReset(0.U) 151 }) with HasMHPMSink { 152 regOut.hpmcounter := mHPM.hpmcounters(num - 3) 153 }).setAddr(CSRs.cycle + num) 154 ) 155 156 val unprivilegedCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap( 157 CSRs.fflags -> (fcsr.wAliasFflags -> fcsr.fflagsRdata), 158 CSRs.frm -> (fcsr.wAliasFfm -> fcsr.frmRdata), 159 CSRs.fcsr -> (fcsr.w -> fcsr.rdata), 160 CSRs.vstart -> (vstart.w -> vstart.rdata), 161 CSRs.vxsat -> (vcsr.wAliasVxsat -> vcsr.vxsat), 162 CSRs.vxrm -> (vcsr.wAlisaVxrm -> vcsr.vxrm), 163 CSRs.vcsr -> (vcsr.w -> vcsr.rdata), 164 CSRs.vl -> (vl.w -> vl.rdata), 165 CSRs.vtype -> (vtype.w -> vtype.rdata), 166 CSRs.vlenb -> (vlenb.w -> vlenb.rdata), 167 CSRs.cycle -> (cycle.w -> cycle.rdata), 168 CSRs.time -> (time.w -> time.rdata), 169 CSRs.instret -> (instret.w -> instret.rdata), 170 ) ++ hpmcounters.map(counter => (counter.addr -> (counter.w -> counter.rdata))) 171 172 val unprivilegedCSRMods: Seq[CSRModule[_]] = Seq( 173 fcsr, 174 vcsr, 175 vstart, 176 vl, 177 vtype, 178 vlenb, 179 cycle, 180 time, 181 instret, 182 ) ++ hpmcounters 183 184 val unprivilegedCSROutMap: SeqMap[Int, UInt] = SeqMap( 185 CSRs.fflags -> fcsr.fflags.asUInt, 186 CSRs.frm -> fcsr.frm.asUInt, 187 CSRs.fcsr -> fcsr.rdata.asUInt, 188 CSRs.vstart -> vstart.rdata.asUInt, 189 CSRs.vxsat -> vcsr.vxsat.asUInt, 190 CSRs.vxrm -> vcsr.vxrm.asUInt, 191 CSRs.vcsr -> vcsr.rdata.asUInt, 192 CSRs.vl -> vl.rdata.asUInt, 193 CSRs.vtype -> vtype.rdata.asUInt, 194 CSRs.vlenb -> vlenb.rdata.asUInt, 195 CSRs.cycle -> cycle.rdata, 196 CSRs.time -> time.rdata, 197 CSRs.instret -> instret.rdata, 198 ) ++ hpmcounters.map(counter => (counter.addr -> counter.rdata)) 199} 200 201class CSRVTypeBundle extends CSRBundle { 202 // vtype's vill is initialized to 1, when executing vector instructions 203 // which depend on vtype, will raise illegal instruction exception 204 val VILL = RO( 63).withReset(1.U) 205 val VMA = RO( 7).withReset(0.U) 206 val VTA = RO( 6).withReset(0.U) 207 val VSEW = RO(5, 3).withReset(0.U) 208 val VLMUL = RO(2, 0).withReset(0.U) 209} 210 211class CSRFrmBundle extends CSRBundle { 212 val FRM = WARL(2, 0, wNoFilter) 213} 214 215class CSRFFlagsBundle extends CSRBundle { 216 val NX = WARL(0, wNoFilter) 217 val UF = WARL(1, wNoFilter) 218 val OF = WARL(2, wNoFilter) 219 val DZ = WARL(3, wNoFilter) 220 val NV = WARL(4, wNoFilter) 221} 222 223object VlenbField extends CSREnum with ROApply { 224 val init = Value((VLEN / 8).U) 225} 226 227trait HasMHPMSink { self: CSRModule[_] => 228 val mHPM = IO(Input(new Bundle { 229 val cycle = UInt(64.W) 230 // ValidIO is used to update time reg 231 val time = ValidIO(UInt(64.W)) 232 val instret = UInt(64.W) 233 val hpmcounters = Vec(perfCntNum, UInt(XLEN.W)) 234 })) 235 val v = IO(Input(Bool())) 236 val htimedelta = IO(Input(UInt(64.W))) 237} 238