2016-06-09 05:19:52 +02:00
|
|
|
// See LICENSE for license details.
|
|
|
|
|
|
|
|
package rocket
|
|
|
|
|
|
|
|
import Chisel._
|
2016-09-28 06:27:07 +02:00
|
|
|
import util._
|
2016-09-29 01:10:32 +02:00
|
|
|
import Chisel.ImplicitConversions._
|
2016-11-18 23:05:14 +01:00
|
|
|
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) {
|
2016-08-26 08:07:34 +02:00
|
|
|
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()
|
2016-08-26 08:07:34 +02:00
|
|
|
val w = Bool()
|
|
|
|
val r = Bool()
|
2016-06-10 04:07:10 +02:00
|
|
|
|
2016-08-26 08:07:34 +02:00
|
|
|
def tType = 2
|
|
|
|
def maskMax = 4
|
|
|
|
def enabled(mstatus: MStatus) = !mstatus.debug && Cat(m, h, s, u)(mstatus.prv)
|
2016-06-11 04:55:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
class BP(implicit p: Parameters) extends CoreBundle()(p) {
|
|
|
|
val control = new BPControl
|
|
|
|
val address = UInt(width = vaddrBits)
|
|
|
|
|
2016-08-26 08:07:34 +02:00
|
|
|
def mask(dummy: Int = 0) =
|
|
|
|
(0 until control.maskMax-1).scanLeft(control.tmatch(0))((m, i) => m && address(i)).asUInt
|
2016-06-11 04:55:58 +02:00
|
|
|
|
|
|
|
def pow2AddressMatch(x: UInt) =
|
|
|
|
(~x | mask()) === (~address | mask())
|
2016-08-26 08:07:34 +02:00
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2016-08-26 08:07:34 +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
|
2016-08-26 08:07:34 +02:00
|
|
|
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)
|
2016-08-26 08:07:34 +02:00
|
|
|
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
|
2016-08-26 08:07:34 +02:00
|
|
|
io.debug_if := false
|
|
|
|
io.debug_ld := false
|
|
|
|
io.debug_st := false
|
2016-06-09 05:19:52 +02:00
|
|
|
|
2016-08-26 08:07:34 +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
|
|
|
|
2016-08-26 08:07:34 +02:00
|
|
|
(end || r, end || w, end || x)
|
2016-06-09 05:19:52 +02:00
|
|
|
}
|
|
|
|
}
|