1
0

correctly sign-extend badvaddr, epc, and ebase

This commit is contained in:
Andrew Waterman 2013-01-06 05:18:33 -08:00
parent 63060bc0a8
commit 5b9f938263
2 changed files with 40 additions and 16 deletions

View File

@ -132,9 +132,9 @@ class PCR(implicit conf: RocketConfiguration) extends Component
}
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_epc = Reg{Bits(width = conf.xprlen)}
val reg_badvaddr = Reg{Bits(width = conf.xprlen)}
val reg_ebase = Reg{Bits(width = conf.xprlen)}
val reg_count = WideCounter(32)
val reg_compare = Reg{Bits(width = 32)}
val reg_cause = Reg{Bits(width = io.cause.getWidth)}
@ -189,24 +189,22 @@ class PCR(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(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;
}
when (io.vec_irq_aux_wen) {
reg_badvaddr := io.vec_irq_aux.toUFix
when (io.badvaddr_wen || io.vec_irq_aux_wen) {
val wdata = Mux(io.badvaddr_wen, io.w.data, io.vec_irq_aux)
val (upper, lower) = Split(wdata, VADDR_BITS)
val sign = Mux(lower.toFix < Fix(0), upper.andR, upper.orR)
reg_badvaddr := Cat(sign, lower).toFix
}
when (io.exception) {
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
}
reg_status.s := true
reg_status.ps := reg_status.s
reg_status.et := false
reg_epc := io.pc.toFix
reg_cause := io.cause
}
when (io.eret) {
@ -250,7 +248,7 @@ class PCR(implicit conf: RocketConfiguration) extends Component
if (!conf.rvc) reg_status.ec := false
}
when (waddr === EPC) { reg_epc := wdata(VADDR_BITS,0).toFix }
when (waddr === EVEC) { reg_ebase := wdata(VADDR_BITS-1,0).toUFix; }
when (waddr === EVEC) { reg_ebase := wdata(VADDR_BITS-1,0).toFix }
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) }

View File

@ -24,6 +24,32 @@ object AVec
tabulate(n1)(i1 => tabulate(n2)(f(i1, _)))
}
object Split
{
// is there a better way to do do this?
def apply(x: Bits, n0: Int) = {
val w = checkWidth(x, n0)
(x(w-1,n0), x(n0-1,0))
}
def apply(x: Bits, n1: Int, n0: Int) = {
val w = checkWidth(x, n1, n0)
(x(w-1,n1), x(n1-1,n0), x(n0-1,0))
}
def apply(x: Bits, n2: Int, n1: Int, n0: Int) = {
val w = checkWidth(x, n2, n1, n0)
(x(w-1,n2), x(n2-1,n1), x(n1-1,n0), x(n0-1,0))
}
private def checkWidth(x: Bits, n: Int*) = {
val w = x.getWidth
def decreasing(x: Seq[Int]): Boolean =
if (x.tail.isEmpty) true
else x.head > x.tail.head && decreasing(x.tail)
require(decreasing(w :: n.toList))
w
}
}
// a counter that clock gates most of its MSBs using the LSB carry-out
case class WideCounter(width: Int, inc: Bool = Bool(true))
{