83 lines
2.3 KiB
Scala
83 lines
2.3 KiB
Scala
// See LICENSE for license details.
|
|
|
|
package rocket
|
|
|
|
import Chisel._
|
|
import Util._
|
|
import cde.Parameters
|
|
|
|
class TDRSelect(implicit p: Parameters) extends CoreBundle()(p) {
|
|
val tdrmode = Bool()
|
|
val reserved = UInt(width = xLen - 1 - log2Up(nTDR))
|
|
val tdrindex = UInt(width = log2Up(nTDR))
|
|
|
|
def nTDR = p(NBreakpoints)
|
|
}
|
|
|
|
class BPControl(implicit p: Parameters) extends CoreBundle()(p) {
|
|
val tdrtype = UInt(width = 4)
|
|
val bpamaskmax = UInt(width = 5)
|
|
val reserved = UInt(width = xLen-28)
|
|
val bpaction = UInt(width = 8)
|
|
val bpmatch = UInt(width = 4)
|
|
val m = Bool()
|
|
val h = Bool()
|
|
val s = Bool()
|
|
val u = Bool()
|
|
val r = Bool()
|
|
val w = Bool()
|
|
val x = Bool()
|
|
|
|
def tdrType = 1
|
|
def bpaMaskMax = 4
|
|
def enabled(mstatus: MStatus) = Cat(m, h, s, u)(mstatus.prv)
|
|
}
|
|
|
|
class BP(implicit p: Parameters) extends CoreBundle()(p) {
|
|
val control = new BPControl
|
|
val address = UInt(width = vaddrBits)
|
|
|
|
def mask(dummy: Int = 0) = {
|
|
var mask: UInt = control.bpmatch(1)
|
|
for (i <- 1 until control.bpaMaskMax)
|
|
mask = Cat(mask(i-1) && address(i-1), mask)
|
|
mask
|
|
}
|
|
|
|
def pow2AddressMatch(x: UInt) =
|
|
(~x | mask()) === (~address | mask())
|
|
}
|
|
|
|
class BreakpointUnit(implicit p: Parameters) extends CoreModule()(p) {
|
|
val io = new Bundle {
|
|
val status = new MStatus().asInput
|
|
val bp = Vec(p(NBreakpoints), new BP).asInput
|
|
val pc = UInt(INPUT, vaddrBits)
|
|
val ea = UInt(INPUT, vaddrBits)
|
|
val xcpt_if = Bool(OUTPUT)
|
|
val xcpt_ld = Bool(OUTPUT)
|
|
val xcpt_st = Bool(OUTPUT)
|
|
}
|
|
|
|
io.xcpt_if := false
|
|
io.xcpt_ld := false
|
|
io.xcpt_st := false
|
|
|
|
for (bp <- io.bp) {
|
|
when (bp.control.enabled(io.status)) {
|
|
when (bp.pow2AddressMatch(io.pc) && bp.control.x) { io.xcpt_if := true }
|
|
when (bp.pow2AddressMatch(io.ea) && bp.control.r) { io.xcpt_ld := true }
|
|
when (bp.pow2AddressMatch(io.ea) && bp.control.w) { io.xcpt_st := true }
|
|
}
|
|
}
|
|
|
|
if (!io.bp.isEmpty) for ((bpl, bph) <- io.bp zip io.bp.tail) {
|
|
def matches(x: UInt) = !(x < bpl.address) && x < bph.address
|
|
when (bph.control.enabled(io.status) && bph.control.bpmatch === 1) {
|
|
when (matches(io.pc) && bph.control.x) { io.xcpt_if := true }
|
|
when (matches(io.ea) && bph.control.r) { io.xcpt_ld := true }
|
|
when (matches(io.ea) && bph.control.w) { io.xcpt_st := true }
|
|
}
|
|
}
|
|
}
|