New privileged ISA implementation
This commit is contained in:
parent
ebbd14254c
commit
e85c54cc4b
@ -59,5 +59,11 @@ trait ScalarOpConstants {
|
|||||||
val DW_64 = Y
|
val DW_64 = Y
|
||||||
val DW_XPR = 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)
|
val RA = UInt(1, 5)
|
||||||
}
|
}
|
||||||
|
@ -4,34 +4,71 @@ package rocket
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import Util._
|
import Util._
|
||||||
|
import Instructions._
|
||||||
import Node._
|
import Node._
|
||||||
import uncore._
|
import uncore._
|
||||||
import scala.math._
|
import scala.math._
|
||||||
|
|
||||||
class Status extends Bundle {
|
class MStatus extends Bundle {
|
||||||
val ip = Bits(width = 8)
|
val sd = Bool()
|
||||||
val im = Bits(width = 8)
|
val zero6 = UInt(width = 19)
|
||||||
val zero = Bits(width = 7)
|
val ha = UInt(width = 4)
|
||||||
val er = Bool()
|
val sa = UInt(width = 4)
|
||||||
val vm = Bool()
|
val ua = UInt(width = 4)
|
||||||
val s64 = Bool()
|
val zero5 = UInt(width = 1)
|
||||||
val u64 = Bool()
|
val xs = UInt(width = 2)
|
||||||
val ef = Bool()
|
val fs = UInt(width = 2)
|
||||||
val pei = Bool()
|
val mtie = Bool()
|
||||||
val ei = 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 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
|
object CSR
|
||||||
{
|
{
|
||||||
// commands
|
// commands
|
||||||
val SZ = 2
|
val SZ = 3
|
||||||
val X = Bits("b??", 2)
|
val X = UInt.DC(SZ)
|
||||||
val N = Bits(0,2)
|
val N = UInt(0,SZ)
|
||||||
val W = Bits(1,2)
|
val W = UInt(1,SZ)
|
||||||
val S = Bits(2,2)
|
val S = UInt(2,SZ)
|
||||||
val C = Bits(3,2)
|
val C = UInt(3,SZ)
|
||||||
|
val I = UInt(4,SZ)
|
||||||
|
val R = UInt(5,SZ)
|
||||||
}
|
}
|
||||||
|
|
||||||
class CSRFileIO extends CoreBundle {
|
class CSRFileIO extends CoreBundle {
|
||||||
@ -43,40 +80,49 @@ class CSRFileIO extends CoreBundle {
|
|||||||
val wdata = Bits(INPUT, xLen)
|
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 ptbr = UInt(OUTPUT, paddrBits)
|
||||||
val evec = UInt(OUTPUT, vaddrBits+1)
|
val evec = UInt(OUTPUT, vaddrBits+1)
|
||||||
val exception = Bool(INPUT)
|
val exception = Bool(INPUT)
|
||||||
val retire = UInt(INPUT, log2Up(1+retireWidth))
|
val retire = UInt(INPUT, log2Up(1+retireWidth))
|
||||||
val uarch_counters = Vec.fill(16)(UInt(INPUT, log2Up(1+retireWidth)))
|
val uarch_counters = Vec.fill(16)(UInt(INPUT, log2Up(1+retireWidth)))
|
||||||
val cause = UInt(INPUT, xLen)
|
val cause = UInt(INPUT, xLen)
|
||||||
val badvaddr_wen = Bool(INPUT)
|
val mbadaddr_wen = Bool(INPUT)
|
||||||
val pc = UInt(INPUT, vaddrBits+1)
|
val pc = SInt(INPUT, vaddrBits+1)
|
||||||
val sret = Bool(INPUT)
|
val sret = Bool(INPUT)
|
||||||
val fatc = Bool(OUTPUT)
|
val fatc = Bool(OUTPUT)
|
||||||
val replay = Bool(OUTPUT)
|
|
||||||
val time = UInt(OUTPUT, xLen)
|
val time = UInt(OUTPUT, xLen)
|
||||||
val fcsr_rm = Bits(OUTPUT, FPConstants.RM_SZ)
|
val fcsr_rm = Bits(OUTPUT, FPConstants.RM_SZ)
|
||||||
val fcsr_flags = Valid(Bits(width = FPConstants.FLAGS_SZ)).flip
|
val fcsr_flags = Valid(Bits(width = FPConstants.FLAGS_SZ)).flip
|
||||||
val rocc = new RoCCInterface().flip
|
val rocc = new RoCCInterface().flip
|
||||||
|
val interrupt = Bool(OUTPUT)
|
||||||
|
val interrupt_cause = UInt(OUTPUT, xLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
class CSRFile extends CoreModule
|
class CSRFile extends CoreModule
|
||||||
{
|
{
|
||||||
val io = new CSRFileIO
|
val io = new CSRFileIO
|
||||||
|
|
||||||
val reg_epc = Reg(Bits(width = vaddrBits+1))
|
val reg_mstatus = Reg(new MStatus)
|
||||||
val reg_badvaddr = Reg(Bits(width = vaddrBits))
|
val reg_mepc = Reg(SInt(width = vaddrBits+1))
|
||||||
val reg_evec = Reg(Bits(width = vaddrBits))
|
val reg_mcause = Reg(Bits(width = xLen))
|
||||||
val reg_compare = Reg(Bits(width = 32))
|
val reg_mbadaddr = Reg(SInt(width = vaddrBits+1))
|
||||||
val reg_cause = Reg(Bits(width = xLen))
|
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_tohost = Reg(init=Bits(0, xLen))
|
||||||
val reg_fromhost = 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_stats = Reg(init=Bool(false))
|
||||||
val reg_status = Reg(new Status) // reset down below
|
|
||||||
val reg_time = WideCounter(xLen)
|
val reg_time = WideCounter(xLen)
|
||||||
val reg_instret = WideCounter(xLen, io.retire)
|
val reg_instret = WideCounter(xLen, io.retire)
|
||||||
val reg_uarch_counters = io.uarch_counters.map(WideCounter(xLen, _))
|
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 reg_frm = Reg(UInt(width = 3))
|
||||||
|
|
||||||
val r_irq_timer = Reg(init=Bool(false))
|
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 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_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_rep_valid = Reg(Bool()) // don't reset
|
||||||
val host_pcr_bits = Reg(io.host.pcr_req.bits)
|
val host_pcr_bits = Reg(io.host.pcr_req.bits)
|
||||||
io.host.pcr_req.ready := !host_pcr_req_valid && !host_pcr_rep_valid
|
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
|
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 addr = Mux(cpu_ren, io.rw.addr, host_pcr_bits.addr)
|
||||||
val decoded_addr = {
|
val decoded_addr = Map((
|
||||||
val map = for ((v, i) <- CSRs.all.zipWithIndex)
|
for ((v, i) <- CSRs.all.zipWithIndex)
|
||||||
yield v -> UInt(BigInt(1) << i)
|
yield v -> (addr === CSRs.all(i))):_*)
|
||||||
val out = ROM(map)(addr)
|
|
||||||
Map((CSRs.all zip out.toBools):_*)
|
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)))
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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 }
|
||||||
}
|
}
|
||||||
|
|
||||||
val wen = cpu_req_valid || host_pcr_req_fire && host_pcr_bits.rw
|
reg_mbadaddr := io.pc
|
||||||
val wdata = Mux(cpu_req_valid, io.rw.wdata, host_pcr_bits.data)
|
when (io.cause === Causes.fault_load || io.cause === Causes.misaligned_load ||
|
||||||
|
io.cause === Causes.fault_store || io.cause === Causes.misaligned_store) {
|
||||||
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
|
|
||||||
|
|
||||||
when (io.badvaddr_wen) {
|
|
||||||
val wdata = io.rw.wdata
|
val wdata = io.rw.wdata
|
||||||
val (upper, lower) = Split(wdata, vaddrBits)
|
val (upper, lower) = Split(wdata, vaddrBits)
|
||||||
val sign = Mux(lower.toSInt < SInt(0), upper.andR, upper.orR)
|
val sign = Mux(lower.toSInt < SInt(0), upper.andR, upper.orR)
|
||||||
reg_badvaddr := Cat(sign, lower).toSInt
|
reg_mbadaddr := Cat(sign, lower).toSInt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
when (io.exception) {
|
when (insn_ret) {
|
||||||
reg_status.s := true
|
reg_mstatus.ie := reg_mstatus.ie1
|
||||||
reg_status.ps := reg_status.s
|
reg_mstatus.prv := reg_mstatus.prv1
|
||||||
reg_status.ei := false
|
reg_mstatus.prv1 := reg_mstatus.prv2
|
||||||
reg_status.pei := reg_status.ei
|
reg_mstatus.ie1 := reg_mstatus.ie2
|
||||||
reg_epc := io.pc.toSInt
|
reg_mstatus.prv2 := PRV_U
|
||||||
reg_cause := io.cause
|
reg_mstatus.ie2 := true
|
||||||
}
|
}
|
||||||
|
|
||||||
when (io.sret) {
|
when (insn_redirect_trap) {
|
||||||
reg_status.s := reg_status.ps
|
reg_mstatus.prv := PRV_S
|
||||||
reg_status.ei := reg_status.pei
|
reg_sbadaddr := reg_mbadaddr
|
||||||
|
reg_scause := reg_mcause
|
||||||
|
reg_sepc := reg_mepc
|
||||||
}
|
}
|
||||||
|
|
||||||
when (reg_time(reg_compare.getWidth-1,0) === reg_compare) {
|
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
|
r_irq_timer := true
|
||||||
}
|
}
|
||||||
|
|
||||||
io.time := reg_time
|
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.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) }
|
when (host_pcr_req_fire && !host_pcr_bits.rw && decoded_addr(CSRs.tohost)) { reg_tohost := UInt(0) }
|
||||||
|
|
||||||
val read_impl = Bits(2)
|
val read_mstatus = io.status.toBits
|
||||||
val read_ptbr = reg_ptbr(paddrBits-1, pgIdxBits) << UInt(pgIdxBits)
|
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](
|
val read_mapping = collection.mutable.LinkedHashMap[Int,Bits](
|
||||||
CSRs.fflags -> (if (!params(BuildFPU).isEmpty) reg_fflags else UInt(0)),
|
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.fcsr -> (if (!params(BuildFPU).isEmpty) Cat(reg_frm, reg_fflags) else UInt(0)),
|
||||||
CSRs.cycle -> reg_time,
|
CSRs.cycle -> reg_time,
|
||||||
CSRs.time -> reg_time,
|
CSRs.time -> reg_time,
|
||||||
|
CSRs.scycle -> reg_time,
|
||||||
|
CSRs.stime -> reg_time,
|
||||||
CSRs.instret -> reg_instret,
|
CSRs.instret -> reg_instret,
|
||||||
CSRs.sup0 -> reg_sup0,
|
CSRs.sinstret -> reg_instret,
|
||||||
CSRs.sup1 -> reg_sup1,
|
CSRs.mstatus -> read_mstatus,
|
||||||
CSRs.epc -> reg_epc,
|
CSRs.mscratch -> reg_mscratch,
|
||||||
CSRs.badvaddr -> reg_badvaddr,
|
CSRs.mepc -> reg_mepc,
|
||||||
CSRs.ptbr -> read_ptbr,
|
CSRs.mbadaddr -> reg_mbadaddr,
|
||||||
CSRs.asid -> UInt(0),
|
CSRs.mcause -> reg_mcause,
|
||||||
CSRs.count -> reg_time,
|
CSRs.sstatus -> read_sstatus.toBits,
|
||||||
CSRs.compare -> reg_compare,
|
CSRs.sscratch -> reg_sscratch,
|
||||||
CSRs.evec -> reg_evec,
|
CSRs.sepc -> reg_sepc,
|
||||||
CSRs.cause -> reg_cause,
|
CSRs.scause -> reg_scause,
|
||||||
CSRs.status -> io.status.toBits,
|
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.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.stats -> reg_stats,
|
||||||
CSRs.tohost -> reg_tohost,
|
CSRs.tohost -> reg_tohost,
|
||||||
CSRs.fromhost -> reg_fromhost)
|
CSRs.fromhost -> reg_fromhost)
|
||||||
@ -199,46 +320,80 @@ class CSRFile extends CoreModule
|
|||||||
}
|
}
|
||||||
|
|
||||||
when (wen) {
|
when (wen) {
|
||||||
when (decoded_addr(CSRs.status)) {
|
when (decoded_addr(CSRs.mstatus)) {
|
||||||
reg_status := new Status().fromBits(wdata)
|
val new_mstatus = new MStatus().fromBits(wdata)
|
||||||
reg_status.s64 := true
|
reg_mstatus.ssip := new_mstatus.ssip
|
||||||
reg_status.u64 := true
|
reg_mstatus.msip := new_mstatus.msip
|
||||||
reg_status.zero := 0
|
reg_mstatus.stie := new_mstatus.stie
|
||||||
if (!params(UseVM)) reg_status.vm := false
|
reg_mstatus.ie := new_mstatus.ie
|
||||||
if (params(BuildRoCC).isEmpty) reg_status.er := false
|
reg_mstatus.ie1 := new_mstatus.ie1
|
||||||
if (params(BuildFPU).isEmpty) reg_status.ef := false
|
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.fflags)) { reg_fflags := wdata }
|
||||||
when (decoded_addr(CSRs.frm)) { reg_frm := 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.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.mepc)) { reg_mepc := wdata(vaddrBits,0).toSInt }
|
||||||
when (decoded_addr(CSRs.evec)) { reg_evec := wdata(vaddrBits-1,0).toSInt }
|
when (decoded_addr(CSRs.mscratch)) { reg_mscratch := wdata }
|
||||||
when (decoded_addr(CSRs.count)) { reg_time := wdata.toUInt }
|
when (decoded_addr(CSRs.mcause)) { reg_mcause := wdata & UInt((BigInt(1) << (xLen-1)) + 31) /* only implement 5 LSBs and MSB */ }
|
||||||
when (decoded_addr(CSRs.compare)) { reg_compare := wdata(31,0).toUInt; r_irq_timer := Bool(false) }
|
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.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.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.sscratch)) { reg_sscratch := wdata }
|
||||||
when (decoded_addr(CSRs.sup0)) { reg_sup0 := wdata }
|
when (decoded_addr(CSRs.sptbr)) { reg_sptbr := Cat(wdata(paddrBits-1, pgIdxBits), Bits(0, pgIdxBits)).toUInt }
|
||||||
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.stats)) { reg_stats := wdata(0) }
|
when (decoded_addr(CSRs.stats)) { reg_stats := wdata(0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
io.host.ipi_rep.ready := Bool(true)
|
io.host.ipi_rep.ready := true
|
||||||
when (io.host.ipi_rep.valid) { r_irq_ipi := Bool(true) }
|
when (io.host.ipi_rep.valid) { reg_mstatus.msip := true }
|
||||||
|
|
||||||
when(this.reset) {
|
when(this.reset) {
|
||||||
reg_status.ei := false
|
reg_mstatus.zero1 := 0
|
||||||
reg_status.pei := false
|
reg_mstatus.ssip := false
|
||||||
reg_status.ef := false
|
reg_mstatus.hsip := false
|
||||||
reg_status.er := false
|
reg_mstatus.msip := false
|
||||||
reg_status.ps := false
|
reg_mstatus.ie := false
|
||||||
reg_status.s := true
|
reg_mstatus.prv := PRV_M
|
||||||
reg_status.u64 := true
|
reg_mstatus.ie1 := false
|
||||||
reg_status.s64 := true
|
reg_mstatus.prv1 := PRV_S
|
||||||
reg_status.vm := false
|
reg_mstatus.ie2 := false
|
||||||
reg_status.zero := 0
|
reg_mstatus.prv2 := PRV_S
|
||||||
reg_status.im := 0
|
reg_mstatus.mprv := PRV_M
|
||||||
reg_status.ip := 0
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,7 @@ class CtrlDpathIO extends CoreBundle
|
|||||||
val ren = Vec.fill(2)(Bool(OUTPUT))
|
val ren = Vec.fill(2)(Bool(OUTPUT))
|
||||||
val ex_ctrl = new IntCtrlSigs().asOutput
|
val ex_ctrl = new IntCtrlSigs().asOutput
|
||||||
val mem_ctrl = new IntCtrlSigs().asOutput
|
val mem_ctrl = new IntCtrlSigs().asOutput
|
||||||
val csr = UInt(OUTPUT, 3)
|
val csr_cmd = UInt(OUTPUT, CSR.SZ)
|
||||||
val sret = Bool(OUTPUT)
|
|
||||||
val ex_valid = Bool(OUTPUT)
|
val ex_valid = Bool(OUTPUT)
|
||||||
val wb_wen = Bool(OUTPUT)
|
val wb_wen = Bool(OUTPUT)
|
||||||
val bypass = Vec.fill(2)(Bool(OUTPUT))
|
val bypass = Vec.fill(2)(Bool(OUTPUT))
|
||||||
@ -28,11 +27,11 @@ class CtrlDpathIO extends CoreBundle
|
|||||||
val retire = Bool(OUTPUT)
|
val retire = Bool(OUTPUT)
|
||||||
val exception = Bool(OUTPUT)
|
val exception = Bool(OUTPUT)
|
||||||
val cause = UInt(OUTPUT, xLen)
|
val cause = UInt(OUTPUT, xLen)
|
||||||
val badvaddr_wen = Bool(OUTPUT) // high for a load/store access fault
|
|
||||||
// inputs from datapath
|
// inputs from datapath
|
||||||
val inst = Bits(INPUT, 32)
|
val inst = Bits(INPUT, 32)
|
||||||
val mem_br_taken = Bool(INPUT)
|
val mem_br_taken = Bool(INPUT)
|
||||||
val mem_misprediction = Bool(INPUT)
|
val mem_misprediction = Bool(INPUT)
|
||||||
|
val mem_npc_misaligned = Bool(INPUT)
|
||||||
val div_mul_rdy = Bool(INPUT)
|
val div_mul_rdy = Bool(INPUT)
|
||||||
val ll_wen = Bool(INPUT)
|
val ll_wen = Bool(INPUT)
|
||||||
val ll_waddr = UInt(INPUT, 5)
|
val ll_waddr = UInt(INPUT, 5)
|
||||||
@ -40,10 +39,14 @@ class CtrlDpathIO extends CoreBundle
|
|||||||
val mem_rs1_ra = Bool(INPUT)
|
val mem_rs1_ra = Bool(INPUT)
|
||||||
val mem_waddr = UInt(INPUT, 5)
|
val mem_waddr = UInt(INPUT, 5)
|
||||||
val wb_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_clr = Bool(INPUT)
|
||||||
val fp_sboard_clra = UInt(INPUT, 5)
|
val fp_sboard_clra = UInt(INPUT, 5)
|
||||||
|
// inputs from csr file
|
||||||
val csr_replay = Bool(INPUT)
|
val csr_replay = Bool(INPUT)
|
||||||
|
val csr_xcpt = Bool(INPUT)
|
||||||
|
val interrupt = Bool(INPUT)
|
||||||
|
val interrupt_cause = UInt(INPUT, xLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract trait DecodeConstants
|
abstract trait DecodeConstants
|
||||||
@ -52,14 +55,14 @@ abstract trait DecodeConstants
|
|||||||
|
|
||||||
val decode_default =
|
val decode_default =
|
||||||
// jal renf1 fence.i
|
// jal renf1 fence.i
|
||||||
// | jalr | renf2 | sret
|
// | jalr | renf2 |
|
||||||
// fp_val| | renx2 | | renf3 | | syscall
|
// fp_val| | renx2 | | renf3 |
|
||||||
// | rocc| | | renx1 s_alu1 mem_val | | | wfd | | |
|
// | rocc| | | renx1 s_alu1 mem_val | | | wfd |
|
||||||
// val | | br| | | | s_alu2 | imm dw alu | mem_cmd mem_type| | | | div | | |
|
// val | | br| | | | s_alu2 | imm dw alu | mem_cmd mem_type| | | | div |
|
||||||
// | | | | | | | | | | | | | | | | | | | | | wxd | | | fence
|
// | | | | | | | | | | | | | | | | | | | | | wxd | fence
|
||||||
// | | | | | | | | | | | | | | | | | | | | | | csr | | | | amo
|
// | | | | | | | | | | | | | | | | | | | | | | 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)
|
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])]
|
val table: Array[(UInt, List[UInt])]
|
||||||
}
|
}
|
||||||
@ -89,8 +92,6 @@ class IntCtrlSigs extends Bundle {
|
|||||||
val wxd = Bool()
|
val wxd = Bool()
|
||||||
val csr = Bits(width = CSR.SZ)
|
val csr = Bits(width = CSR.SZ)
|
||||||
val fence_i = Bool()
|
val fence_i = Bool()
|
||||||
val sret = Bool()
|
|
||||||
val scall = Bool()
|
|
||||||
val fence = Bool()
|
val fence = Bool()
|
||||||
val amo = Bool()
|
val amo = Bool()
|
||||||
|
|
||||||
@ -98,8 +99,7 @@ class IntCtrlSigs extends Bundle {
|
|||||||
val decoder = DecodeLogic(inst, XDecode.decode_default, table)
|
val decoder = DecodeLogic(inst, XDecode.decode_default, table)
|
||||||
Vec(legal, fp, rocc, branch, jal, jalr, rxs2, rxs1, sel_alu2, sel_alu1,
|
Vec(legal, fp, rocc, branch, jal, jalr, rxs2, rxs1, sel_alu2, sel_alu1,
|
||||||
sel_imm, alu_dw, alu_fn, mem, mem_cmd, mem_type,
|
sel_imm, alu_dw, alu_fn, mem, mem_cmd, mem_type,
|
||||||
rfs1, rfs2, rfs3, wfd, div, wxd,
|
rfs1, rfs2, rfs3, wfd, div, wxd, csr, fence_i, fence, amo) := decoder
|
||||||
csr, fence_i, sret, scall, fence, amo) := decoder
|
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,224 +108,230 @@ object XDecode extends DecodeConstants
|
|||||||
{
|
{
|
||||||
val table = Array(
|
val table = Array(
|
||||||
// jal renf1 fence.i
|
// jal renf1 fence.i
|
||||||
// | jalr | renf2 | sret
|
// | jalr | renf2 |
|
||||||
// fp_val| | renx2 | | renf3 | | syscall
|
// fp_val| | renx2 | | renf3 |
|
||||||
// | rocc| | | renx1 s_alu1 mem_val | | | wfd | | |
|
// | rocc| | | renx1 s_alu1 mem_val | | | wfd |
|
||||||
// val | | br| | | | s_alu2 | imm dw alu | mem_cmd mem_type| | | | div | | |
|
// val | | br| | | | s_alu2 | imm dw alu | mem_cmd mem_type| | | | div |
|
||||||
// | | | | | | | | | | | | | | | | | | | | | wxd | | | fence
|
// | | | | | | | | | | | | | | | | | | | | | wxd | fence
|
||||||
// | | | | | | | | | | | | | | | | | | | | | | csr | | | | amo
|
// | | | | | | | | | | | | | | | | | | | | | | 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),
|
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,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,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,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,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,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),
|
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,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,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),
|
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,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,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,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,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,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,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,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,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,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,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),
|
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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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_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,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,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,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),
|
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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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),
|
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,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,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,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,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,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,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,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,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),
|
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,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,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,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,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),
|
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,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,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,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,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,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,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,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),
|
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),
|
||||||
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_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),
|
||||||
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),
|
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),
|
||||||
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),
|
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),
|
||||||
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),
|
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),
|
||||||
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),
|
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),
|
||||||
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),
|
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),
|
||||||
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),
|
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),
|
||||||
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))
|
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
|
object FDecode extends DecodeConstants
|
||||||
{
|
{
|
||||||
val table = Array(
|
val table = Array(
|
||||||
// jal renf1 fence.i
|
// jal renf1 fence.i
|
||||||
// | jalr | renf2 | sret
|
// | jalr | renf2 |
|
||||||
// fp_val| | renx2 | | renf3 | | syscall
|
// fp_val| | renx2 | | renf3 |
|
||||||
// | rocc| | | renx1 s_alu1 mem_val | | | wfd | | |
|
// | rocc| | | renx1 s_alu1 mem_val | | | wfd |
|
||||||
// val | | br| | | | s_alu2 | imm dw alu | mem_cmd mem_type| | | | div | | |
|
// val | | br| | | | s_alu2 | imm dw alu | mem_cmd mem_type| | | | div |
|
||||||
// | | | | | | | | | | | | | | | | | | | | | wxd | | | fence
|
// | | | | | | | | | | | | | | | | | | | | | wxd | fence
|
||||||
// | | | | | | | | | | | | | | | | | | | | | | csr | | | | amo
|
// | | | | | | | | | | | | | | | | | | | | | | 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_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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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
|
object RoCCDecode extends DecodeConstants
|
||||||
{
|
{
|
||||||
val table = Array(
|
val table = Array(
|
||||||
// jal renf1 fence.i
|
// jal renf1 fence.i
|
||||||
// | jalr | renf2 | sret
|
// | jalr | renf2 |
|
||||||
// fp_val| | renx2 | | renf3 | | syscall
|
// fp_val| | renx2 | | renf3 |
|
||||||
// | rocc| | | renx1 s_alu1 mem_val | | | wfd | | |
|
// | rocc| | | renx1 s_alu1 mem_val | | | wfd |
|
||||||
// val | | br| | | | s_alu2 | imm dw alu | mem_cmd mem_type| | | | div | | |
|
// val | | br| | | | s_alu2 | imm dw alu | mem_cmd mem_type| | | | div |
|
||||||
// | | | | | | | | | | | | | | | | | | | | | wxd | | | fence
|
// | | | | | | | | | | | | | | | | | | | | | wxd | fence
|
||||||
// | | | | | | | | | | | | | | | | | | | | | | csr | | | | amo
|
// | | | | | | | | | | | | | | | | | | | | | | 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-> 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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
|
class Control extends CoreModule
|
||||||
@ -374,7 +380,8 @@ class Control extends CoreModule
|
|||||||
|
|
||||||
val take_pc_wb = Bool()
|
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 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_mem_wb = take_pc_wb || take_pc_mem
|
||||||
val take_pc = take_pc_mem_wb
|
val take_pc = take_pc_mem_wb
|
||||||
val ctrl_killd = Bool()
|
val ctrl_killd = Bool()
|
||||||
@ -388,38 +395,19 @@ class Control extends CoreModule
|
|||||||
val id_load_use = Bool()
|
val id_load_use = Bool()
|
||||||
val id_reg_fence = Reg(init=Bool(false))
|
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_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_system_insn = id_ctrl.csr === CSR.I
|
||||||
val id_csr_wen = id_raddr1 != UInt(0) || !Vec(CSR.S, CSR.C).contains(id_ctrl.csr)
|
val id_csr_ren = (id_ctrl.csr === CSR.S || id_ctrl.csr === CSR.C) && id_raddr1 === UInt(0)
|
||||||
val id_csr_invalid = id_csr_en && !isLegalCSR(id_csr_addr)
|
val id_csr = Mux(id_csr_ren, CSR.R, id_ctrl.csr)
|
||||||
val id_csr_privileged = id_csr_en &&
|
val id_csr_addr = io.dpath.inst(31,20)
|
||||||
(id_csr_addr(11,10) === UInt(3) && id_csr_wen ||
|
// this is overly conservative
|
||||||
id_csr_addr(11,10) === UInt(2) ||
|
val safe_csrs = CSRs.sscratch :: CSRs.sepc :: CSRs.mscratch :: CSRs.mepc :: CSRs.mcause :: CSRs.mbadaddr :: Nil
|
||||||
id_csr_addr(11,10) === UInt(1) && !io.dpath.status.s ||
|
val legal_csrs = collection.mutable.LinkedHashSet(CSRs.all:_*)
|
||||||
id_csr_addr(9,8) >= UInt(2) ||
|
val id_csr_flush = id_system_insn || (id_csr_en && !id_csr_ren && !DecodeLogic(id_csr_addr, safe_csrs, legal_csrs -- safe_csrs))
|
||||||
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_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)
|
// 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_aq = io.dpath.inst(26)
|
||||||
val id_amo_rl = io.dpath.inst(25)
|
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)
|
mem_reg_valid && mem_ctrl.rocc || wb_reg_valid && wb_ctrl.rocc)
|
||||||
id_reg_fence := id_fence_next || id_reg_fence && id_mem_busy
|
id_reg_fence := id_fence_next || id_reg_fence && id_mem_busy
|
||||||
val id_do_fence = id_rocc_busy && id_ctrl.fence ||
|
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(
|
val (id_xcpt, id_cause) = checkExceptions(List(
|
||||||
(id_interrupt, id_interrupt_cause),
|
(io.dpath.interrupt, io.dpath.interrupt_cause),
|
||||||
(io.imem.resp.bits.xcpt_ma, UInt(Causes.misaligned_fetch)),
|
|
||||||
(io.imem.resp.bits.xcpt_if, UInt(Causes.fault_fetch)),
|
(io.imem.resp.bits.xcpt_if, UInt(Causes.fault_fetch)),
|
||||||
(!id_ctrl.legal || id_csr_invalid, UInt(Causes.illegal_instruction)),
|
(id_illegal_insn, 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))))
|
|
||||||
|
|
||||||
ex_reg_valid := !ctrl_killd
|
ex_reg_valid := !ctrl_killd
|
||||||
ex_reg_xcpt := !ctrl_killd && id_xcpt
|
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 (id_xcpt) { ex_reg_cause := id_cause }
|
||||||
|
|
||||||
when (!ctrl_killd) {
|
when (!ctrl_killd) {
|
||||||
ex_ctrl := id_ctrl
|
ex_ctrl := id_ctrl
|
||||||
|
ex_ctrl.csr := id_csr
|
||||||
ex_reg_btb_hit := io.imem.btb_resp.valid
|
ex_reg_btb_hit := io.imem.btb_resp.valid
|
||||||
when (io.imem.btb_resp.valid) { ex_reg_btb_resp := io.imem.btb_resp.bits }
|
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
|
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(
|
val (mem_xcpt, mem_cause) = checkExceptions(List(
|
||||||
(mem_reg_xcpt_interrupt || mem_reg_xcpt, mem_reg_cause),
|
(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.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.ma.ld, UInt(Causes.misaligned_load)),
|
||||||
(mem_reg_valid && mem_ctrl.mem && io.dmem.xcpt.pf.st, UInt(Causes.fault_store)),
|
(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
|
// write CAUSE CSR on an exception
|
||||||
io.dpath.exception := wb_reg_xcpt
|
io.dpath.exception := wb_reg_xcpt
|
||||||
io.dpath.cause := wb_reg_cause
|
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
|
// 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 :=
|
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(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.valid := mem_reg_btb_hit
|
||||||
io.imem.btb_update.bits.prediction.bits := mem_reg_btb_resp
|
io.imem.btb_update.bits.prediction.bits := mem_reg_btb_resp
|
||||||
io.imem.btb_update.bits.isJump := mem_ctrl.jal || mem_ctrl.jalr
|
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.valid := mem_reg_btb_hit
|
||||||
io.imem.bht_update.bits.prediction.bits := mem_reg_btb_resp
|
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.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.isReturn := mem_ctrl.jalr && io.dpath.mem_rs1_ra
|
||||||
io.imem.ras_update.bits.prediction.valid := mem_reg_btb_hit
|
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 ||
|
id_ctrl.mem && !io.dmem.req.ready ||
|
||||||
Bool(!params(BuildRoCC).isEmpty) && wb_reg_rocc_pending && id_ctrl.rocc && !io.rocc.cmd.ready ||
|
Bool(!params(BuildRoCC).isEmpty) && wb_reg_rocc_pending && id_ctrl.rocc && !io.rocc.cmd.ready ||
|
||||||
id_do_fence
|
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
|
ctrl_killd := !io.imem.resp.valid || take_pc || ctrl_stalld || ctrl_draind
|
||||||
|
|
||||||
io.dpath.killd := 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.mem_ctrl := mem_ctrl
|
||||||
io.dpath.ex_valid := ex_reg_valid
|
io.dpath.ex_valid := ex_reg_valid
|
||||||
io.dpath.ll_ready := !(wb_reg_valid && wb_ctrl.wxd)
|
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.wb_wen := io.dpath.retire && wb_ctrl.wxd
|
||||||
io.dpath.csr := Mux(wb_reg_valid, wb_ctrl.csr, CSR.N)
|
io.dpath.csr_cmd := Mux(wb_reg_valid, wb_ctrl.csr, CSR.N)
|
||||||
io.dpath.sret := wb_reg_valid && wb_ctrl.sret && !replay_wb
|
|
||||||
io.dpath.killm := killm_common
|
io.dpath.killm := killm_common
|
||||||
|
|
||||||
io.fpu.valid := !ctrl_killd && id_ctrl.fp
|
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.cmd := ex_ctrl.mem_cmd
|
||||||
io.dmem.req.bits.typ := ex_ctrl.mem_type
|
io.dmem.req.bits.typ := ex_ctrl.mem_type
|
||||||
io.dmem.req.bits.phys := Bool(false)
|
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.cmd.valid := wb_rocc_val
|
||||||
io.rocc.exception := wb_reg_xcpt && sr.er
|
io.rocc.exception := wb_xcpt && io.dpath.status.xs != 0
|
||||||
io.rocc.s := sr.s
|
io.rocc.s := io.dpath.status.prv != 0 // should we just pass all of mstatus?
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ class Datapath extends CoreModule
|
|||||||
|
|
||||||
// immediate generation
|
// immediate generation
|
||||||
def imm(sel: Bits, inst: Bits) = {
|
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 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 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),
|
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 <> io.fpu
|
||||||
pcr.io.rocc <> io.rocc
|
pcr.io.rocc <> io.rocc
|
||||||
pcr.io.pc := wb_reg_pc
|
pcr.io.pc := wb_reg_pc
|
||||||
io.ctrl.csr_replay := pcr.io.replay
|
|
||||||
pcr.io.uarch_counters.foreach(_ := Bool(false))
|
pcr.io.uarch_counters.foreach(_ := Bool(false))
|
||||||
|
|
||||||
io.ptw.ptbr := pcr.io.ptbr
|
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)))
|
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
|
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_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
|
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
|
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,
|
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.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)))
|
wb_reg_wdata)))
|
||||||
|
|
||||||
val wb_wen = io.ctrl.ll_wen || io.ctrl.wb_wen
|
val wb_wen = io.ctrl.ll_wen || io.ctrl.wb_wen
|
||||||
@ -259,10 +259,8 @@ class Datapath extends CoreModule
|
|||||||
|
|
||||||
// processor control regfile write
|
// processor control regfile write
|
||||||
pcr.io.rw.addr := wb_reg_inst(31,20)
|
pcr.io.rw.addr := wb_reg_inst(31,20)
|
||||||
pcr.io.rw.cmd := io.ctrl.csr
|
pcr.io.rw.cmd := io.ctrl.csr_cmd
|
||||||
pcr.io.rw.wdata := Mux(io.ctrl.csr === CSR.S, pcr.io.rw.rdata | wb_reg_wdata,
|
pcr.io.rw.wdata := wb_reg_wdata
|
||||||
Mux(io.ctrl.csr === CSR.C, pcr.io.rw.rdata & ~wb_reg_wdata,
|
|
||||||
wb_reg_wdata))
|
|
||||||
|
|
||||||
io.rocc.cmd.bits.inst := new RoCCInstruction().fromBits(wb_reg_inst)
|
io.rocc.cmd.bits.inst := new RoCCInstruction().fromBits(wb_reg_inst)
|
||||||
io.rocc.cmd.bits.rs1 := wb_reg_wdata
|
io.rocc.cmd.bits.rs1 := wb_reg_wdata
|
||||||
|
@ -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.asid := UInt(0)
|
||||||
tlb.io.req.bits.passthrough := Bool(false)
|
tlb.io.req.bits.passthrough := Bool(false)
|
||||||
tlb.io.req.bits.instruction := Bool(true)
|
tlb.io.req.bits.instruction := Bool(true)
|
||||||
|
tlb.io.req.bits.store := Bool(false)
|
||||||
|
|
||||||
icache.io.mem <> io.mem
|
icache.io.mem <> io.mem
|
||||||
icache.io.req.valid := !stall && !s0_same_block
|
icache.io.req.valid := !stall && !s0_same_block
|
||||||
|
@ -95,7 +95,12 @@ object Instructions {
|
|||||||
def SC_D = Bits("b00011????????????011?????0101111")
|
def SC_D = Bits("b00011????????????011?????0101111")
|
||||||
def SCALL = Bits("b00000000000000000000000001110011")
|
def SCALL = Bits("b00000000000000000000000001110011")
|
||||||
def SBREAK = Bits("b00000000000100000000000001110011")
|
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 CSRRW = Bits("b?????????????????001?????1110011")
|
||||||
def CSRRS = Bits("b?????????????????010?????1110011")
|
def CSRRS = Bits("b?????????????????010?????1110011")
|
||||||
def CSRRC = Bits("b?????????????????011?????1110011")
|
def CSRRC = Bits("b?????????????????011?????1110011")
|
||||||
@ -193,29 +198,27 @@ object Causes {
|
|||||||
val misaligned_fetch = 0x0
|
val misaligned_fetch = 0x0
|
||||||
val fault_fetch = 0x1
|
val fault_fetch = 0x1
|
||||||
val illegal_instruction = 0x2
|
val illegal_instruction = 0x2
|
||||||
val privileged_instruction = 0x3
|
val scall = 0x4
|
||||||
val fp_disabled = 0x4
|
val hcall = 0x5
|
||||||
val syscall = 0x6
|
val mcall = 0x6
|
||||||
val breakpoint = 0x7
|
val breakpoint = 0x7
|
||||||
val misaligned_load = 0x8
|
val misaligned_load = 0x8
|
||||||
val misaligned_store = 0x9
|
val fault_load = 0x9
|
||||||
val fault_load = 0xa
|
val misaligned_store = 0xa
|
||||||
val fault_store = 0xb
|
val fault_store = 0xb
|
||||||
val accelerator_disabled = 0xc
|
|
||||||
val all = {
|
val all = {
|
||||||
val res = collection.mutable.ArrayBuffer[Int]()
|
val res = collection.mutable.ArrayBuffer[Int]()
|
||||||
res += misaligned_fetch
|
res += misaligned_fetch
|
||||||
res += fault_fetch
|
res += fault_fetch
|
||||||
res += illegal_instruction
|
res += illegal_instruction
|
||||||
res += privileged_instruction
|
res += scall
|
||||||
res += fp_disabled
|
res += hcall
|
||||||
res += syscall
|
res += mcall
|
||||||
res += breakpoint
|
res += breakpoint
|
||||||
res += misaligned_load
|
res += misaligned_load
|
||||||
res += misaligned_store
|
|
||||||
res += fault_load
|
res += fault_load
|
||||||
|
res += misaligned_store
|
||||||
res += fault_store
|
res += fault_store
|
||||||
res += accelerator_disabled
|
|
||||||
res.toArray
|
res.toArray
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,29 +226,10 @@ object CSRs {
|
|||||||
val fflags = 0x1
|
val fflags = 0x1
|
||||||
val frm = 0x2
|
val frm = 0x2
|
||||||
val fcsr = 0x3
|
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 cycle = 0xc00
|
||||||
val time = 0xc01
|
val time = 0xc01
|
||||||
val instret = 0xc02
|
val instret = 0xc02
|
||||||
|
val stats = 0xc0
|
||||||
val uarch0 = 0xcc0
|
val uarch0 = 0xcc0
|
||||||
val uarch1 = 0xcc1
|
val uarch1 = 0xcc1
|
||||||
val uarch2 = 0xcc2
|
val uarch2 = 0xcc2
|
||||||
@ -262,38 +246,43 @@ object CSRs {
|
|||||||
val uarch13 = 0xccd
|
val uarch13 = 0xccd
|
||||||
val uarch14 = 0xcce
|
val uarch14 = 0xcce
|
||||||
val uarch15 = 0xccf
|
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 cycleh = 0xc80
|
||||||
val timeh = 0xc81
|
val timeh = 0xc81
|
||||||
val instreth = 0xc82
|
val instreth = 0xc82
|
||||||
|
val scycleh = 0x980
|
||||||
|
val stimeh = 0x981
|
||||||
|
val sinstreth = 0x982
|
||||||
val all = {
|
val all = {
|
||||||
val res = collection.mutable.ArrayBuffer[Int]()
|
val res = collection.mutable.ArrayBuffer[Int]()
|
||||||
res += fflags
|
res += fflags
|
||||||
res += frm
|
res += frm
|
||||||
res += fcsr
|
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 += cycle
|
||||||
res += time
|
res += time
|
||||||
res += instret
|
res += instret
|
||||||
|
res += stats
|
||||||
res += uarch0
|
res += uarch0
|
||||||
res += uarch1
|
res += uarch1
|
||||||
res += uarch2
|
res += uarch2
|
||||||
@ -310,14 +299,38 @@ object CSRs {
|
|||||||
res += uarch13
|
res += uarch13
|
||||||
res += uarch14
|
res += uarch14
|
||||||
res += uarch15
|
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
|
res.toArray
|
||||||
}
|
}
|
||||||
val all32 = {
|
val all32 = {
|
||||||
val res = collection.mutable.ArrayBuffer(all:_*)
|
val res = collection.mutable.ArrayBuffer(all:_*)
|
||||||
res += counth
|
|
||||||
res += cycleh
|
res += cycleh
|
||||||
res += timeh
|
res += timeh
|
||||||
res += instreth
|
res += instreth
|
||||||
|
res += scycleh
|
||||||
|
res += stimeh
|
||||||
|
res += sinstreth
|
||||||
res.toArray
|
res.toArray
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -641,6 +641,7 @@ class HellaCache extends L1HellaCacheModule {
|
|||||||
dtlb.io.req.bits.asid := UInt(0)
|
dtlb.io.req.bits.asid := UInt(0)
|
||||||
dtlb.io.req.bits.vpn := s1_req.addr >> pgIdxBits
|
dtlb.io.req.bits.vpn := s1_req.addr >> pgIdxBits
|
||||||
dtlb.io.req.bits.instruction := Bool(false)
|
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 (!dtlb.io.req.ready && !io.cpu.req.bits.phys) { io.cpu.req.ready := Bool(false) }
|
||||||
|
|
||||||
when (io.cpu.req.valid) {
|
when (io.cpu.req.valid) {
|
||||||
|
@ -3,5 +3,5 @@
|
|||||||
package object rocket extends
|
package object rocket extends
|
||||||
rocket.constants.ScalarOpConstants
|
rocket.constants.ScalarOpConstants
|
||||||
{
|
{
|
||||||
val START_ADDR = 0x2000
|
val START_ADDR = 0x100
|
||||||
}
|
}
|
||||||
|
@ -6,23 +6,29 @@ import Chisel._
|
|||||||
import uncore._
|
import uncore._
|
||||||
import Util._
|
import Util._
|
||||||
|
|
||||||
|
class PTWReq extends CoreBundle {
|
||||||
|
val addr = UInt(width = vpnBits)
|
||||||
|
val perm = Bits(width = permBits)
|
||||||
|
}
|
||||||
|
|
||||||
class PTWResp extends CoreBundle {
|
class PTWResp extends CoreBundle {
|
||||||
val error = Bool()
|
val error = Bool()
|
||||||
val ppn = UInt(width = ppnBits)
|
val ppn = UInt(width = ppnBits)
|
||||||
val perm = Bits(width = permBits)
|
val perm = Bits(width = permBits)
|
||||||
|
val dirty = Bool()
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLBPTWIO extends CoreBundle {
|
class TLBPTWIO extends CoreBundle {
|
||||||
val req = Decoupled(UInt(width = vpnBits))
|
val req = Decoupled(new PTWReq)
|
||||||
val resp = Valid(new PTWResp).flip
|
val resp = Valid(new PTWResp).flip
|
||||||
val status = new Status().asInput
|
val status = new MStatus().asInput
|
||||||
val invalidate = Bool(INPUT)
|
val invalidate = Bool(INPUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
class DatapathPTWIO extends CoreBundle {
|
class DatapathPTWIO extends CoreBundle {
|
||||||
val ptbr = UInt(INPUT, paddrBits)
|
val ptbr = UInt(INPUT, paddrBits)
|
||||||
val invalidate = Bool(INPUT)
|
val invalidate = Bool(INPUT)
|
||||||
val status = new Status().asInput
|
val status = new MStatus().asInput
|
||||||
}
|
}
|
||||||
|
|
||||||
class PTW(n: Int) extends CoreModule
|
class PTW(n: Int) extends CoreModule
|
||||||
@ -37,48 +43,54 @@ class PTW(n: Int) extends CoreModule
|
|||||||
val bitsPerLevel = vpnBits/levels
|
val bitsPerLevel = vpnBits/levels
|
||||||
require(vpnBits == levels * bitsPerLevel)
|
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 state = Reg(init=s_ready)
|
||||||
val count = Reg(UInt(width = log2Up(levels)))
|
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_req_dest = Reg(Bits())
|
||||||
val r_pte = 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.in <> io.requestor.map(_.req)
|
||||||
arb.io.out.ready := state === s_ready
|
arb.io.out.ready := state === s_ready
|
||||||
|
|
||||||
|
val pte = io.mem.resp.bits.data
|
||||||
when (arb.io.out.fire()) {
|
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_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) {
|
val perm_ok = (pte(8,3) & r_req.perm).orR
|
||||||
r_pte := io.mem.resp.bits.data
|
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.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.typ := MT_D
|
||||||
io.mem.req.bits.addr := Cat(r_pte(paddrBits-1,pgIdxBits), vpn_idx).toUInt << log2Up(xLen/8)
|
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.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
|
||||||
val resp_err = state === s_error || state === s_wait
|
val resp_val = state === s_done || resp_err
|
||||||
|
|
||||||
val r_resp_ppn = io.mem.req.bits.addr >> UInt(pgIdxBits)
|
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) {
|
for (i <- 0 until io.requestor.size) {
|
||||||
val me = r_req_dest === UInt(i)
|
val me = r_req_dest === UInt(i)
|
||||||
io.requestor(i).resp.valid := resp_val && me
|
io.requestor(i).resp.valid := resp_val && me
|
||||||
io.requestor(i).resp.bits.error := resp_err
|
io.requestor(i).resp.bits.error := resp_err
|
||||||
io.requestor(i).resp.bits.perm := r_pte(8,3)
|
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).resp.bits.ppn := resp_ppn.toUInt
|
||||||
io.requestor(i).invalidate := io.dpath.invalidate
|
io.requestor(i).invalidate := io.dpath.invalidate
|
||||||
io.requestor(i).status := io.dpath.status
|
io.requestor(i).status := io.dpath.status
|
||||||
@ -103,8 +115,10 @@ class PTW(n: Int) extends CoreModule
|
|||||||
}
|
}
|
||||||
when (io.mem.resp.valid) {
|
when (io.mem.resp.valid) {
|
||||||
state := s_error
|
state := s_error
|
||||||
when (io.mem.resp.bits.data(0)) {
|
when (pte(0)) {
|
||||||
when (!io.mem.resp.bits.data(1)) {
|
when (set_dirty_bit) {
|
||||||
|
state := s_set_dirty
|
||||||
|
}.elsewhen (!pte(1)) {
|
||||||
state := s_done
|
state := s_done
|
||||||
}.elsewhen (count < levels-1) {
|
}.elsewhen (count < levels-1) {
|
||||||
state := s_req
|
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) {
|
is (s_done) {
|
||||||
state := s_ready
|
state := s_ready
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
package rocket
|
package rocket
|
||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
|
import Util._
|
||||||
import uncore._
|
import uncore._
|
||||||
import scala.math._
|
import scala.math._
|
||||||
|
|
||||||
@ -19,7 +20,7 @@ abstract class TLBModule extends Module with TLBParameters
|
|||||||
|
|
||||||
class CAMIO extends TLBBundle {
|
class CAMIO extends TLBBundle {
|
||||||
val clear = Bool(INPUT)
|
val clear = Bool(INPUT)
|
||||||
val clear_hit = Bool(INPUT)
|
val clear_mask = Bits(INPUT, entries)
|
||||||
val tag = Bits(INPUT, camTagBits)
|
val tag = Bits(INPUT, camTagBits)
|
||||||
val hit = Bool(OUTPUT)
|
val hit = Bool(OUTPUT)
|
||||||
val hits = UInt(OUTPUT, entries)
|
val hits = UInt(OUTPUT, entries)
|
||||||
@ -40,10 +41,7 @@ class RocketCAM extends TLBModule {
|
|||||||
cam_tags(io.write_addr) := io.write_tag
|
cam_tags(io.write_addr) := io.write_tag
|
||||||
}
|
}
|
||||||
when (io.clear) {
|
when (io.clear) {
|
||||||
vb_array := Bits(0, entries)
|
vb_array := vb_array & ~io.clear_mask
|
||||||
}
|
|
||||||
.elsewhen (io.clear_hit) {
|
|
||||||
vb_array := vb_array & ~io.hits
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val hits = (0 until entries).map(i => vb_array(i) && cam_tags(i) === io.tag)
|
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 vpn = UInt(width = vpnBits+1)
|
||||||
val passthrough = Bool()
|
val passthrough = Bool()
|
||||||
val instruction = Bool()
|
val instruction = Bool()
|
||||||
|
val store = Bool()
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLBRespNoHitIndex extends CoreBundle {
|
class TLBRespNoHitIndex extends CoreBundle {
|
||||||
@ -107,36 +106,38 @@ class TLB extends TLBModule {
|
|||||||
val state = Reg(init=s_ready)
|
val state = Reg(init=s_ready)
|
||||||
val r_refill_tag = Reg(UInt())
|
val r_refill_tag = Reg(UInt())
|
||||||
val r_refill_waddr = Reg(UInt())
|
val r_refill_waddr = Reg(UInt())
|
||||||
|
val r_req = Reg(new TLBReq)
|
||||||
|
|
||||||
val tag_cam = Module(new RocketCAM)
|
val tag_cam = Module(new RocketCAM)
|
||||||
val tag_ram = Mem(io.ptw.resp.bits.ppn.clone, entries)
|
val tag_ram = Mem(io.ptw.resp.bits.ppn.clone, entries)
|
||||||
|
|
||||||
val lookup_tag = Cat(io.req.bits.asid, io.req.bits.vpn).toUInt
|
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.tag := lookup_tag
|
||||||
tag_cam.io.write := state === s_wait && io.ptw.resp.valid
|
tag_cam.io.write := state === s_wait && io.ptw.resp.valid
|
||||||
tag_cam.io.write_tag := r_refill_tag
|
tag_cam.io.write_tag := r_refill_tag
|
||||||
tag_cam.io.write_addr := r_refill_waddr
|
tag_cam.io.write_addr := r_refill_waddr
|
||||||
val tag_hit = tag_cam.io.hit
|
|
||||||
val tag_hit_addr = OHToUInt(tag_cam.io.hits)
|
val tag_hit_addr = OHToUInt(tag_cam.io.hits)
|
||||||
|
|
||||||
// permission bit arrays
|
// 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 ur_array = Reg(Bits()) // user read permission
|
||||||
val uw_array = Reg(Bits()) // user write permission
|
val uw_array = Reg(Bits()) // user write permission
|
||||||
val ux_array = Reg(Bits()) // user execute permission
|
val ux_array = Reg(Bits()) // user execute permission
|
||||||
val sr_array = Reg(Bits()) // supervisor read permission
|
val sr_array = Reg(Bits()) // supervisor read permission
|
||||||
val sw_array = Reg(Bits()) // supervisor write permission
|
val sw_array = Reg(Bits()) // supervisor write permission
|
||||||
val sx_array = Reg(Bits()) // supervisor execute permission
|
val sx_array = Reg(Bits()) // supervisor execute permission
|
||||||
|
val dirty_array = Reg(Bits()) // PTE dirty bit
|
||||||
when (io.ptw.resp.valid) {
|
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
|
tag_ram(r_refill_waddr) := io.ptw.resp.bits.ppn
|
||||||
val perm = (!io.ptw.resp.bits.error).toSInt & io.ptw.resp.bits.perm
|
valid_array := valid_array.bitSet(r_refill_waddr, !io.ptw.resp.bits.error)
|
||||||
ur_array := ur_array.bitSet(r_refill_waddr, perm(0))
|
ur_array := ur_array.bitSet(r_refill_waddr, perm(0) || perm(2))
|
||||||
uw_array := uw_array.bitSet(r_refill_waddr, perm(1))
|
uw_array := uw_array.bitSet(r_refill_waddr, perm(1))
|
||||||
ux_array := ux_array.bitSet(r_refill_waddr, perm(2))
|
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))
|
sw_array := sw_array.bitSet(r_refill_waddr, perm(4))
|
||||||
sx_array := sx_array.bitSet(r_refill_waddr, perm(5))
|
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
|
// high if there are any unused (invalid) entries in the TLB
|
||||||
@ -145,29 +146,50 @@ class TLB extends TLBModule {
|
|||||||
val plru = new PseudoLRU(entries)
|
val plru = new PseudoLRU(entries)
|
||||||
val repl_waddr = Mux(has_invalid_entry, invalid_entry, plru.replace)
|
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 bad_va = io.req.bits.vpn(vpnBits) != io.req.bits.vpn(vpnBits-1)
|
||||||
val tlb_hit = io.ptw.status.vm && tag_hit
|
// it's only a store hit if the dirty bit is set
|
||||||
val tlb_miss = io.ptw.status.vm && !tag_hit && !bad_va
|
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) {
|
when (io.req.valid && tlb_hit) {
|
||||||
plru.access(OHToUInt(tag_cam.io.hits))
|
plru.access(OHToUInt(tag_cam.io.hits))
|
||||||
}
|
}
|
||||||
|
|
||||||
io.req.ready := state === s_ready
|
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_ld := bad_va || tlb_hit && !(r_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_st := bad_va || tlb_hit && !(w_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_if := bad_va || tlb_hit && !(x_array & tag_cam.io.hits).orR
|
||||||
io.resp.miss := tlb_miss
|
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
|
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.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) {
|
when (io.req.fire() && tlb_miss) {
|
||||||
state := s_request
|
state := s_request
|
||||||
r_refill_tag := lookup_tag
|
r_refill_tag := lookup_tag
|
||||||
r_refill_waddr := repl_waddr
|
r_refill_waddr := repl_waddr
|
||||||
|
r_req := io.req.bits
|
||||||
}
|
}
|
||||||
when (state === s_request) {
|
when (state === s_request) {
|
||||||
when (io.ptw.invalidate) {
|
when (io.ptw.invalidate) {
|
||||||
|
Loading…
Reference in New Issue
Block a user