correctly sign-extend badvaddr, epc, and ebase
This commit is contained in:
parent
63060bc0a8
commit
5b9f938263
@ -132,9 +132,9 @@ class PCR(implicit conf: RocketConfiguration) extends Component
|
|||||||
}
|
}
|
||||||
import PCR._
|
import PCR._
|
||||||
|
|
||||||
val reg_epc = Reg{Fix(width = VADDR_BITS+1)}
|
val reg_epc = Reg{Bits(width = conf.xprlen)}
|
||||||
val reg_badvaddr = Reg{Fix(width = VADDR_BITS+1)}
|
val reg_badvaddr = Reg{Bits(width = conf.xprlen)}
|
||||||
val reg_ebase = Reg{Fix(width = VADDR_BITS)}
|
val reg_ebase = Reg{Bits(width = conf.xprlen)}
|
||||||
val reg_count = WideCounter(32)
|
val reg_count = WideCounter(32)
|
||||||
val reg_compare = Reg{Bits(width = 32)}
|
val reg_compare = Reg{Bits(width = 32)}
|
||||||
val reg_cause = Reg{Bits(width = io.cause.getWidth)}
|
val reg_cause = Reg{Bits(width = io.cause.getWidth)}
|
||||||
@ -189,25 +189,23 @@ class PCR(implicit conf: RocketConfiguration) extends Component
|
|||||||
cnt = cnt + reg_vecbank(i)
|
cnt = cnt + reg_vecbank(i)
|
||||||
io.vecbankcnt := cnt(3,0)
|
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 || io.vec_irq_aux_wen) {
|
||||||
when (io.badvaddr_wen) {
|
val wdata = Mux(io.badvaddr_wen, io.w.data, io.vec_irq_aux)
|
||||||
reg_badvaddr := Cat(badvaddr_sign, io.w.data(VADDR_BITS-1,0)).toUFix;
|
val (upper, lower) = Split(wdata, VADDR_BITS)
|
||||||
}
|
val sign = Mux(lower.toFix < Fix(0), upper.andR, upper.orR)
|
||||||
when (io.vec_irq_aux_wen) {
|
reg_badvaddr := Cat(sign, lower).toFix
|
||||||
reg_badvaddr := io.vec_irq_aux.toUFix
|
|
||||||
}
|
}
|
||||||
|
|
||||||
when (io.exception) {
|
when (io.exception) {
|
||||||
when (!reg_status.et) {
|
when (!reg_status.et) {
|
||||||
reg_error_mode := true
|
reg_error_mode := true
|
||||||
}.otherwise {
|
}
|
||||||
reg_status.s := true
|
reg_status.s := true
|
||||||
reg_status.ps := reg_status.s
|
reg_status.ps := reg_status.s
|
||||||
reg_status.et := false
|
reg_status.et := false
|
||||||
reg_epc := io.pc
|
reg_epc := io.pc.toFix
|
||||||
reg_cause := io.cause
|
reg_cause := io.cause
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
when (io.eret) {
|
when (io.eret) {
|
||||||
reg_status.s := reg_status.ps
|
reg_status.s := reg_status.ps
|
||||||
@ -250,7 +248,7 @@ class PCR(implicit conf: RocketConfiguration) extends Component
|
|||||||
if (!conf.rvc) reg_status.ec := false
|
if (!conf.rvc) reg_status.ec := false
|
||||||
}
|
}
|
||||||
when (waddr === EPC) { reg_epc := wdata(VADDR_BITS,0).toFix }
|
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 === COUNT) { reg_count := wdata.toUFix }
|
||||||
when (waddr === COMPARE) { reg_compare := wdata(31,0).toUFix; r_irq_timer := Bool(false); }
|
when (waddr === COMPARE) { reg_compare := wdata(31,0).toUFix; r_irq_timer := Bool(false); }
|
||||||
when (waddr === COREID) { reg_coreid := wdata(15,0) }
|
when (waddr === COREID) { reg_coreid := wdata(15,0) }
|
||||||
|
@ -24,6 +24,32 @@ object AVec
|
|||||||
tabulate(n1)(i1 => tabulate(n2)(f(i1, _)))
|
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
|
// a counter that clock gates most of its MSBs using the LSB carry-out
|
||||||
case class WideCounter(width: Int, inc: Bool = Bool(true))
|
case class WideCounter(width: Int, inc: Bool = Bool(true))
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user