diff --git a/rocket/src/main/scala/consts.scala b/rocket/src/main/scala/consts.scala index 4c601d81..030753d0 100644 --- a/rocket/src/main/scala/consts.scala +++ b/rocket/src/main/scala/consts.scala @@ -59,5 +59,11 @@ trait ScalarOpConstants { val DW_64 = Y val DW_XPR = Y + val SZ_PRV = 2 + val PRV_U = 0 + val PRV_S = 1 + val PRV_H = 2 + val PRV_M = 3 + val RA = UInt(1, 5) } diff --git a/rocket/src/main/scala/csr.scala b/rocket/src/main/scala/csr.scala index ec288987..7dec9a09 100644 --- a/rocket/src/main/scala/csr.scala +++ b/rocket/src/main/scala/csr.scala @@ -4,34 +4,71 @@ package rocket import Chisel._ import Util._ +import Instructions._ import Node._ import uncore._ import scala.math._ -class Status extends Bundle { - val ip = Bits(width = 8) - val im = Bits(width = 8) - val zero = Bits(width = 7) - val er = Bool() - val vm = Bool() - val s64 = Bool() - val u64 = Bool() - val ef = Bool() - val pei = Bool() - val ei = Bool() +class MStatus extends Bundle { + val sd = Bool() + val zero6 = UInt(width = 19) + val ha = UInt(width = 4) + val sa = UInt(width = 4) + val ua = UInt(width = 4) + val zero5 = UInt(width = 1) + val xs = UInt(width = 2) + val fs = UInt(width = 2) + val mtie = Bool() + val htie = Bool() + val stie = Bool() + val zero4 = UInt(width = 1) + val vm = UInt(width = 4) + val zero3 = UInt(width = 1) + val mprv = UInt(width = 2) + val zero2 = UInt(width = 3) + val prv2 = UInt(width = 2) + val ie2 = Bool() + val prv1 = UInt(width = 2) + val ie1 = Bool() + val prv = UInt(width = 2) + val ie = Bool() + val msip = Bool() + val hsip = Bool() + val ssip = Bool() + val zero1 = UInt(width = 1) +} + +class SStatus extends Bundle { + val sd = Bool() + val zero6 = UInt(width = 32) + val xs = UInt(width = 2) + val fs = UInt(width = 2) + val tip = Bool() + val zero5 = UInt(width = 1) + val tie = Bool() + val zero4 = UInt(width = 4) + val ua = UInt(width = 4) + val zero3 = UInt(width = 7) val ps = Bool() - val s = Bool() + val pie = UInt(width = 1) + val zero2 = UInt(width = 2) + val ie = Bool() + val zero1 = UInt(width = 2) + val sip = Bool() + val zero0 = UInt(width = 1) } object CSR { // commands - val SZ = 2 - val X = Bits("b??", 2) - val N = Bits(0,2) - val W = Bits(1,2) - val S = Bits(2,2) - val C = Bits(3,2) + val SZ = 3 + val X = UInt.DC(SZ) + val N = UInt(0,SZ) + val W = UInt(1,SZ) + val S = UInt(2,SZ) + val C = UInt(3,SZ) + val I = UInt(4,SZ) + val R = UInt(5,SZ) } class CSRFileIO extends CoreBundle { @@ -43,40 +80,49 @@ class CSRFileIO extends CoreBundle { val wdata = Bits(INPUT, xLen) } - val status = new Status().asOutput + val csr_replay = Bool(OUTPUT) + val csr_xcpt = Bool(OUTPUT) + + val status = new MStatus().asOutput val ptbr = UInt(OUTPUT, paddrBits) val evec = UInt(OUTPUT, vaddrBits+1) val exception = Bool(INPUT) val retire = UInt(INPUT, log2Up(1+retireWidth)) val uarch_counters = Vec.fill(16)(UInt(INPUT, log2Up(1+retireWidth))) val cause = UInt(INPUT, xLen) - val badvaddr_wen = Bool(INPUT) - val pc = UInt(INPUT, vaddrBits+1) + val mbadaddr_wen = Bool(INPUT) + val pc = SInt(INPUT, vaddrBits+1) val sret = Bool(INPUT) val fatc = Bool(OUTPUT) - val replay = Bool(OUTPUT) val time = UInt(OUTPUT, xLen) val fcsr_rm = Bits(OUTPUT, FPConstants.RM_SZ) val fcsr_flags = Valid(Bits(width = FPConstants.FLAGS_SZ)).flip val rocc = new RoCCInterface().flip + val interrupt = Bool(OUTPUT) + val interrupt_cause = UInt(OUTPUT, xLen) } class CSRFile extends CoreModule { val io = new CSRFileIO - val reg_epc = Reg(Bits(width = vaddrBits+1)) - val reg_badvaddr = Reg(Bits(width = vaddrBits)) - val reg_evec = Reg(Bits(width = vaddrBits)) - val reg_compare = Reg(Bits(width = 32)) - val reg_cause = Reg(Bits(width = xLen)) + val reg_mstatus = Reg(new MStatus) + val reg_mepc = Reg(SInt(width = vaddrBits+1)) + val reg_mcause = Reg(Bits(width = xLen)) + val reg_mbadaddr = Reg(SInt(width = vaddrBits+1)) + val reg_mscratch = Reg(Bits(width = xLen)) + + val reg_sepc = Reg(SInt(width = vaddrBits+1)) + val reg_scause = Reg(Bits(width = xLen)) + val reg_sbadaddr = Reg(SInt(width = vaddrBits+1)) + val reg_sscratch = Reg(Bits(width = xLen)) + val reg_stvec = Reg(SInt(width = vaddrBits)) + val reg_stimecmp = Reg(Bits(width = 32)) + val reg_sptbr = Reg(UInt(width = paddrBits)) + val reg_tohost = Reg(init=Bits(0, xLen)) val reg_fromhost = Reg(init=Bits(0, xLen)) - val reg_sup0 = Reg(Bits(width = xLen)) - val reg_sup1 = Reg(Bits(width = xLen)) - val reg_ptbr = Reg(UInt(width = paddrBits)) val reg_stats = Reg(init=Bool(false)) - val reg_status = Reg(new Status) // reset down below val reg_time = WideCounter(xLen) val reg_instret = WideCounter(xLen, io.retire) val reg_uarch_counters = io.uarch_counters.map(WideCounter(xLen, _)) @@ -84,12 +130,27 @@ class CSRFile extends CoreModule val reg_frm = Reg(UInt(width = 3)) val r_irq_timer = Reg(init=Bool(false)) - val r_irq_ipi = Reg(init=Bool(true)) val irq_rocc = Bool(!params(BuildRoCC).isEmpty) && io.rocc.interrupt - val cpu_req_valid = io.rw.cmd != CSR.N + io.interrupt_cause := 0 + io.interrupt := io.interrupt_cause(xLen-1) + def checkInterrupt(max_priv: UInt, cond: Bool, num: Int) = { + when (cond && (reg_mstatus.prv < max_priv || reg_mstatus.prv === max_priv && reg_mstatus.ie)) { + io.interrupt_cause := UInt((BigInt(1) << (xLen-1)) + num) + } + } + + checkInterrupt(PRV_S, r_irq_timer, 0) + checkInterrupt(PRV_S, reg_mstatus.ssip, 1) + checkInterrupt(PRV_M, reg_mstatus.msip, 1) + checkInterrupt(PRV_M, reg_fromhost != 0, 2) + checkInterrupt(PRV_M, irq_rocc, 3) + + val system_insn = io.rw.cmd === CSR.I + val cpu_ren = io.rw.cmd != CSR.N && !system_insn + val host_pcr_req_valid = Reg(Bool()) // don't reset - val host_pcr_req_fire = host_pcr_req_valid && !cpu_req_valid + val host_pcr_req_fire = host_pcr_req_valid && !cpu_ren val host_pcr_rep_valid = Reg(Bool()) // don't reset val host_pcr_bits = Reg(io.host.pcr_req.bits) io.host.pcr_req.ready := !host_pcr_req_valid && !host_pcr_rep_valid @@ -108,58 +169,116 @@ class CSRFile extends CoreModule io.host.debug_stats_pcr := reg_stats // direct export up the hierarchy - val addr = Mux(cpu_req_valid, io.rw.addr, host_pcr_bits.addr | 0x500) - val decoded_addr = { - val map = for ((v, i) <- CSRs.all.zipWithIndex) - yield v -> UInt(BigInt(1) << i) - val out = ROM(map)(addr) - Map((CSRs.all zip out.toBools):_*) - } + val addr = Mux(cpu_ren, io.rw.addr, host_pcr_bits.addr) + val decoded_addr = Map(( + for ((v, i) <- CSRs.all.zipWithIndex) + yield v -> (addr === CSRs.all(i))):_*) - val wen = cpu_req_valid || host_pcr_req_fire && host_pcr_bits.rw - val wdata = Mux(cpu_req_valid, io.rw.wdata, host_pcr_bits.data) + val addr_valid = decoded_addr.values.reduce(_||_) + val fp_csr = decoded_addr(CSRs.fflags) || decoded_addr(CSRs.frm) || decoded_addr(CSRs.fcsr) + val csr_addr_priv = io.rw.addr(9,8) + val priv_sufficient = reg_mstatus.prv >= csr_addr_priv + val read_only = io.rw.addr(11,10).andR + val cpu_wen = cpu_ren && io.rw.cmd != CSR.R && priv_sufficient + val wen = cpu_wen && !read_only || host_pcr_req_fire && host_pcr_bits.rw + val wdata = Mux(io.rw.cmd === CSR.W, io.rw.wdata, + Mux(io.rw.cmd === CSR.C, io.rw.rdata & ~io.rw.wdata, + Mux(io.rw.cmd === CSR.S, io.rw.rdata | io.rw.wdata, + host_pcr_bits.data))) - io.status := reg_status - io.status.ip := Cat(r_irq_timer, reg_fromhost.orR, r_irq_ipi, Bool(false), - Bool(false), irq_rocc, Bool(false), Bool(false)) - io.fatc := wen && decoded_addr(CSRs.fatc) - io.evec := Mux(io.exception, reg_evec.toSInt, reg_epc).toUInt - io.ptbr := reg_ptbr + val opcode = io.rw.addr(3,0) + // The following comparison is meant to be opcode === SFENCE_VM(23,20). But + // FOR SOME FUCKING REASON, extracting SFENCE_VM(23,20) gives 3, not 4. + val insn_sfence_vm = opcode === 4 && system_insn && priv_sufficient + val insn_redirect_trap = opcode === MRTS(23,20) && system_insn && priv_sufficient + val insn_ret = opcode === SRET(23,20) /* or H/MRET */ && io.rw.addr(1) && system_insn && priv_sufficient + val insn_break = opcode === SBREAK(23,20) && io.rw.addr(0) && system_insn && priv_sufficient + val insn_call = opcode === SCALL(23,20) /* or H/MCALL */ && system_insn && priv_sufficient - when (io.badvaddr_wen) { - val wdata = io.rw.wdata - val (upper, lower) = Split(wdata, vaddrBits) - val sign = Mux(lower.toSInt < SInt(0), upper.andR, upper.orR) - reg_badvaddr := Cat(sign, lower).toSInt - } + val csr_xcpt = (cpu_wen && read_only) || + (cpu_ren && (!priv_sufficient || !addr_valid || fp_csr && !io.status.fs.orR)) || + (system_insn && !priv_sufficient) || + insn_call || insn_break - when (io.exception) { - reg_status.s := true - reg_status.ps := reg_status.s - reg_status.ei := false - reg_status.pei := reg_status.ei - reg_epc := io.pc.toSInt - reg_cause := io.cause + val mtvec = reg_mstatus.prv << 6 + io.fatc := insn_sfence_vm + io.evec := Mux(io.exception || csr_xcpt, mtvec.zext, + Mux(insn_redirect_trap, reg_stvec, + Mux(reg_mstatus.prv(1), reg_mepc, reg_sepc))).toUInt + io.ptbr := reg_sptbr + io.csr_xcpt := csr_xcpt || insn_redirect_trap || insn_ret /* sort of a lie */ + io.status := reg_mstatus + io.status.fs := reg_mstatus.fs.orR.toSInt // either off or dirty (no clean/initial support yet) + io.status.xs := reg_mstatus.xs.orR.toSInt // either off or dirty (no clean/initial support yet) + io.status.sd := reg_mstatus.xs.orR || reg_mstatus.fs.orR + + when (io.exception || csr_xcpt) { + reg_mstatus.ie := false + reg_mstatus.prv := PRV_M + reg_mstatus.mprv := PRV_M + reg_mstatus.prv1 := reg_mstatus.prv + reg_mstatus.ie1 := reg_mstatus.ie + reg_mstatus.prv2 := reg_mstatus.prv1 + reg_mstatus.ie2 := reg_mstatus.ie1 + + reg_mepc := io.pc + reg_mcause := io.cause + when (csr_xcpt) { + reg_mcause := Causes.illegal_instruction + when (insn_break) { reg_mcause := Causes.breakpoint } + when (insn_call) { reg_mcause := Causes.scall + csr_addr_priv } + } + + reg_mbadaddr := io.pc + when (io.cause === Causes.fault_load || io.cause === Causes.misaligned_load || + io.cause === Causes.fault_store || io.cause === Causes.misaligned_store) { + val wdata = io.rw.wdata + val (upper, lower) = Split(wdata, vaddrBits) + val sign = Mux(lower.toSInt < SInt(0), upper.andR, upper.orR) + reg_mbadaddr := Cat(sign, lower).toSInt + } } - when (io.sret) { - reg_status.s := reg_status.ps - reg_status.ei := reg_status.pei + when (insn_ret) { + reg_mstatus.ie := reg_mstatus.ie1 + reg_mstatus.prv := reg_mstatus.prv1 + reg_mstatus.prv1 := reg_mstatus.prv2 + reg_mstatus.ie1 := reg_mstatus.ie2 + reg_mstatus.prv2 := PRV_U + reg_mstatus.ie2 := true } - when (reg_time(reg_compare.getWidth-1,0) === reg_compare) { + when (insn_redirect_trap) { + reg_mstatus.prv := PRV_S + reg_sbadaddr := reg_mbadaddr + reg_scause := reg_mcause + reg_sepc := reg_mepc + } + + assert(PopCount(insn_ret :: insn_redirect_trap :: io.exception :: csr_xcpt :: io.csr_replay :: Nil) <= 1, "these conditions must be mutually exclusive") + + when (reg_time(reg_stimecmp.getWidth-1,0) === reg_stimecmp) { r_irq_timer := true } io.time := reg_time - io.host.ipi_req.valid := cpu_req_valid && decoded_addr(CSRs.send_ipi) + io.host.ipi_req.valid := cpu_wen && decoded_addr(CSRs.send_ipi) io.host.ipi_req.bits := io.rw.wdata - io.replay := io.host.ipi_req.valid && !io.host.ipi_req.ready + io.csr_replay := io.host.ipi_req.valid && !io.host.ipi_req.ready when (host_pcr_req_fire && !host_pcr_bits.rw && decoded_addr(CSRs.tohost)) { reg_tohost := UInt(0) } - val read_impl = Bits(2) - val read_ptbr = reg_ptbr(paddrBits-1, pgIdxBits) << UInt(pgIdxBits) + val read_mstatus = io.status.toBits + val read_sstatus = new SStatus + read_sstatus := new SStatus().fromBits(read_mstatus) // sstatus mostly overlaps mstatus + read_sstatus.zero0 := 0 + read_sstatus.zero1 := 0 + read_sstatus.zero2 := 0 + read_sstatus.zero3 := 0 + read_sstatus.zero4 := 0 + read_sstatus.zero5 := 0 + read_sstatus.ua := io.status.ua + read_sstatus.tip := r_irq_timer val read_mapping = collection.mutable.LinkedHashMap[Int,Bits]( CSRs.fflags -> (if (!params(BuildFPU).isEmpty) reg_fflags else UInt(0)), @@ -167,23 +286,25 @@ class CSRFile extends CoreModule CSRs.fcsr -> (if (!params(BuildFPU).isEmpty) Cat(reg_frm, reg_fflags) else UInt(0)), CSRs.cycle -> reg_time, CSRs.time -> reg_time, + CSRs.scycle -> reg_time, + CSRs.stime -> reg_time, CSRs.instret -> reg_instret, - CSRs.sup0 -> reg_sup0, - CSRs.sup1 -> reg_sup1, - CSRs.epc -> reg_epc, - CSRs.badvaddr -> reg_badvaddr, - CSRs.ptbr -> read_ptbr, - CSRs.asid -> UInt(0), - CSRs.count -> reg_time, - CSRs.compare -> reg_compare, - CSRs.evec -> reg_evec, - CSRs.cause -> reg_cause, - CSRs.status -> io.status.toBits, + CSRs.sinstret -> reg_instret, + CSRs.mstatus -> read_mstatus, + CSRs.mscratch -> reg_mscratch, + CSRs.mepc -> reg_mepc, + CSRs.mbadaddr -> reg_mbadaddr, + CSRs.mcause -> reg_mcause, + CSRs.sstatus -> read_sstatus.toBits, + CSRs.sscratch -> reg_sscratch, + CSRs.sepc -> reg_sepc, + CSRs.scause -> reg_scause, + CSRs.sbadaddr -> reg_sbadaddr, + CSRs.sptbr -> reg_sptbr, + CSRs.sasid -> UInt(0), + CSRs.stimecmp -> reg_stimecmp, + CSRs.stvec -> reg_stvec, CSRs.hartid -> io.host.id, - CSRs.impl -> read_impl, - CSRs.fatc -> read_impl, // don't care - CSRs.send_ipi -> read_impl, // don't care - CSRs.clear_ipi -> read_impl, // don't care CSRs.stats -> reg_stats, CSRs.tohost -> reg_tohost, CSRs.fromhost -> reg_fromhost) @@ -199,46 +320,80 @@ class CSRFile extends CoreModule } when (wen) { - when (decoded_addr(CSRs.status)) { - reg_status := new Status().fromBits(wdata) - reg_status.s64 := true - reg_status.u64 := true - reg_status.zero := 0 - if (!params(UseVM)) reg_status.vm := false - if (params(BuildRoCC).isEmpty) reg_status.er := false - if (params(BuildFPU).isEmpty) reg_status.ef := false + when (decoded_addr(CSRs.mstatus)) { + val new_mstatus = new MStatus().fromBits(wdata) + reg_mstatus.ssip := new_mstatus.ssip + reg_mstatus.msip := new_mstatus.msip + reg_mstatus.stie := new_mstatus.stie + reg_mstatus.ie := new_mstatus.ie + reg_mstatus.ie1 := new_mstatus.ie1 + reg_mstatus.ie2 := new_mstatus.ie2 + when (new_mstatus.mprv != PRV_H) { reg_mstatus.mprv := new_mstatus.mprv } + when (new_mstatus.prv != PRV_H) { reg_mstatus.prv := new_mstatus.prv } + when (new_mstatus.prv1 != PRV_H) { reg_mstatus.prv1 := new_mstatus.prv1 } + when (new_mstatus.prv2 != PRV_H) { reg_mstatus.prv2 := new_mstatus.prv2 } + if (params(UseVM)) when (new_mstatus.vm === 0 || new_mstatus.vm === 5) { reg_mstatus.vm := new_mstatus.vm } + if (!params(BuildFPU).isEmpty) reg_mstatus.fs := new_mstatus.fs + if (!params(BuildRoCC).isEmpty) reg_mstatus.xs := new_mstatus.xs + } + when (decoded_addr(CSRs.sstatus)) { + val new_sstatus = new SStatus().fromBits(wdata) + reg_mstatus.ssip := new_sstatus.sip + reg_mstatus.stie := new_sstatus.tie + reg_mstatus.ie := new_sstatus.ie + reg_mstatus.ie1 := new_sstatus.pie + reg_mstatus.prv1 := Mux(new_sstatus.ps, PRV_S, PRV_U) + if (!params(BuildFPU).isEmpty) reg_mstatus.fs := new_sstatus.fs + if (!params(BuildRoCC).isEmpty) reg_mstatus.xs := new_sstatus.xs } when (decoded_addr(CSRs.fflags)) { reg_fflags := wdata } when (decoded_addr(CSRs.frm)) { reg_frm := wdata } when (decoded_addr(CSRs.fcsr)) { reg_fflags := wdata; reg_frm := wdata >> reg_fflags.getWidth } - when (decoded_addr(CSRs.epc)) { reg_epc := wdata(vaddrBits,0).toSInt } - when (decoded_addr(CSRs.evec)) { reg_evec := wdata(vaddrBits-1,0).toSInt } - when (decoded_addr(CSRs.count)) { reg_time := wdata.toUInt } - when (decoded_addr(CSRs.compare)) { reg_compare := wdata(31,0).toUInt; r_irq_timer := Bool(false) } + when (decoded_addr(CSRs.mepc)) { reg_mepc := wdata(vaddrBits,0).toSInt } + when (decoded_addr(CSRs.mscratch)) { reg_mscratch := wdata } + when (decoded_addr(CSRs.mcause)) { reg_mcause := wdata & UInt((BigInt(1) << (xLen-1)) + 31) /* only implement 5 LSBs and MSB */ } + when (decoded_addr(CSRs.mbadaddr)) { reg_mbadaddr := wdata } + when (decoded_addr(CSRs.sepc)) { reg_sepc := wdata(vaddrBits,0).toSInt } + when (decoded_addr(CSRs.stvec)) { reg_stvec := wdata(vaddrBits-1,0).toSInt } + when (decoded_addr(CSRs.scycle)) { reg_time := wdata.toUInt } + when (decoded_addr(CSRs.stime)) { reg_time := wdata.toUInt } + when (decoded_addr(CSRs.sinstret)) { reg_instret := wdata.toUInt } + when (decoded_addr(CSRs.stimecmp)) { reg_stimecmp := wdata(31,0).toUInt; r_irq_timer := Bool(false) } when (decoded_addr(CSRs.fromhost)) { when (reg_fromhost === UInt(0) || !host_pcr_req_fire) { reg_fromhost := wdata } } when (decoded_addr(CSRs.tohost)) { when (reg_tohost === UInt(0) || host_pcr_req_fire) { reg_tohost := wdata } } - when (decoded_addr(CSRs.clear_ipi)){ r_irq_ipi := wdata(0) } - when (decoded_addr(CSRs.sup0)) { reg_sup0 := wdata } - when (decoded_addr(CSRs.sup1)) { reg_sup1 := wdata } - when (decoded_addr(CSRs.ptbr)) { reg_ptbr := Cat(wdata(paddrBits-1, pgIdxBits), Bits(0, pgIdxBits)).toUInt } + when (decoded_addr(CSRs.sscratch)) { reg_sscratch := wdata } + when (decoded_addr(CSRs.sptbr)) { reg_sptbr := Cat(wdata(paddrBits-1, pgIdxBits), Bits(0, pgIdxBits)).toUInt } when (decoded_addr(CSRs.stats)) { reg_stats := wdata(0) } } - io.host.ipi_rep.ready := Bool(true) - when (io.host.ipi_rep.valid) { r_irq_ipi := Bool(true) } + io.host.ipi_rep.ready := true + when (io.host.ipi_rep.valid) { reg_mstatus.msip := true } when(this.reset) { - reg_status.ei := false - reg_status.pei := false - reg_status.ef := false - reg_status.er := false - reg_status.ps := false - reg_status.s := true - reg_status.u64 := true - reg_status.s64 := true - reg_status.vm := false - reg_status.zero := 0 - reg_status.im := 0 - reg_status.ip := 0 + reg_mstatus.zero1 := 0 + reg_mstatus.ssip := false + reg_mstatus.hsip := false + reg_mstatus.msip := false + reg_mstatus.ie := false + reg_mstatus.prv := PRV_M + reg_mstatus.ie1 := false + reg_mstatus.prv1 := PRV_S + reg_mstatus.ie2 := false + reg_mstatus.prv2 := PRV_S + reg_mstatus.mprv := PRV_M + reg_mstatus.zero2 := 0 + reg_mstatus.vm := 0 + reg_mstatus.zero3 := 0 + reg_mstatus.stie := false + reg_mstatus.htie := false + reg_mstatus.mtie := false + reg_mstatus.fs := 0 + reg_mstatus.xs := 0 + reg_mstatus.zero4 := 0 + reg_mstatus.ua := 4 + reg_mstatus.sa := 4 + reg_mstatus.ha := 0 + reg_mstatus.zero5 := 0 + reg_mstatus.sd := false } } diff --git a/rocket/src/main/scala/ctrl.scala b/rocket/src/main/scala/ctrl.scala index 590dc1e2..450a8817 100644 --- a/rocket/src/main/scala/ctrl.scala +++ b/rocket/src/main/scala/ctrl.scala @@ -17,8 +17,7 @@ class CtrlDpathIO extends CoreBundle val ren = Vec.fill(2)(Bool(OUTPUT)) val ex_ctrl = new IntCtrlSigs().asOutput val mem_ctrl = new IntCtrlSigs().asOutput - val csr = UInt(OUTPUT, 3) - val sret = Bool(OUTPUT) + val csr_cmd = UInt(OUTPUT, CSR.SZ) val ex_valid = Bool(OUTPUT) val wb_wen = Bool(OUTPUT) val bypass = Vec.fill(2)(Bool(OUTPUT)) @@ -28,11 +27,11 @@ class CtrlDpathIO extends CoreBundle val retire = Bool(OUTPUT) val exception = Bool(OUTPUT) val cause = UInt(OUTPUT, xLen) - val badvaddr_wen = Bool(OUTPUT) // high for a load/store access fault // inputs from datapath val inst = Bits(INPUT, 32) val mem_br_taken = Bool(INPUT) val mem_misprediction = Bool(INPUT) + val mem_npc_misaligned = Bool(INPUT) val div_mul_rdy = Bool(INPUT) val ll_wen = Bool(INPUT) val ll_waddr = UInt(INPUT, 5) @@ -40,10 +39,14 @@ class CtrlDpathIO extends CoreBundle val mem_rs1_ra = Bool(INPUT) val mem_waddr = UInt(INPUT, 5) val wb_waddr = UInt(INPUT, 5) - val status = new Status().asInput + val status = new MStatus().asInput val fp_sboard_clr = Bool(INPUT) val fp_sboard_clra = UInt(INPUT, 5) + // inputs from csr file val csr_replay = Bool(INPUT) + val csr_xcpt = Bool(INPUT) + val interrupt = Bool(INPUT) + val interrupt_cause = UInt(INPUT, xLen) } abstract trait DecodeConstants @@ -52,14 +55,14 @@ abstract trait DecodeConstants val decode_default = // jal renf1 fence.i - // | jalr | renf2 | sret - // fp_val| | renx2 | | renf3 | | syscall - // | rocc| | | renx1 s_alu1 mem_val | | | wfd | | | - // val | | br| | | | s_alu2 | imm dw alu | mem_cmd mem_type| | | | div | | | - // | | | | | | | | | | | | | | | | | | | | | wxd | | | fence - // | | | | | | | | | | | | | | | | | | | | | | csr | | | | amo - // | | | | | | | | | | | | | | | | | | | | | | | | | | | | - List(N, X,X,X,X,X,X,X,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, X,X,X,X,X,X,CSR.X,X,X,X,X,X) + // | jalr | renf2 | + // fp_val| | renx2 | | renf3 | + // | rocc| | | renx1 s_alu1 mem_val | | | wfd | + // val | | br| | | | s_alu2 | imm dw alu | mem_cmd mem_type| | | | div | + // | | | | | | | | | | | | | | | | | | | | | wxd | fence + // | | | | | | | | | | | | | | | | | | | | | | csr | | amo + // | | | | | | | | | | | | | | | | | | | | | | | | | | + List(N, X,X,X,X,X,X,X,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, X,X,X,X,X,X,CSR.X,X,X,X) val table: Array[(UInt, List[UInt])] } @@ -89,8 +92,6 @@ class IntCtrlSigs extends Bundle { val wxd = Bool() val csr = Bits(width = CSR.SZ) val fence_i = Bool() - val sret = Bool() - val scall = Bool() val fence = Bool() val amo = Bool() @@ -98,8 +99,7 @@ class IntCtrlSigs extends Bundle { val decoder = DecodeLogic(inst, XDecode.decode_default, table) Vec(legal, fp, rocc, branch, jal, jalr, rxs2, rxs1, sel_alu2, sel_alu1, sel_imm, alu_dw, alu_fn, mem, mem_cmd, mem_type, - rfs1, rfs2, rfs3, wfd, div, wxd, - csr, fence_i, sret, scall, fence, amo) := decoder + rfs1, rfs2, rfs3, wfd, div, wxd, csr, fence_i, fence, amo) := decoder this } } @@ -108,224 +108,230 @@ object XDecode extends DecodeConstants { val table = Array( // jal renf1 fence.i - // | jalr | renf2 | sret - // fp_val| | renx2 | | renf3 | | syscall - // | rocc| | | renx1 s_alu1 mem_val | | | wfd | | | - // val | | br| | | | s_alu2 | imm dw alu | mem_cmd mem_type| | | | div | | | - // | | | | | | | | | | | | | | | | | | | | | wxd | | | fence - // | | | | | | | | | | | | | | | | | | | | | | csr | | | | amo - // | | | | | | | | | | | | | | | | | | | | | | | | | | | | - BNE-> List(Y, N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X, FN_SNE, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N,N), - BEQ-> List(Y, N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X, FN_SEQ, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N,N), - BLT-> List(Y, N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X, FN_SLT, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N,N), - BLTU-> List(Y, N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X, FN_SLTU, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N,N), - BGE-> List(Y, N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X, FN_SGE, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N,N), - BGEU-> List(Y, N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X, FN_SGEU, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N,N), + // | jalr | renf2 | + // fp_val| | renx2 | | renf3 | + // | rocc| | | renx1 s_alu1 mem_val | | | wfd | + // val | | br| | | | s_alu2 | imm dw alu | mem_cmd mem_type| | | | div | + // | | | | | | | | | | | | | | | | | | | | | wxd | fence + // | | | | | | | | | | | | | | | | | | | | | | csr | | amo + // | | | | | | | | | | | | | | | | | | | | | | | | | | + BNE-> List(Y, N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X, FN_SNE, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N), + BEQ-> List(Y, N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X, FN_SEQ, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N), + BLT-> List(Y, N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X, FN_SLT, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N), + BLTU-> List(Y, N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X, FN_SLTU, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N), + BGE-> List(Y, N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X, FN_SGE, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N), + BGEU-> List(Y, N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X, FN_SGEU, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N), - JAL-> List(Y, N,N,N,Y,N,N,N,A2_FOUR,A1_PC, IMM_UJ,DW_X, FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - JALR-> List(Y, N,N,N,N,Y,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - AUIPC-> List(Y, N,N,N,N,N,N,N,A2_IMM, A1_PC, IMM_U, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), + JAL-> List(Y, N,N,N,Y,N,N,N,A2_FOUR,A1_PC, IMM_UJ,DW_X, FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + JALR-> List(Y, N,N,N,N,Y,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + AUIPC-> List(Y, N,N,N,N,N,N,N,A2_IMM, A1_PC, IMM_U, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), - LB-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, MT_B, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - LH-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, MT_H, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - LW-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, MT_W, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - LD-> List(xpr64,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, MT_D, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - LBU-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, MT_BU,N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - LHU-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, MT_HU,N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - LWU-> List(xpr64,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, MT_WU,N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - SB-> List(Y, N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD, Y,M_XWR, MT_B, N,N,N,N,N,N,CSR.N,N,N,N,N,N), - SH-> List(Y, N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD, Y,M_XWR, MT_H, N,N,N,N,N,N,CSR.N,N,N,N,N,N), - SW-> List(Y, N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD, Y,M_XWR, MT_W, N,N,N,N,N,N,CSR.N,N,N,N,N,N), - SD-> List(xpr64,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD, Y,M_XWR, MT_D, N,N,N,N,N,N,CSR.N,N,N,N,N,N), + LB-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, MT_B, N,N,N,N,N,Y,CSR.N,N,N,N), + LH-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, MT_H, N,N,N,N,N,Y,CSR.N,N,N,N), + LW-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, MT_W, N,N,N,N,N,Y,CSR.N,N,N,N), + LD-> List(xpr64,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, MT_D, N,N,N,N,N,Y,CSR.N,N,N,N), + LBU-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, MT_BU,N,N,N,N,N,Y,CSR.N,N,N,N), + LHU-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, MT_HU,N,N,N,N,N,Y,CSR.N,N,N,N), + LWU-> List(xpr64,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, MT_WU,N,N,N,N,N,Y,CSR.N,N,N,N), + SB-> List(Y, N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD, Y,M_XWR, MT_B, N,N,N,N,N,N,CSR.N,N,N,N), + SH-> List(Y, N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD, Y,M_XWR, MT_H, N,N,N,N,N,N,CSR.N,N,N,N), + SW-> List(Y, N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD, Y,M_XWR, MT_W, N,N,N,N,N,N,CSR.N,N,N,N), + SD-> List(xpr64,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD, Y,M_XWR, MT_D, N,N,N,N,N,N,CSR.N,N,N,N), - AMOADD_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_ADD, MT_W, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), - AMOXOR_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_XOR, MT_W, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), - AMOSWAP_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_SWAP,MT_W, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), - AMOAND_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_AND, MT_W, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), - AMOOR_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_OR, MT_W, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), - AMOMIN_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MIN, MT_W, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), - AMOMINU_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MINU,MT_W, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), - AMOMAX_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MAX, MT_W, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), - AMOMAXU_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MAXU,MT_W, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), - AMOADD_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_ADD, MT_D, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), - AMOSWAP_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_SWAP,MT_D, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), - AMOXOR_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_XOR, MT_D, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), - AMOAND_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_AND, MT_D, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), - AMOOR_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_OR, MT_D, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), - AMOMIN_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MIN, MT_D, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), - AMOMINU_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MINU,MT_D, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), - AMOMAX_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MAX, MT_D, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), - AMOMAXU_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MAXU,MT_D, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), + AMOADD_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_ADD, MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y), + AMOXOR_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_XOR, MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y), + AMOSWAP_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_SWAP,MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y), + AMOAND_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_AND, MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y), + AMOOR_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_OR, MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y), + AMOMIN_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MIN, MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y), + AMOMINU_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MINU,MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y), + AMOMAX_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MAX, MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y), + AMOMAXU_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MAXU,MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y), + AMOADD_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_ADD, MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y), + AMOSWAP_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_SWAP,MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y), + AMOXOR_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_XOR, MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y), + AMOAND_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_AND, MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y), + AMOOR_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_OR, MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y), + AMOMIN_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MIN, MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y), + AMOMINU_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MINU,MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y), + AMOMAX_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MAX, MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y), + AMOMAXU_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XA_MAXU,MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y), - LR_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XLR, MT_W, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), - LR_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XLR, MT_D, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), - SC_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XSC, MT_W, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), - SC_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XSC, MT_D, N,N,N,N,N,Y,CSR.N,N,N,N,N,Y), + LR_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XLR, MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y), + LR_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XLR, MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y), + SC_W-> List(Y, N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XSC, MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y), + SC_D-> List(xpr64,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, Y,M_XSC, MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y), - LUI-> List(Y, N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_U, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - ADDI-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - SLTI -> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SLT, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - SLTIU-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SLTU, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - ANDI-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_AND, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - ORI-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_OR, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - XORI-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_XOR, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - SLLI-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SL, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - SRLI-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SR, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - SRAI-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SRA, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - ADD-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - SUB-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SUB, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - SLT-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SLT, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - SLTU-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SLTU, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - AND-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_AND, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - OR-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_OR, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - XOR-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_XOR, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - SLL-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SL, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - SRL-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SR, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - SRA-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SRA, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), + LUI-> List(Y, N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_U, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + ADDI-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + SLTI -> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SLT, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + SLTIU-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SLTU, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + ANDI-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_AND, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + ORI-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_OR, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + XORI-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_XOR, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + SLLI-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SL, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + SRLI-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SR, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + SRAI-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SRA, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + ADD-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + SUB-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SUB, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + SLT-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SLT, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + SLTU-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SLTU, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + AND-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_AND, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + OR-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_OR, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + XOR-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_XOR, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + SLL-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SL, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + SRL-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SR, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + SRA-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SRA, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), - ADDIW-> List(xpr64,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - SLLIW-> List(xpr64,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,FN_SL, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - SRLIW-> List(xpr64,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,FN_SR, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - SRAIW-> List(xpr64,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,FN_SRA, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - ADDW-> List(xpr64,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - SUBW-> List(xpr64,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_SUB, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - SLLW-> List(xpr64,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_SL, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - SRLW-> List(xpr64,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_SR, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - SRAW-> List(xpr64,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_SRA, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), + ADDIW-> List(xpr64,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + SLLIW-> List(xpr64,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,FN_SL, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + SRLIW-> List(xpr64,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,FN_SR, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + SRAIW-> List(xpr64,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,FN_SRA, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + ADDW-> List(xpr64,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + SUBW-> List(xpr64,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_SUB, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + SLLW-> List(xpr64,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_SL, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + SRLW-> List(xpr64,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_SR, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + SRAW-> List(xpr64,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_SRA, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), - MUL-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_MUL, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N,N), - MULH-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_MULH, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N,N), - MULHU-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_MULHU, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N,N), - MULHSU-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_MULHSU,N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N,N), - MULW-> List(xpr64,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_MUL, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N,N), + MUL-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_MUL, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N), + MULH-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_MULH, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N), + MULHU-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_MULHU, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N), + MULHSU-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_MULHSU,N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N), + MULW-> List(xpr64,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_MUL, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N), - DIV-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_DIV, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N,N), - DIVU-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_DIVU, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N,N), - REM-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_REM, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N,N), - REMU-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_REMU, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N,N), - DIVW-> List(xpr64,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_DIV, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N,N), - DIVUW-> List(xpr64,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_DIVU, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N,N), - REMW-> List(xpr64,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_REM, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N,N), - REMUW-> List(xpr64,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_REMU, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N,N), + DIV-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_DIV, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N), + DIVU-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_DIVU, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N), + REM-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_REM, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N), + REMU-> List(Y, N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_REMU, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N), + DIVW-> List(xpr64,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_DIV, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N), + DIVUW-> List(xpr64,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_DIVU, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N), + REMW-> List(xpr64,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_REM, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N), + REMUW-> List(xpr64,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_REMU, N,M_X, MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N), - SCALL-> List(Y, N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,Y,N,N), - SRET-> List(Y, N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,Y,N,N,N), - FENCE-> List(Y, N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N,Y,N), - FENCE_I-> List(Y, N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,Y,N,N,N,N), - CSRRW-> List(Y, N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.W,N,N,N,N,N), - CSRRS-> List(Y, N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.S,N,N,N,N,N), - CSRRC-> List(Y, N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.C,N,N,N,N,N), - CSRRWI-> List(Y, N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.W,N,N,N,N,N), - CSRRSI-> List(Y, N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.S,N,N,N,N,N), - CSRRCI-> List(Y, N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.C,N,N,N,N,N)) + FENCE-> List(Y, N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,Y,N), + FENCE_I-> List(Y, N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,Y,N,N), + + SFENCE_VM-> List(Y, N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.I,N,N,N), + SCALL-> List(Y, N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.I,N,N,N), + SBREAK-> List(Y, N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.I,N,N,N), + SRET-> List(Y, N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.I,N,N,N), + HCALL-> List(Y, N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.I,N,N,N), + MRET-> List(Y, N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.I,N,N,N), + MRTS-> List(Y, N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.I,N,N,N), + CSRRW-> List(Y, N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.W,N,N,N), + CSRRS-> List(Y, N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.S,N,N,N), + CSRRC-> List(Y, N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.C,N,N,N), + CSRRWI-> List(Y, N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.W,N,N,N), + CSRRSI-> List(Y, N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.S,N,N,N), + CSRRCI-> List(Y, N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.C,N,N,N)) } object FDecode extends DecodeConstants { val table = Array( // jal renf1 fence.i - // | jalr | renf2 | sret - // fp_val| | renx2 | | renf3 | | syscall - // | rocc| | | renx1 s_alu1 mem_val | | | wfd | | | - // val | | br| | | | s_alu2 | imm dw alu | mem_cmd mem_type| | | | div | | | - // | | | | | | | | | | | | | | | | | | | | | wxd | | | fence - // | | | | | | | | | | | | | | | | | | | | | | csr | | | | amo - // | | | | | | | | | | | | | | | | | | | | | | | | | | | | - FCVT_S_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,Y,N,N,CSR.N,N,N,N,N,N), - FCVT_D_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,Y,N,N,CSR.N,N,N,N,N,N), - FSGNJ_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N,N), - FSGNJ_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N,N), - FSGNJX_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N,N), - FSGNJX_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N,N), - FSGNJN_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N,N), - FSGNJN_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N,N), - FMIN_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N,N), - FMIN_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N,N), - FMAX_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N,N), - FMAX_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N,N), - FADD_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N,N), - FADD_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N,N), - FSUB_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N,N), - FSUB_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N,N), - FMUL_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N,N), - FMUL_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N,N), - FMADD_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N,N,N), - FMADD_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N,N,N), - FMSUB_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N,N,N), - FMSUB_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N,N,N), - FNMADD_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N,N,N), - FNMADD_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N,N,N), - FNMSUB_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N,N,N), - FNMSUB_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N,N,N), - FCLASS_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,N,N), - FCLASS_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,N,N), - FMV_X_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,N,N), - FMV_X_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,N,N), - FCVT_W_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,N,N), - FCVT_W_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,N,N), - FCVT_WU_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,N,N), - FCVT_WU_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,N,N), - FCVT_L_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,N,N), - FCVT_L_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,N,N), - FCVT_LU_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,N,N), - FCVT_LU_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,N,N), - FEQ_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N,N,N), - FEQ_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N,N,N), - FLT_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N,N,N), - FLT_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N,N,N), - FLE_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N,N,N), - FLE_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N,N,N), - FMV_S_X-> List(Y, Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N,N,N), - FMV_D_X-> List(Y, Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N,N,N), - FCVT_S_W-> List(Y, Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N,N,N), - FCVT_D_W-> List(Y, Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N,N,N), - FCVT_S_WU-> List(Y, Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N,N,N), - FCVT_D_WU-> List(Y, Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N,N,N), - FCVT_S_L-> List(Y, Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N,N,N), - FCVT_D_L-> List(Y, Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N,N,N), - FCVT_S_LU-> List(Y, Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N,N,N), - FCVT_D_LU-> List(Y, Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N,N,N), - FLW-> List(Y, Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, MT_W, N,N,N,Y,N,N,CSR.N,N,N,N,N,N), - FLD-> List(Y, Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, MT_D, N,N,N,Y,N,N,CSR.N,N,N,N,N,N), - FSW-> List(Y, Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD, Y,M_XWR, MT_W, N,Y,N,N,N,N,CSR.N,N,N,N,N,N), - FSD-> List(Y, Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD, Y,M_XWR, MT_D, N,Y,N,N,N,N,CSR.N,N,N,N,N,N)) + // | jalr | renf2 | + // fp_val| | renx2 | | renf3 | + // | rocc| | | renx1 s_alu1 mem_val | | | wfd | + // val | | br| | | | s_alu2 | imm dw alu | mem_cmd mem_type| | | | div | + // | | | | | | | | | | | | | | | | | | | | | wxd | fence + // | | | | | | | | | | | | | | | | | | | | | | csr | | amo + // | | | | | | | | | | | | | | | | | | | | | | | | | | + FCVT_S_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,Y,N,N,CSR.N,N,N,N), + FCVT_D_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,Y,N,N,CSR.N,N,N,N), + FSGNJ_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N), + FSGNJ_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N), + FSGNJX_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N), + FSGNJX_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N), + FSGNJN_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N), + FSGNJN_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N), + FMIN_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N), + FMIN_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N), + FMAX_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N), + FMAX_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N), + FADD_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N), + FADD_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N), + FSUB_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N), + FSUB_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N), + FMUL_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N), + FMUL_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N), + FMADD_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N), + FMADD_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N), + FMSUB_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N), + FMSUB_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N), + FNMADD_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N), + FNMADD_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N), + FNMSUB_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N), + FNMSUB_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N), + FCLASS_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N), + FCLASS_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N), + FMV_X_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N), + FMV_X_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N), + FCVT_W_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N), + FCVT_W_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N), + FCVT_WU_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N), + FCVT_WU_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N), + FCVT_L_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N), + FCVT_L_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N), + FCVT_LU_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N), + FCVT_LU_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N), + FEQ_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N), + FEQ_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N), + FLT_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N), + FLT_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N), + FLE_S-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N), + FLE_D-> List(Y, Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N), + FMV_S_X-> List(Y, Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N), + FMV_D_X-> List(Y, Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N), + FCVT_S_W-> List(Y, Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N), + FCVT_D_W-> List(Y, Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N), + FCVT_S_WU-> List(Y, Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N), + FCVT_D_WU-> List(Y, Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N), + FCVT_S_L-> List(Y, Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N), + FCVT_D_L-> List(Y, Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N), + FCVT_S_LU-> List(Y, Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N), + FCVT_D_LU-> List(Y, Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N), + FLW-> List(Y, Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, MT_W, N,N,N,Y,N,N,CSR.N,N,N,N), + FLD-> List(Y, Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, Y,M_XRD, MT_D, N,N,N,Y,N,N,CSR.N,N,N,N), + FSW-> List(Y, Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD, Y,M_XWR, MT_W, N,Y,N,N,N,N,CSR.N,N,N,N), + FSD-> List(Y, Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD, Y,M_XWR, MT_D, N,Y,N,N,N,N,CSR.N,N,N,N)) } object RoCCDecode extends DecodeConstants { val table = Array( // jal renf1 fence.i - // | jalr | renf2 | sret - // fp_val| | renx2 | | renf3 | | syscall - // | rocc| | | renx1 s_alu1 mem_val | | | wfd | | | - // val | | br| | | | s_alu2 | imm dw alu | mem_cmd mem_type| | | | div | | | - // | | | | | | | | | | | | | | | | | | | | | wxd | | | fence - // | | | | | | | | | | | | | | | | | | | | | | csr | | | | amo - // | | | | | | | | | | | | | | | | | | | | | | | | | | | | - CUSTOM0-> List(Y, N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N,N), - CUSTOM0_RS1-> List(Y, N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N,N), - CUSTOM0_RS1_RS2-> List(Y, N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N,N), - CUSTOM0_RD-> List(Y, N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - CUSTOM0_RD_RS1-> List(Y, N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - CUSTOM0_RD_RS1_RS2->List(Y, N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - CUSTOM1-> List(Y, N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N,N), - CUSTOM1_RS1-> List(Y, N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N,N), - CUSTOM1_RS1_RS2-> List(Y, N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N,N), - CUSTOM1_RD-> List(Y, N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - CUSTOM1_RD_RS1-> List(Y, N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - CUSTOM1_RD_RS1_RS2->List(Y, N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - CUSTOM2-> List(Y, N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N,N), - CUSTOM2_RS1-> List(Y, N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N,N), - CUSTOM2_RS1_RS2-> List(Y, N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N,N), - CUSTOM2_RD-> List(Y, N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - CUSTOM2_RD_RS1-> List(Y, N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - CUSTOM2_RD_RS1_RS2->List(Y, N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - CUSTOM3-> List(Y, N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N,N), - CUSTOM3_RS1-> List(Y, N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N,N), - CUSTOM3_RS1_RS2-> List(Y, N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N,N), - CUSTOM3_RD-> List(Y, N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - CUSTOM3_RD_RS1-> List(Y, N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N), - CUSTOM3_RD_RS1_RS2->List(Y, N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N)) + // | jalr | renf2 | + // fp_val| | renx2 | | renf3 | + // | rocc| | | renx1 s_alu1 mem_val | | | wfd | + // val | | br| | | | s_alu2 | imm dw alu | mem_cmd mem_type| | | | div | + // | | | | | | | | | | | | | | | | | | | | | wxd | fence + // | | | | | | | | | | | | | | | | | | | | | | csr | | amo + // | | | | | | | | | | | | | | | | | | | | | | | | | | + CUSTOM0-> List(Y, N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N), + CUSTOM0_RS1-> List(Y, N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N), + CUSTOM0_RS1_RS2-> List(Y, N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N), + CUSTOM0_RD-> List(Y, N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + CUSTOM0_RD_RS1-> List(Y, N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + CUSTOM0_RD_RS1_RS2->List(Y, N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + CUSTOM1-> List(Y, N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N), + CUSTOM1_RS1-> List(Y, N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N), + CUSTOM1_RS1_RS2-> List(Y, N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N), + CUSTOM1_RD-> List(Y, N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + CUSTOM1_RD_RS1-> List(Y, N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + CUSTOM1_RD_RS1_RS2->List(Y, N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + CUSTOM2-> List(Y, N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N), + CUSTOM2_RS1-> List(Y, N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N), + CUSTOM2_RS1_RS2-> List(Y, N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N), + CUSTOM2_RD-> List(Y, N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + CUSTOM2_RD_RS1-> List(Y, N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + CUSTOM2_RD_RS1_RS2->List(Y, N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + CUSTOM3-> List(Y, N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N), + CUSTOM3_RS1-> List(Y, N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N), + CUSTOM3_RS1_RS2-> List(Y, N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,N,N), + CUSTOM3_RD-> List(Y, N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + CUSTOM3_RD_RS1-> List(Y, N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N), + CUSTOM3_RD_RS1_RS2->List(Y, N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N)) } class Control extends CoreModule @@ -374,7 +380,8 @@ class Control extends CoreModule val take_pc_wb = Bool() val mem_misprediction = io.dpath.mem_misprediction && mem_reg_valid && (mem_ctrl.branch || mem_ctrl.jalr || mem_ctrl.jal) - val take_pc_mem = mem_reg_valid && (mem_misprediction || mem_reg_flush_pipe) + val want_take_pc_mem = mem_reg_valid && (mem_misprediction || mem_reg_flush_pipe) + val take_pc_mem = want_take_pc_mem && !io.dpath.mem_npc_misaligned val take_pc_mem_wb = take_pc_wb || take_pc_mem val take_pc = take_pc_mem_wb val ctrl_killd = Bool() @@ -388,38 +395,19 @@ class Control extends CoreModule val id_load_use = Bool() val id_reg_fence = Reg(init=Bool(false)) - val sr = io.dpath.status - var id_interrupts = (0 until sr.ip.getWidth).map(i => (sr.im(i) && sr.ip(i), UInt(BigInt(1) << (xLen-1) | i))) - - val (id_interrupt_unmasked, id_interrupt_cause) = checkExceptions(id_interrupts) - val id_interrupt = io.dpath.status.ei && id_interrupt_unmasked - - def checkExceptions(x: Seq[(Bool, UInt)]) = - (x.map(_._1).reduce(_||_), PriorityMux(x)) - - val fp_csrs = CSRs.fcsr :: CSRs.frm :: CSRs.fflags :: Nil - val legal_csrs = collection.mutable.LinkedHashSet(CSRs.all:_*) - if(params(BuildFPU).isEmpty) - legal_csrs --= fp_csrs - - val id_csr_addr = io.dpath.inst(31,20) - val isLegalCSR = Vec.tabulate(1 << id_csr_addr.getWidth)(i => Bool(legal_csrs contains i)) val id_csr_en = id_ctrl.csr != CSR.N - val id_csr_fp = Bool(!params(BuildFPU).isEmpty) && id_csr_en && DecodeLogic(id_csr_addr, fp_csrs, CSRs.all.toSet -- fp_csrs) - val id_csr_wen = id_raddr1 != UInt(0) || !Vec(CSR.S, CSR.C).contains(id_ctrl.csr) - val id_csr_invalid = id_csr_en && !isLegalCSR(id_csr_addr) - val id_csr_privileged = id_csr_en && - (id_csr_addr(11,10) === UInt(3) && id_csr_wen || - id_csr_addr(11,10) === UInt(2) || - id_csr_addr(11,10) === UInt(1) && !io.dpath.status.s || - id_csr_addr(9,8) >= UInt(2) || - id_csr_addr(9,8) === UInt(1) && !io.dpath.status.s && id_csr_wen) - // flush pipeline on CSR writes that may have side effects - val id_csr_flush = { - val safe_csrs = CSRs.sup0 :: CSRs.sup1 :: CSRs.epc :: Nil - id_csr_en && id_csr_wen && !DecodeLogic(id_csr_addr, safe_csrs, legal_csrs -- safe_csrs) - } + val id_system_insn = id_ctrl.csr === CSR.I + val id_csr_ren = (id_ctrl.csr === CSR.S || id_ctrl.csr === CSR.C) && id_raddr1 === UInt(0) + val id_csr = Mux(id_csr_ren, CSR.R, id_ctrl.csr) + val id_csr_addr = io.dpath.inst(31,20) + // this is overly conservative + val safe_csrs = CSRs.sscratch :: CSRs.sepc :: CSRs.mscratch :: CSRs.mepc :: CSRs.mcause :: CSRs.mbadaddr :: Nil + val legal_csrs = collection.mutable.LinkedHashSet(CSRs.all:_*) + val id_csr_flush = id_system_insn || (id_csr_en && !id_csr_ren && !DecodeLogic(id_csr_addr, safe_csrs, legal_csrs -- safe_csrs)) + val id_illegal_insn = !id_ctrl.legal || + id_ctrl.fp && !io.dpath.status.fs.orR || + id_ctrl.rocc && !io.dpath.status.xs.orR // stall decode for fences (now, for AMO.aq; later, for AMO.rl and FENCE) val id_amo_aq = io.dpath.inst(26) val id_amo_rl = io.dpath.inst(25) @@ -430,26 +418,24 @@ class Control extends CoreModule mem_reg_valid && mem_ctrl.rocc || wb_reg_valid && wb_ctrl.rocc) id_reg_fence := id_fence_next || id_reg_fence && id_mem_busy val id_do_fence = id_rocc_busy && id_ctrl.fence || - id_mem_busy && (id_ctrl.amo && id_amo_aq || id_ctrl.fence_i || id_reg_fence && (id_ctrl.mem || id_ctrl.rocc) || id_csr_flush) + id_mem_busy && (id_ctrl.amo && id_amo_aq || id_ctrl.fence_i || id_reg_fence && (id_ctrl.mem || id_ctrl.rocc) || id_csr_en) + + def checkExceptions(x: Seq[(Bool, UInt)]) = + (x.map(_._1).reduce(_||_), PriorityMux(x)) val (id_xcpt, id_cause) = checkExceptions(List( - (id_interrupt, id_interrupt_cause), - (io.imem.resp.bits.xcpt_ma, UInt(Causes.misaligned_fetch)), + (io.dpath.interrupt, io.dpath.interrupt_cause), (io.imem.resp.bits.xcpt_if, UInt(Causes.fault_fetch)), - (!id_ctrl.legal || id_csr_invalid, UInt(Causes.illegal_instruction)), - (id_csr_privileged, UInt(Causes.privileged_instruction)), - (id_ctrl.sret && !io.dpath.status.s, UInt(Causes.privileged_instruction)), - ((id_ctrl.fp || id_csr_fp) && !io.dpath.status.ef,UInt(Causes.fp_disabled)), - (id_ctrl.scall, UInt(Causes.syscall)), - (id_ctrl.rocc && !io.dpath.status.er, UInt(Causes.accelerator_disabled)))) + (id_illegal_insn, UInt(Causes.illegal_instruction)))) ex_reg_valid := !ctrl_killd ex_reg_xcpt := !ctrl_killd && id_xcpt - ex_reg_xcpt_interrupt := id_interrupt && !take_pc && io.imem.resp.valid + ex_reg_xcpt_interrupt := io.dpath.interrupt && !take_pc && io.imem.resp.valid when (id_xcpt) { ex_reg_cause := id_cause } when (!ctrl_killd) { ex_ctrl := id_ctrl + ex_ctrl.csr := id_csr ex_reg_btb_hit := io.imem.btb_resp.valid when (io.imem.btb_resp.valid) { ex_reg_btb_resp := io.imem.btb_resp.bits } ex_reg_flush_pipe := id_ctrl.fence_i || id_csr_flush @@ -488,6 +474,7 @@ class Control extends CoreModule val (mem_xcpt, mem_cause) = checkExceptions(List( (mem_reg_xcpt_interrupt || mem_reg_xcpt, mem_reg_cause), + (want_take_pc_mem && io.dpath.mem_npc_misaligned, UInt(Causes.misaligned_fetch)), (mem_reg_valid && mem_ctrl.mem && io.dmem.xcpt.ma.st, UInt(Causes.misaligned_store)), (mem_reg_valid && mem_ctrl.mem && io.dmem.xcpt.ma.ld, UInt(Causes.misaligned_load)), (mem_reg_valid && mem_ctrl.mem && io.dmem.xcpt.pf.st, UInt(Causes.fault_store)), @@ -551,18 +538,17 @@ class Control extends CoreModule // write CAUSE CSR on an exception io.dpath.exception := wb_reg_xcpt io.dpath.cause := wb_reg_cause - io.dpath.badvaddr_wen := wb_reg_xcpt // don't care for non-memory exceptions + val wb_xcpt = wb_reg_xcpt || io.dpath.csr_xcpt // control transfer from ex/wb - take_pc_wb := replay_wb || wb_reg_xcpt || io.dpath.sret + take_pc_wb := replay_wb || wb_xcpt io.dpath.sel_pc := - Mux(wb_reg_xcpt, PC_PCR, // exception + Mux(wb_xcpt, PC_PCR, // exception or [m|s]ret Mux(replay_wb, PC_WB, // replay - Mux(wb_reg_valid && wb_ctrl.sret, PC_PCR, // sret instruction - PC_MEM))) + PC_MEM)) - io.imem.btb_update.valid := mem_reg_valid && io.dpath.mem_misprediction && ((mem_ctrl.branch && io.dpath.mem_br_taken) || mem_ctrl.jalr || mem_ctrl.jal) && !take_pc_wb + io.imem.btb_update.valid := mem_reg_valid && !io.dpath.mem_npc_misaligned && io.dpath.mem_misprediction && ((mem_ctrl.branch && io.dpath.mem_br_taken) || mem_ctrl.jalr || mem_ctrl.jal) && !take_pc_wb io.imem.btb_update.bits.prediction.valid := mem_reg_btb_hit io.imem.btb_update.bits.prediction.bits := mem_reg_btb_resp io.imem.btb_update.bits.isJump := mem_ctrl.jal || mem_ctrl.jalr @@ -574,7 +560,7 @@ class Control extends CoreModule io.imem.bht_update.bits.prediction.valid := mem_reg_btb_hit io.imem.bht_update.bits.prediction.bits := mem_reg_btb_resp - io.imem.ras_update.valid := io.imem.btb_update.bits.isJump && !take_pc_wb + io.imem.ras_update.valid := io.imem.btb_update.bits.isJump && !io.dpath.mem_npc_misaligned && !take_pc_wb io.imem.ras_update.bits.isCall := mem_ctrl.wxd && io.dpath.mem_waddr(0) io.imem.ras_update.bits.isReturn := mem_ctrl.jalr && io.dpath.mem_rs1_ra io.imem.ras_update.bits.prediction.valid := mem_reg_btb_hit @@ -652,7 +638,7 @@ class Control extends CoreModule id_ctrl.mem && !io.dmem.req.ready || Bool(!params(BuildRoCC).isEmpty) && wb_reg_rocc_pending && id_ctrl.rocc && !io.rocc.cmd.ready || id_do_fence - val ctrl_draind = id_interrupt + val ctrl_draind = io.dpath.interrupt ctrl_killd := !io.imem.resp.valid || take_pc || ctrl_stalld || ctrl_draind io.dpath.killd := take_pc || ctrl_stalld && !ctrl_draind @@ -665,10 +651,9 @@ class Control extends CoreModule io.dpath.mem_ctrl := mem_ctrl io.dpath.ex_valid := ex_reg_valid io.dpath.ll_ready := !(wb_reg_valid && wb_ctrl.wxd) - io.dpath.retire := wb_reg_valid && !replay_wb + io.dpath.retire := wb_reg_valid && !replay_wb && !io.dpath.csr_xcpt io.dpath.wb_wen := io.dpath.retire && wb_ctrl.wxd - io.dpath.csr := Mux(wb_reg_valid, wb_ctrl.csr, CSR.N) - io.dpath.sret := wb_reg_valid && wb_ctrl.sret && !replay_wb + io.dpath.csr_cmd := Mux(wb_reg_valid, wb_ctrl.csr, CSR.N) io.dpath.killm := killm_common io.fpu.valid := !ctrl_killd && id_ctrl.fp @@ -680,9 +665,9 @@ class Control extends CoreModule io.dmem.req.bits.cmd := ex_ctrl.mem_cmd io.dmem.req.bits.typ := ex_ctrl.mem_type io.dmem.req.bits.phys := Bool(false) - io.dmem.sret := io.dpath.sret + io.dmem.sret := wb_xcpt // obviously not an sret, but sufficient io.rocc.cmd.valid := wb_rocc_val - io.rocc.exception := wb_reg_xcpt && sr.er - io.rocc.s := sr.s + io.rocc.exception := wb_xcpt && io.dpath.status.xs != 0 + io.rocc.s := io.dpath.status.prv != 0 // should we just pass all of mstatus? } diff --git a/rocket/src/main/scala/dpath.scala b/rocket/src/main/scala/dpath.scala index f5346b3b..57021306 100644 --- a/rocket/src/main/scala/dpath.scala +++ b/rocket/src/main/scala/dpath.scala @@ -72,7 +72,7 @@ class Datapath extends CoreModule // immediate generation def imm(sel: Bits, inst: Bits) = { - val sign = inst(31).toSInt + val sign = Mux(sel === IMM_Z, SInt(0), inst(31).toSInt) val b30_20 = Mux(sel === IMM_U, inst(30,20).toSInt, sign) val b19_12 = Mux(sel != IMM_U && sel != IMM_UJ, sign, inst(19,12).toSInt) val b11 = Mux(sel === IMM_U || sel === IMM_Z, SInt(0), @@ -172,7 +172,6 @@ class Datapath extends CoreModule pcr.io <> io.fpu pcr.io.rocc <> io.rocc pcr.io.pc := wb_reg_pc - io.ctrl.csr_replay := pcr.io.replay pcr.io.uarch_counters.foreach(_ := Bool(false)) io.ptw.ptbr := pcr.io.ptbr @@ -232,6 +231,7 @@ class Datapath extends CoreModule Mux(io.ctrl.mem_ctrl.jal, imm(IMM_UJ, mem_reg_inst), SInt(4))) val mem_npc = Mux(io.ctrl.mem_ctrl.jalr, Cat(vaSign(mem_reg_wdata, mem_reg_wdata), mem_reg_wdata(vaddrBits-1,0)), mem_br_target).toUInt io.ctrl.mem_misprediction := mem_npc != ex_reg_pc || !io.ctrl.ex_valid + io.ctrl.mem_npc_misaligned := mem_npc(1) io.ctrl.mem_rs1_ra := mem_reg_inst(19,15) === 1 val mem_int_wdata = Mux(io.ctrl.mem_ctrl.jalr, mem_br_target, mem_reg_wdata).toUInt @@ -246,7 +246,7 @@ class Datapath extends CoreModule } wb_wdata := Mux(dmem_resp_valid && dmem_resp_xpu, io.dmem.resp.bits.data_subword, Mux(io.ctrl.ll_wen, ll_wdata, - Mux(io.ctrl.csr != CSR.N, pcr.io.rw.rdata, + Mux(io.ctrl.csr_cmd != CSR.N, pcr.io.rw.rdata, wb_reg_wdata))) val wb_wen = io.ctrl.ll_wen || io.ctrl.wb_wen @@ -259,10 +259,8 @@ class Datapath extends CoreModule // processor control regfile write pcr.io.rw.addr := wb_reg_inst(31,20) - pcr.io.rw.cmd := io.ctrl.csr - pcr.io.rw.wdata := Mux(io.ctrl.csr === CSR.S, pcr.io.rw.rdata | wb_reg_wdata, - Mux(io.ctrl.csr === CSR.C, pcr.io.rw.rdata & ~wb_reg_wdata, - wb_reg_wdata)) + pcr.io.rw.cmd := io.ctrl.csr_cmd + pcr.io.rw.wdata := wb_reg_wdata io.rocc.cmd.bits.inst := new RoCCInstruction().fromBits(wb_reg_inst) io.rocc.cmd.bits.rs1 := wb_reg_wdata diff --git a/rocket/src/main/scala/icache.scala b/rocket/src/main/scala/icache.scala index b3d40b09..39c3c9fd 100644 --- a/rocket/src/main/scala/icache.scala +++ b/rocket/src/main/scala/icache.scala @@ -102,6 +102,7 @@ class Frontend(btb_updates_out_of_order: Boolean = false) extends FrontendModule tlb.io.req.bits.asid := UInt(0) tlb.io.req.bits.passthrough := Bool(false) tlb.io.req.bits.instruction := Bool(true) + tlb.io.req.bits.store := Bool(false) icache.io.mem <> io.mem icache.io.req.valid := !stall && !s0_same_block diff --git a/rocket/src/main/scala/instructions.scala b/rocket/src/main/scala/instructions.scala index 56ebf3c1..c3c015c7 100644 --- a/rocket/src/main/scala/instructions.scala +++ b/rocket/src/main/scala/instructions.scala @@ -95,7 +95,12 @@ object Instructions { def SC_D = Bits("b00011????????????011?????0101111") def SCALL = Bits("b00000000000000000000000001110011") def SBREAK = Bits("b00000000000100000000000001110011") - def SRET = Bits("b10000000000000000000000001110011") + def SRET = Bits("b00010000001000000000000001110011") + def SFENCE_VM = Bits("b000100000100?????000000001110011") + def HCALL = Bits("b00010000000000000000000001110011") + def MCALL = Bits("b00100000000000000000000001110011") + def MRET = Bits("b00110000001000000000000001110011") + def MRTS = Bits("b00110000100100000000000001110011") def CSRRW = Bits("b?????????????????001?????1110011") def CSRRS = Bits("b?????????????????010?????1110011") def CSRRC = Bits("b?????????????????011?????1110011") @@ -193,29 +198,27 @@ object Causes { val misaligned_fetch = 0x0 val fault_fetch = 0x1 val illegal_instruction = 0x2 - val privileged_instruction = 0x3 - val fp_disabled = 0x4 - val syscall = 0x6 + val scall = 0x4 + val hcall = 0x5 + val mcall = 0x6 val breakpoint = 0x7 val misaligned_load = 0x8 - val misaligned_store = 0x9 - val fault_load = 0xa + val fault_load = 0x9 + val misaligned_store = 0xa val fault_store = 0xb - val accelerator_disabled = 0xc val all = { val res = collection.mutable.ArrayBuffer[Int]() res += misaligned_fetch res += fault_fetch res += illegal_instruction - res += privileged_instruction - res += fp_disabled - res += syscall + res += scall + res += hcall + res += mcall res += breakpoint res += misaligned_load - res += misaligned_store res += fault_load + res += misaligned_store res += fault_store - res += accelerator_disabled res.toArray } } @@ -223,29 +226,10 @@ object CSRs { val fflags = 0x1 val frm = 0x2 val fcsr = 0x3 - val stats = 0xc0 - val sup0 = 0x500 - val sup1 = 0x501 - val epc = 0x502 - val badvaddr = 0x503 - val ptbr = 0x504 - val asid = 0x505 - val count = 0x506 - val compare = 0x507 - val evec = 0x508 - val cause = 0x509 - val status = 0x50a - val hartid = 0x50b - val impl = 0x50c - val fatc = 0x50d - val send_ipi = 0x50e - val clear_ipi = 0x50f - val reset = 0x51d - val tohost = 0x51e - val fromhost = 0x51f val cycle = 0xc00 val time = 0xc01 val instret = 0xc02 + val stats = 0xc0 val uarch0 = 0xcc0 val uarch1 = 0xcc1 val uarch2 = 0xcc2 @@ -262,38 +246,43 @@ object CSRs { val uarch13 = 0xccd val uarch14 = 0xcce val uarch15 = 0xccf - val counth = 0x586 + val sstatus = 0x100 + val stvec = 0x101 + val stimecmp = 0x121 + val sscratch = 0x140 + val sepc = 0x141 + val sptbr = 0x188 + val sasid = 0x189 + val scycle = 0x900 + val stime = 0x901 + val sinstret = 0x902 + val scause = 0xd40 + val sbadaddr = 0xd41 + val mstatus = 0x300 + val mscratch = 0x340 + val mepc = 0x341 + val mcause = 0x342 + val mbadaddr = 0x343 + val reset = 0x780 + val tohost = 0x781 + val fromhost = 0x782 + val send_ipi = 0x783 + val hartid = 0xfc0 val cycleh = 0xc80 val timeh = 0xc81 val instreth = 0xc82 + val scycleh = 0x980 + val stimeh = 0x981 + val sinstreth = 0x982 val all = { val res = collection.mutable.ArrayBuffer[Int]() res += fflags res += frm res += fcsr - res += stats - res += sup0 - res += sup1 - res += epc - res += badvaddr - res += ptbr - res += asid - res += count - res += compare - res += evec - res += cause - res += status - res += hartid - res += impl - res += fatc - res += send_ipi - res += clear_ipi - res += reset - res += tohost - res += fromhost res += cycle res += time res += instret + res += stats res += uarch0 res += uarch1 res += uarch2 @@ -310,14 +299,38 @@ object CSRs { res += uarch13 res += uarch14 res += uarch15 + res += sstatus + res += stvec + res += stimecmp + res += sscratch + res += sepc + res += sptbr + res += sasid + res += scycle + res += stime + res += sinstret + res += scause + res += sbadaddr + res += mstatus + res += mscratch + res += mepc + res += mcause + res += mbadaddr + res += reset + res += tohost + res += fromhost + res += send_ipi + res += hartid res.toArray } val all32 = { val res = collection.mutable.ArrayBuffer(all:_*) - res += counth res += cycleh res += timeh res += instreth + res += scycleh + res += stimeh + res += sinstreth res.toArray } } diff --git a/rocket/src/main/scala/nbdcache.scala b/rocket/src/main/scala/nbdcache.scala index 7ea62577..7d124d92 100644 --- a/rocket/src/main/scala/nbdcache.scala +++ b/rocket/src/main/scala/nbdcache.scala @@ -641,6 +641,7 @@ class HellaCache extends L1HellaCacheModule { dtlb.io.req.bits.asid := UInt(0) dtlb.io.req.bits.vpn := s1_req.addr >> pgIdxBits dtlb.io.req.bits.instruction := Bool(false) + dtlb.io.req.bits.store := s1_write when (!dtlb.io.req.ready && !io.cpu.req.bits.phys) { io.cpu.req.ready := Bool(false) } when (io.cpu.req.valid) { diff --git a/rocket/src/main/scala/package.scala b/rocket/src/main/scala/package.scala index e24c646f..75c065be 100644 --- a/rocket/src/main/scala/package.scala +++ b/rocket/src/main/scala/package.scala @@ -3,5 +3,5 @@ package object rocket extends rocket.constants.ScalarOpConstants { - val START_ADDR = 0x2000 + val START_ADDR = 0x100 } diff --git a/rocket/src/main/scala/ptw.scala b/rocket/src/main/scala/ptw.scala index a165cfc0..5ef014c7 100644 --- a/rocket/src/main/scala/ptw.scala +++ b/rocket/src/main/scala/ptw.scala @@ -6,23 +6,29 @@ import Chisel._ import uncore._ import Util._ +class PTWReq extends CoreBundle { + val addr = UInt(width = vpnBits) + val perm = Bits(width = permBits) +} + class PTWResp extends CoreBundle { val error = Bool() val ppn = UInt(width = ppnBits) val perm = Bits(width = permBits) + val dirty = Bool() } class TLBPTWIO extends CoreBundle { - val req = Decoupled(UInt(width = vpnBits)) + val req = Decoupled(new PTWReq) val resp = Valid(new PTWResp).flip - val status = new Status().asInput + val status = new MStatus().asInput val invalidate = Bool(INPUT) } class DatapathPTWIO extends CoreBundle { val ptbr = UInt(INPUT, paddrBits) val invalidate = Bool(INPUT) - val status = new Status().asInput + val status = new MStatus().asInput } class PTW(n: Int) extends CoreModule @@ -37,48 +43,54 @@ class PTW(n: Int) extends CoreModule val bitsPerLevel = vpnBits/levels require(vpnBits == levels * bitsPerLevel) - val s_ready :: s_req :: s_wait :: s_done :: s_error :: Nil = Enum(UInt(), 5) + val s_ready :: s_req :: s_wait :: s_set_dirty :: s_wait_dirty :: s_done :: s_error :: Nil = Enum(UInt(), 7) val state = Reg(init=s_ready) val count = Reg(UInt(width = log2Up(levels))) - val r_req_vpn = Reg(Bits()) + val r_req = Reg(new PTWReq) val r_req_dest = Reg(Bits()) val r_pte = Reg(Bits()) - val vpn_idx = Vec((0 until levels).map(i => (r_req_vpn >> (levels-i-1)*bitsPerLevel)(bitsPerLevel-1,0)))(count) + val vpn_idx = Vec((0 until levels).map(i => (r_req.addr >> (levels-i-1)*bitsPerLevel)(bitsPerLevel-1,0)))(count) - val arb = Module(new RRArbiter(UInt(width = vpnBits), n)) + val arb = Module(new RRArbiter(new PTWReq, n)) arb.io.in <> io.requestor.map(_.req) arb.io.out.ready := state === s_ready + val pte = io.mem.resp.bits.data when (arb.io.out.fire()) { - r_req_vpn := arb.io.out.bits + r_req := arb.io.out.bits r_req_dest := arb.io.chosen - r_pte := Cat(io.dpath.ptbr(paddrBits-1,pgIdxBits), io.mem.resp.bits.data(pgIdxBits-1,0)) + r_pte := Cat(io.dpath.ptbr(paddrBits-1,pgIdxBits), pte(pgIdxBits-1,0)) } - when (io.mem.resp.valid) { - r_pte := io.mem.resp.bits.data + val perm_ok = (pte(8,3) & r_req.perm).orR + val is_store = r_req.perm(1) || r_req.perm(4) + val set_dirty_bit = perm_ok && !pte(1) && (!pte(9) || (is_store && !pte(10))) + when (io.mem.resp.valid && state === s_wait && !set_dirty_bit) { + r_pte := pte } - io.mem.req.valid := state === s_req + io.mem.req.valid := state === s_req || state === s_set_dirty io.mem.req.bits.phys := Bool(true) - io.mem.req.bits.cmd := M_XRD + io.mem.req.bits.cmd := Mux(state === s_set_dirty, M_XA_OR, M_XRD) io.mem.req.bits.typ := MT_D io.mem.req.bits.addr := Cat(r_pte(paddrBits-1,pgIdxBits), vpn_idx).toUInt << log2Up(xLen/8) io.mem.req.bits.kill := Bool(false) + io.mem.req.bits.data := UInt(1<<9) | Mux(is_store, UInt(1<<10), UInt(0)) - val resp_val = state === s_done || state === s_error - val resp_err = state === s_error || state === s_wait + val resp_err = state === s_error + val resp_val = state === s_done || resp_err val r_resp_ppn = io.mem.req.bits.addr >> UInt(pgIdxBits) - val resp_ppn = Vec((0 until levels-1).map(i => Cat(r_resp_ppn >> bitsPerLevel*(levels-i-1), r_req_vpn(bitsPerLevel*(levels-i-1)-1,0))) :+ r_resp_ppn)(count) + val resp_ppn = Vec((0 until levels-1).map(i => Cat(r_resp_ppn >> bitsPerLevel*(levels-i-1), r_req.addr(bitsPerLevel*(levels-i-1)-1,0))) :+ r_resp_ppn)(count) for (i <- 0 until io.requestor.size) { val me = r_req_dest === UInt(i) io.requestor(i).resp.valid := resp_val && me io.requestor(i).resp.bits.error := resp_err io.requestor(i).resp.bits.perm := r_pte(8,3) + io.requestor(i).resp.bits.dirty := r_pte(10) io.requestor(i).resp.bits.ppn := resp_ppn.toUInt io.requestor(i).invalidate := io.dpath.invalidate io.requestor(i).status := io.dpath.status @@ -103,8 +115,10 @@ class PTW(n: Int) extends CoreModule } when (io.mem.resp.valid) { state := s_error - when (io.mem.resp.bits.data(0)) { - when (!io.mem.resp.bits.data(1)) { + when (pte(0)) { + when (set_dirty_bit) { + state := s_set_dirty + }.elsewhen (!pte(1)) { state := s_done }.elsewhen (count < levels-1) { state := s_req @@ -113,6 +127,19 @@ class PTW(n: Int) extends CoreModule } } } + is (s_set_dirty) { + when (io.mem.req.ready) { + state := s_wait_dirty + } + } + is (s_wait_dirty) { + when (io.mem.resp.bits.nack) { + state := s_set_dirty + } + when (io.mem.resp.valid) { + state := s_req + } + } is (s_done) { state := s_ready } diff --git a/rocket/src/main/scala/tlb.scala b/rocket/src/main/scala/tlb.scala index 78254acb..f209002b 100644 --- a/rocket/src/main/scala/tlb.scala +++ b/rocket/src/main/scala/tlb.scala @@ -3,6 +3,7 @@ package rocket import Chisel._ +import Util._ import uncore._ import scala.math._ @@ -19,7 +20,7 @@ abstract class TLBModule extends Module with TLBParameters class CAMIO extends TLBBundle { val clear = Bool(INPUT) - val clear_hit = Bool(INPUT) + val clear_mask = Bits(INPUT, entries) val tag = Bits(INPUT, camTagBits) val hit = Bool(OUTPUT) val hits = UInt(OUTPUT, entries) @@ -40,10 +41,7 @@ class RocketCAM extends TLBModule { cam_tags(io.write_addr) := io.write_tag } when (io.clear) { - vb_array := Bits(0, entries) - } - .elsewhen (io.clear_hit) { - vb_array := vb_array & ~io.hits + vb_array := vb_array & ~io.clear_mask } val hits = (0 until entries).map(i => vb_array(i) && cam_tags(i) === io.tag) @@ -81,6 +79,7 @@ class TLBReq extends CoreBundle { val vpn = UInt(width = vpnBits+1) val passthrough = Bool() val instruction = Bool() + val store = Bool() } class TLBRespNoHitIndex extends CoreBundle { @@ -107,36 +106,38 @@ class TLB extends TLBModule { val state = Reg(init=s_ready) val r_refill_tag = Reg(UInt()) val r_refill_waddr = Reg(UInt()) + val r_req = Reg(new TLBReq) val tag_cam = Module(new RocketCAM) val tag_ram = Mem(io.ptw.resp.bits.ppn.clone, entries) val lookup_tag = Cat(io.req.bits.asid, io.req.bits.vpn).toUInt - tag_cam.io.clear := io.ptw.invalidate - tag_cam.io.clear_hit := io.req.fire() && Mux(io.req.bits.instruction, io.resp.xcpt_if, io.resp.xcpt_ld && io.resp.xcpt_st) tag_cam.io.tag := lookup_tag tag_cam.io.write := state === s_wait && io.ptw.resp.valid tag_cam.io.write_tag := r_refill_tag tag_cam.io.write_addr := r_refill_waddr - val tag_hit = tag_cam.io.hit val tag_hit_addr = OHToUInt(tag_cam.io.hits) // permission bit arrays + val valid_array = Reg(Bits()) // V bit of PTE (not equivalent to CAM tag valid bit!) val ur_array = Reg(Bits()) // user read permission val uw_array = Reg(Bits()) // user write permission val ux_array = Reg(Bits()) // user execute permission val sr_array = Reg(Bits()) // supervisor read permission val sw_array = Reg(Bits()) // supervisor write permission val sx_array = Reg(Bits()) // supervisor execute permission + val dirty_array = Reg(Bits()) // PTE dirty bit when (io.ptw.resp.valid) { + val perm = io.ptw.resp.bits.perm & ~io.ptw.resp.bits.error.toSInt tag_ram(r_refill_waddr) := io.ptw.resp.bits.ppn - val perm = (!io.ptw.resp.bits.error).toSInt & io.ptw.resp.bits.perm - ur_array := ur_array.bitSet(r_refill_waddr, perm(0)) + valid_array := valid_array.bitSet(r_refill_waddr, !io.ptw.resp.bits.error) + ur_array := ur_array.bitSet(r_refill_waddr, perm(0) || perm(2)) uw_array := uw_array.bitSet(r_refill_waddr, perm(1)) ux_array := ux_array.bitSet(r_refill_waddr, perm(2)) - sr_array := sr_array.bitSet(r_refill_waddr, perm(3)) + sr_array := sr_array.bitSet(r_refill_waddr, perm(3) || perm(5)) sw_array := sw_array.bitSet(r_refill_waddr, perm(4)) sx_array := sx_array.bitSet(r_refill_waddr, perm(5)) + dirty_array := dirty_array.bitSet(r_refill_waddr, io.ptw.resp.bits.dirty) } // high if there are any unused (invalid) entries in the TLB @@ -144,30 +145,51 @@ class TLB extends TLBModule { val invalid_entry = PriorityEncoder(~tag_cam.io.valid_bits) val plru = new PseudoLRU(entries) val repl_waddr = Mux(has_invalid_entry, invalid_entry, plru.replace) - + + val priv = Mux(io.ptw.status.prv === PRV_M && !io.req.bits.instruction, io.ptw.status.mprv, io.ptw.status.prv) + val priv_s = priv === PRV_S + val priv_uses_vm = priv <= PRV_S + val req_xwr = Cat(!r_req.store, r_req.store, !(r_req.instruction || r_req.store)) + val req_perm = Cat(req_xwr & priv_s.toSInt, req_xwr & ~priv_s.toSInt) + + val r_array = Mux(priv_s, sr_array, ur_array) + val w_array = Mux(priv_s, sw_array, uw_array) + val x_array = Mux(priv_s, sx_array, ux_array) + + val vm_enabled = io.ptw.status.vm(2) && priv_uses_vm val bad_va = io.req.bits.vpn(vpnBits) != io.req.bits.vpn(vpnBits-1) - val tlb_hit = io.ptw.status.vm && tag_hit - val tlb_miss = io.ptw.status.vm && !tag_hit && !bad_va + // it's only a store hit if the dirty bit is set + val tag_hits = tag_cam.io.hits & (dirty_array | ~(io.req.bits.store.toSInt & w_array)) + val tag_hit = tag_hits.orR + val tlb_hit = vm_enabled && tag_hit + val tlb_miss = vm_enabled && !tag_hit && !bad_va when (io.req.valid && tlb_hit) { plru.access(OHToUInt(tag_cam.io.hits)) } io.req.ready := state === s_ready - io.resp.xcpt_ld := bad_va || tlb_hit && !Mux(io.ptw.status.s, (sr_array & tag_cam.io.hits).orR, (ur_array & tag_cam.io.hits).orR) - io.resp.xcpt_st := bad_va || tlb_hit && !Mux(io.ptw.status.s, (sw_array & tag_cam.io.hits).orR, (uw_array & tag_cam.io.hits).orR) - io.resp.xcpt_if := bad_va || tlb_hit && !Mux(io.ptw.status.s, (sx_array & tag_cam.io.hits).orR, (ux_array & tag_cam.io.hits).orR) + io.resp.xcpt_ld := bad_va || tlb_hit && !(r_array & tag_cam.io.hits).orR + io.resp.xcpt_st := bad_va || tlb_hit && !(w_array & tag_cam.io.hits).orR + io.resp.xcpt_if := bad_va || tlb_hit && !(x_array & tag_cam.io.hits).orR io.resp.miss := tlb_miss - io.resp.ppn := Mux(io.ptw.status.vm && !io.req.bits.passthrough, Mux1H(tag_cam.io.hits, tag_ram), io.req.bits.vpn(params(PPNBits)-1,0)) + io.resp.ppn := Mux(vm_enabled && !io.req.bits.passthrough, Mux1H(tag_cam.io.hits, tag_ram), io.req.bits.vpn(params(PPNBits)-1,0)) io.resp.hit_idx := tag_cam.io.hits + + // clear invalid entries on access, or all entries on a TLB flush + tag_cam.io.clear := io.ptw.invalidate || io.req.fire() + tag_cam.io.clear_mask := ~valid_array | (tag_cam.io.hits & ~tag_hits) + when (io.ptw.invalidate) { tag_cam.io.clear_mask := SInt(-1) } io.ptw.req.valid := state === s_request - io.ptw.req.bits := r_refill_tag + io.ptw.req.bits.addr := r_refill_tag + io.ptw.req.bits.perm := req_perm when (io.req.fire() && tlb_miss) { state := s_request r_refill_tag := lookup_tag r_refill_waddr := repl_waddr + r_req := io.req.bits } when (state === s_request) { when (io.ptw.invalidate) {