1
0
rocket-chip/src/main/scala/rocket/breakpoint.scala

84 lines
2.4 KiB
Scala
Raw Normal View History

// See LICENSE.SiFive for license details.
2016-06-09 05:19:52 +02:00
package rocket
import Chisel._
import util._
import Chisel.ImplicitConversions._
import config._
2016-06-09 05:19:52 +02:00
2016-06-10 04:07:10 +02:00
class BPControl(implicit p: Parameters) extends CoreBundle()(p) {
val ttype = UInt(width = 4)
val dmode = Bool()
val maskmax = UInt(width = 6)
val reserved = UInt(width = xLen-24)
val action = Bool()
val chain = Bool()
val zero = UInt(width = 2)
val tmatch = UInt(width = 2)
2016-06-09 05:19:52 +02:00
val m = Bool()
val h = Bool()
val s = Bool()
val u = Bool()
val x = Bool()
val w = Bool()
val r = Bool()
2016-06-10 04:07:10 +02:00
def tType = 2
def maskMax = 4
def enabled(mstatus: MStatus) = !mstatus.debug && 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) =
(0 until control.maskMax-1).scanLeft(control.tmatch(0))((m, i) => m && address(i)).asUInt
def pow2AddressMatch(x: UInt) =
(~x | mask()) === (~address | mask())
def rangeAddressMatch(x: UInt) =
(x >= address) ^ control.tmatch(0)
def addressMatch(x: UInt) =
Mux(control.tmatch(1), rangeAddressMatch(x), pow2AddressMatch(x))
2016-06-09 05:19:52 +02:00
}
class BreakpointUnit(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
2016-06-09 05:19:52 +02:00
val io = new Bundle {
2016-06-09 21:41:52 +02:00
val status = new MStatus().asInput
val bp = Vec(n, new BP).asInput
2016-06-09 05:19:52 +02:00
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)
val debug_if = Bool(OUTPUT)
val debug_ld = Bool(OUTPUT)
val debug_st = Bool(OUTPUT)
2016-06-09 05:19:52 +02:00
}
io.xcpt_if := false
io.xcpt_ld := false
io.xcpt_st := false
io.debug_if := false
io.debug_ld := false
io.debug_st := false
2016-06-09 05:19:52 +02:00
io.bp.foldLeft((Bool(true), Bool(true), Bool(true))) { case ((ri, wi, xi), bp) =>
val en = bp.control.enabled(io.status)
val r = en && ri && bp.control.r && bp.addressMatch(io.ea)
val w = en && wi && bp.control.w && bp.addressMatch(io.ea)
val x = en && xi && bp.control.x && bp.addressMatch(io.pc)
val end = !bp.control.chain
when (end && r) { io.xcpt_ld := !bp.control.action; io.debug_ld := bp.control.action }
when (end && w) { io.xcpt_st := !bp.control.action; io.debug_st := bp.control.action }
when (end && x) { io.xcpt_if := !bp.control.action; io.debug_if := bp.control.action }
2016-06-09 05:19:52 +02:00
(end || r, end || w, end || x)
2016-06-09 05:19:52 +02:00
}
}