refactor PCR file
This commit is contained in:
@ -54,66 +54,101 @@ class rocketDpathBTB(entries: Int) extends Component
|
||||
io.target := Mux1H(hits, targets)
|
||||
}
|
||||
|
||||
class ioDpathPCR(implicit conf: RocketConfiguration) extends Bundle
|
||||
{
|
||||
val host = new ioHTIF(conf.ntiles)
|
||||
val r = new ioReadPort(32, 64)
|
||||
val w = new ioWritePort(32, 64)
|
||||
|
||||
val status = Bits(OUTPUT, 32);
|
||||
val ptbr = UFix(OUTPUT, PADDR_BITS);
|
||||
val evec = UFix(OUTPUT, VADDR_BITS);
|
||||
val exception = Bool(INPUT);
|
||||
val cause = UFix(INPUT, 6);
|
||||
val badvaddr_wen = Bool(INPUT);
|
||||
val vec_irq_aux = Bits(INPUT, 64)
|
||||
val vec_irq_aux_wen = Bool(INPUT)
|
||||
val pc = UFix(INPUT, VADDR_BITS+1);
|
||||
val eret = Bool(INPUT);
|
||||
val ei = Bool(INPUT);
|
||||
val di = Bool(INPUT);
|
||||
val ptbr_wen = Bool(OUTPUT);
|
||||
val irq_timer = Bool(OUTPUT);
|
||||
val irq_ipi = Bool(OUTPUT);
|
||||
val replay = Bool(OUTPUT)
|
||||
val vecbank = Bits(OUTPUT, 8)
|
||||
val vecbankcnt = UFix(OUTPUT, 4)
|
||||
val vec_appvl = UFix(INPUT, 12)
|
||||
val vec_nxregs = UFix(INPUT, 6)
|
||||
val vec_nfregs = UFix(INPUT, 6)
|
||||
class Status extends Bundle {
|
||||
val im = Bits(width = 8)
|
||||
val zero = Bits(width = 7)
|
||||
val vm = Bool()
|
||||
val s64 = Bool()
|
||||
val u64 = Bool()
|
||||
val s = Bool()
|
||||
val ps = Bool()
|
||||
val ec = Bool()
|
||||
val ev = Bool()
|
||||
val ef = Bool()
|
||||
val et = Bool()
|
||||
}
|
||||
|
||||
class rocketDpathPCR(implicit conf: RocketConfiguration) extends Component
|
||||
object PCR
|
||||
{
|
||||
val io = new ioDpathPCR
|
||||
|
||||
val reg_epc = Reg{Fix()}
|
||||
val reg_badvaddr = Reg{Fix()}
|
||||
val reg_ebase = Reg{Fix()}
|
||||
// commands
|
||||
val SZ = 3
|
||||
val X = Bits("b???", 3)
|
||||
val N = Bits(0,3)
|
||||
val F = Bits(1,3) // mfpcr
|
||||
val T = Bits(4,3) // mtpcr
|
||||
val C = Bits(6,3) // clearpcr
|
||||
val S = Bits(7,3) // setpcr
|
||||
|
||||
// regs
|
||||
val STATUS = 0
|
||||
val EPC = 1
|
||||
val BADVADDR = 2
|
||||
val EVEC = 3
|
||||
val COUNT = 4
|
||||
val COMPARE = 5
|
||||
val CAUSE = 6
|
||||
val PTBR = 7
|
||||
val SEND_IPI = 8
|
||||
val CLR_IPI = 9
|
||||
val COREID = 10
|
||||
val IMPL = 11
|
||||
val K0 = 12
|
||||
val K1 = 13
|
||||
val VECBANK = 18
|
||||
val VECCFG = 19
|
||||
val RESET = 29
|
||||
val TOHOST = 30
|
||||
val FROMHOST = 31
|
||||
}
|
||||
|
||||
class PCR(implicit conf: RocketConfiguration) extends Component
|
||||
{
|
||||
val io = new Bundle {
|
||||
val host = new ioHTIF(conf.ntiles)
|
||||
val r = new ioReadPort(conf.nxpr, conf.xprlen)
|
||||
val w = new ioWritePort(conf.nxpr, conf.xprlen)
|
||||
|
||||
val status = new Status().asOutput
|
||||
val ptbr = UFix(OUTPUT, PADDR_BITS)
|
||||
val evec = UFix(OUTPUT, VADDR_BITS)
|
||||
val exception = Bool(INPUT)
|
||||
val cause = UFix(INPUT, 6)
|
||||
val badvaddr_wen = Bool(INPUT)
|
||||
val vec_irq_aux = Bits(INPUT, conf.xprlen)
|
||||
val vec_irq_aux_wen = Bool(INPUT)
|
||||
val pc = UFix(INPUT, VADDR_BITS+1)
|
||||
val eret = Bool(INPUT)
|
||||
val ei = Bool(INPUT)
|
||||
val di = Bool(INPUT)
|
||||
val ptbr_wen = Bool(OUTPUT)
|
||||
val irq_timer = Bool(OUTPUT)
|
||||
val irq_ipi = Bool(OUTPUT)
|
||||
val replay = Bool(OUTPUT)
|
||||
val vecbank = Bits(OUTPUT, 8)
|
||||
val vecbankcnt = UFix(OUTPUT, 4)
|
||||
val vec_appvl = UFix(INPUT, 12)
|
||||
val vec_nxregs = UFix(INPUT, 6)
|
||||
val vec_nfregs = UFix(INPUT, 6)
|
||||
}
|
||||
import PCR._
|
||||
|
||||
val reg_epc = Reg{Fix(width = VADDR_BITS+1)}
|
||||
val reg_badvaddr = Reg{Fix(width = VADDR_BITS+1)}
|
||||
val reg_ebase = Reg{Fix(width = VADDR_BITS)}
|
||||
val reg_count = WideCounter(32)
|
||||
val reg_compare = Reg() { UFix() };
|
||||
val reg_cause = Reg() { Bits() };
|
||||
val reg_tohost = Reg(resetVal = Bits(0, 64));
|
||||
val reg_fromhost = Reg(resetVal = Bits(0, 64));
|
||||
val reg_coreid = Reg() { Bits() }
|
||||
val reg_k0 = Reg() { Bits() };
|
||||
val reg_k1 = Reg() { Bits() };
|
||||
val reg_ptbr = Reg() { UFix() };
|
||||
val reg_vecbank = Reg(resetVal = Bits("b1111_1111", 8))
|
||||
|
||||
val reg_error_mode = Reg(resetVal = Bool(false));
|
||||
val reg_status_vm = Reg(resetVal = Bool(false));
|
||||
val reg_status_im = Reg(resetVal = Bits(0,SR_IM_WIDTH));
|
||||
val reg_status_sx = Reg(resetVal = Bool(true));
|
||||
val reg_status_ux = Reg(resetVal = Bool(true));
|
||||
val reg_status_ec = Reg(resetVal = Bool(false));
|
||||
val reg_status_ef = Reg(resetVal = Bool(false));
|
||||
val reg_status_ev = Reg(resetVal = Bool(false));
|
||||
val reg_status_s = Reg(resetVal = Bool(true));
|
||||
val reg_status_ps = Reg(resetVal = Bool(false));
|
||||
val reg_status_et = Reg(resetVal = Bool(false));
|
||||
|
||||
val r_irq_timer = Reg(resetVal = Bool(false));
|
||||
val reg_compare = Reg{Bits(width = 32)}
|
||||
val reg_cause = Reg{Bits(width = io.cause.getWidth)}
|
||||
val reg_tohost = Reg(resetVal = Bits(0, conf.xprlen))
|
||||
val reg_fromhost = Reg(resetVal = Bits(0, conf.xprlen))
|
||||
val reg_coreid = Reg{Bits(width = 16)}
|
||||
val reg_k0 = Reg{Bits(width = conf.xprlen)}
|
||||
val reg_k1 = Reg{Bits(width = conf.xprlen)}
|
||||
val reg_ptbr = Reg{UFix(width = PADDR_BITS)}
|
||||
val reg_vecbank = Reg(resetVal = Fix(-1,8).toBits)
|
||||
val reg_error_mode = Reg(resetVal = Bool(false))
|
||||
val reg_status = Reg{new Status} // reset down below
|
||||
|
||||
val r_irq_timer = Reg(resetVal = Bool(false))
|
||||
val r_irq_ipi = Reg(resetVal = Bool(true))
|
||||
|
||||
val rdata = Bits();
|
||||
@ -127,12 +162,12 @@ class rocketDpathPCR(implicit conf: RocketConfiguration) extends Component
|
||||
val wdata = Mux(io.w.en, io.w.data, io.host.pcr_req.bits.data)
|
||||
io.host.pcr_req.ready := !io.w.en && !io.r.en
|
||||
|
||||
io.ptbr_wen := reg_status_vm.toBool && wen && (waddr === PCR_PTBR);
|
||||
io.status := Cat(reg_status_im, Bits(0,7), reg_status_vm, reg_status_sx, reg_status_ux, reg_status_s, reg_status_ps, reg_status_ec, reg_status_ev, reg_status_ef, reg_status_et);
|
||||
io.evec := Mux(io.exception, reg_ebase, reg_epc).toUFix
|
||||
io.ptbr := reg_ptbr;
|
||||
io.host.debug.error_mode := reg_error_mode;
|
||||
io.r.data := rdata;
|
||||
io.status := reg_status
|
||||
io.ptbr_wen := wen && waddr === PTBR
|
||||
io.evec := Mux(io.exception, reg_ebase, reg_epc).toUFix
|
||||
io.ptbr := reg_ptbr
|
||||
io.host.debug.error_mode := reg_error_mode
|
||||
io.r.data := rdata
|
||||
|
||||
io.vecbank := reg_vecbank
|
||||
var cnt = UFix(0,4)
|
||||
@ -140,7 +175,7 @@ class rocketDpathPCR(implicit conf: RocketConfiguration) extends Component
|
||||
cnt = cnt + reg_vecbank(i)
|
||||
io.vecbankcnt := cnt(3,0)
|
||||
|
||||
val badvaddr_sign = Mux(io.w.data(VADDR_BITS-1), ~io.w.data(63,VADDR_BITS) === UFix(0), io.w.data(63,VADDR_BITS) != UFix(0))
|
||||
val badvaddr_sign = Mux(io.w.data(VADDR_BITS-1), io.w.data(conf.xprlen-1,VADDR_BITS).andR, io.w.data(conf.xprlen-1,VADDR_BITS).orR)
|
||||
when (io.badvaddr_wen) {
|
||||
reg_badvaddr := Cat(badvaddr_sign, io.w.data(VADDR_BITS-1,0)).toUFix;
|
||||
}
|
||||
@ -149,21 +184,20 @@ class rocketDpathPCR(implicit conf: RocketConfiguration) extends Component
|
||||
}
|
||||
|
||||
when (io.exception) {
|
||||
when (!reg_status_et) {
|
||||
reg_error_mode := Bool(true)
|
||||
}
|
||||
.otherwise {
|
||||
reg_status_s := Bool(true);
|
||||
reg_status_ps := reg_status_s;
|
||||
reg_status_et := Bool(false);
|
||||
reg_epc := io.pc;
|
||||
reg_cause := io.cause;
|
||||
when (!reg_status.et) {
|
||||
reg_error_mode := true
|
||||
}.otherwise {
|
||||
reg_status.s := true
|
||||
reg_status.ps := reg_status.s
|
||||
reg_status.et := false
|
||||
reg_epc := io.pc
|
||||
reg_cause := io.cause
|
||||
}
|
||||
}
|
||||
|
||||
when (io.eret) {
|
||||
reg_status_s := reg_status_ps;
|
||||
reg_status_et := Bool(true);
|
||||
reg_status.s := reg_status.ps
|
||||
reg_status.et := true
|
||||
}
|
||||
|
||||
when (reg_count === reg_compare) {
|
||||
@ -172,59 +206,64 @@ class rocketDpathPCR(implicit conf: RocketConfiguration) extends Component
|
||||
|
||||
io.irq_timer := r_irq_timer;
|
||||
io.irq_ipi := r_irq_ipi;
|
||||
io.host.ipi_req.valid := io.w.en && io.w.addr === PCR_SEND_IPI
|
||||
io.host.ipi_req.valid := io.w.en && io.w.addr === SEND_IPI
|
||||
io.host.ipi_req.bits := io.w.data
|
||||
io.replay := io.host.ipi_req.valid && !io.host.ipi_req.ready
|
||||
|
||||
when (io.host.pcr_req.fire() && !io.host.pcr_req.bits.rw && io.host.pcr_req.bits.addr === PCR_TOHOST) { reg_tohost := UFix(0) }
|
||||
when (io.host.pcr_req.fire() && !io.host.pcr_req.bits.rw && io.host.pcr_req.bits.addr === TOHOST) { reg_tohost := UFix(0) }
|
||||
|
||||
val read_impl = Bits(2)
|
||||
val read_ptbr = reg_ptbr(PADDR_BITS-1,PGIDX_BITS) << PGIDX_BITS
|
||||
val read_veccfg = Cat(io.vec_nfregs, io.vec_nxregs, io.vec_appvl)
|
||||
val read_cause = reg_cause(reg_cause.getWidth-1) << conf.xprlen-1 | reg_cause(reg_cause.getWidth-2,0)
|
||||
rdata := AVec[Bits](
|
||||
reg_status.toBits, reg_epc, reg_badvaddr, reg_ebase,
|
||||
reg_count, reg_compare, read_cause, read_ptbr,
|
||||
reg_coreid/*x*/, read_impl/*x*/, reg_coreid, read_impl,
|
||||
reg_k0, reg_k1, reg_k0/*x*/, reg_k1/*x*/,
|
||||
reg_vecbank/*x*/, read_veccfg/*x*/, reg_vecbank, read_veccfg,
|
||||
reg_vecbank/*x*/, read_veccfg/*x*/, reg_vecbank/*x*/, read_veccfg/*x*/,
|
||||
reg_vecbank/*x*/, read_veccfg/*x*/, reg_tohost/*x*/, reg_fromhost/*x*/,
|
||||
reg_vecbank/*x*/, read_veccfg/*x*/, reg_tohost, reg_fromhost
|
||||
)(raddr)
|
||||
|
||||
when (wen) {
|
||||
when (waddr === PCR_STATUS) {
|
||||
reg_status_vm := wdata(SR_VM).toBool;
|
||||
reg_status_im := wdata(SR_IM_WIDTH+SR_IM,SR_IM);
|
||||
reg_status_sx := wdata(SR_S64).toBool;
|
||||
reg_status_ux := wdata(SR_U64).toBool;
|
||||
reg_status_s := wdata(SR_S).toBool;
|
||||
reg_status_ps := wdata(SR_PS).toBool;
|
||||
reg_status_ev := Bool(conf.vec) && wdata(SR_EV).toBool;
|
||||
reg_status_ef := Bool(conf.fpu) && wdata(SR_EF).toBool;
|
||||
reg_status_ec := Bool(conf.rvc) && wdata(SR_EC).toBool;
|
||||
reg_status_et := wdata(SR_ET).toBool;
|
||||
when (waddr === STATUS) {
|
||||
reg_status := new Status().fromBits(wdata)
|
||||
reg_status.zero := 0
|
||||
if (!conf.vec) reg_status.ev := false
|
||||
if (!conf.fpu) reg_status.ef := false
|
||||
if (!conf.rvc) reg_status.ec := false
|
||||
}
|
||||
when (waddr === PCR_EPC) { reg_epc := wdata(VADDR_BITS,0).toFix }
|
||||
when (waddr === PCR_EVEC) { reg_ebase := wdata(VADDR_BITS-1,0).toUFix; }
|
||||
when (waddr === PCR_COUNT) { reg_count := wdata.toUFix }
|
||||
when (waddr === PCR_COMPARE) { reg_compare := wdata(31,0).toUFix; r_irq_timer := Bool(false); }
|
||||
when (waddr === PCR_COREID) { reg_coreid := wdata(15,0) }
|
||||
when (waddr === PCR_FROMHOST) { when (reg_fromhost === UFix(0) || io.w.en) { reg_fromhost := wdata } }
|
||||
when (waddr === PCR_TOHOST) { when (reg_tohost === UFix(0)) { reg_tohost := wdata } }
|
||||
when (waddr === PCR_CLR_IPI) { r_irq_ipi := wdata(0) }
|
||||
when (waddr === PCR_K0) { reg_k0 := wdata; }
|
||||
when (waddr === PCR_K1) { reg_k1 := wdata; }
|
||||
when (waddr === PCR_PTBR) { reg_ptbr := Cat(wdata(PADDR_BITS-1, PGIDX_BITS), Bits(0, PGIDX_BITS)).toUFix; }
|
||||
when (waddr === PCR_VECBANK) { reg_vecbank:= wdata(7,0) }
|
||||
when (waddr === EPC) { reg_epc := wdata(VADDR_BITS,0).toFix }
|
||||
when (waddr === EVEC) { reg_ebase := wdata(VADDR_BITS-1,0).toUFix; }
|
||||
when (waddr === COUNT) { reg_count := wdata.toUFix }
|
||||
when (waddr === COMPARE) { reg_compare := wdata(31,0).toUFix; r_irq_timer := Bool(false); }
|
||||
when (waddr === COREID) { reg_coreid := wdata(15,0) }
|
||||
when (waddr === FROMHOST) { when (reg_fromhost === UFix(0) || io.w.en) { reg_fromhost := wdata } }
|
||||
when (waddr === TOHOST) { when (reg_tohost === UFix(0)) { reg_tohost := wdata } }
|
||||
when (waddr === CLR_IPI) { r_irq_ipi := wdata(0) }
|
||||
when (waddr === K0) { reg_k0 := wdata; }
|
||||
when (waddr === K1) { reg_k1 := wdata; }
|
||||
when (waddr === PTBR) { reg_ptbr := Cat(wdata(PADDR_BITS-1, PGIDX_BITS), Bits(0, PGIDX_BITS)).toUFix; }
|
||||
when (waddr === VECBANK) { reg_vecbank:= wdata(7,0) }
|
||||
}
|
||||
|
||||
io.host.ipi_rep.ready := Bool(true)
|
||||
when (io.host.ipi_rep.valid) { r_irq_ipi := Bool(true) }
|
||||
|
||||
rdata := io.status // raddr === PCR_STATUS
|
||||
switch (raddr) {
|
||||
is (PCR_EPC) { rdata := reg_epc }
|
||||
is (PCR_BADVADDR) { rdata := reg_badvaddr }
|
||||
is (PCR_EVEC) { rdata := reg_ebase }
|
||||
is (PCR_COUNT) { rdata := reg_count }
|
||||
is (PCR_COMPARE) { rdata := reg_compare }
|
||||
is (PCR_CAUSE) { rdata := reg_cause(5) << 63 | reg_cause(4,0) }
|
||||
is (PCR_COREID) { rdata := reg_coreid }
|
||||
is (PCR_IMPL) { rdata := Bits(2) }
|
||||
is (PCR_FROMHOST) { rdata := reg_fromhost; }
|
||||
is (PCR_TOHOST) { rdata := reg_tohost; }
|
||||
is (PCR_K0) { rdata := reg_k0; }
|
||||
is (PCR_K1) { rdata := reg_k1; }
|
||||
is (PCR_PTBR) { rdata := reg_ptbr }
|
||||
is (PCR_VECBANK) { rdata := Cat(Bits(0, 56), reg_vecbank) }
|
||||
is (PCR_VECCFG) { rdata := Cat(Bits(0, 40), io.vec_nfregs, io.vec_nxregs, io.vec_appvl) }
|
||||
when (reset) {
|
||||
reg_status.et := false
|
||||
reg_status.ef := false
|
||||
reg_status.ev := false
|
||||
reg_status.ec := false
|
||||
reg_status.ps := false
|
||||
reg_status.s := true
|
||||
reg_status.u64 := true
|
||||
reg_status.s64 := true
|
||||
reg_status.vm := false
|
||||
reg_status.zero := 0
|
||||
reg_status.im := 0
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user