1
0

refactor PCR file

This commit is contained in:
Andrew Waterman
2012-11-27 01:28:06 -08:00
parent 64674d4d39
commit 9c857b83f0
9 changed files with 388 additions and 396 deletions

View File

@ -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
}
}