Refactor breakpoints and support range comparison (currently disabled)
This commit is contained in:
parent
c8c7246cce
commit
e3b4b55836
@ -30,13 +30,28 @@ class BPControl(implicit p: Parameters) extends CoreBundle()(p) {
|
|||||||
|
|
||||||
def tdrType = 1
|
def tdrType = 1
|
||||||
def bpaMaskMax = 4
|
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) {
|
class BreakpointUnit(implicit p: Parameters) extends CoreModule()(p) {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val status = new MStatus().asInput
|
val status = new MStatus().asInput
|
||||||
val bpcontrol = Vec(p(NBreakpoints), new BPControl).asInput
|
val bp = Vec(p(NBreakpoints), new BP).asInput
|
||||||
val bpaddress = Vec(p(NBreakpoints), UInt(width = vaddrBits)).asInput
|
|
||||||
val pc = UInt(INPUT, vaddrBits)
|
val pc = UInt(INPUT, vaddrBits)
|
||||||
val ea = UInt(INPUT, vaddrBits)
|
val ea = UInt(INPUT, vaddrBits)
|
||||||
val xcpt_if = Bool(OUTPUT)
|
val xcpt_if = Bool(OUTPUT)
|
||||||
@ -48,16 +63,20 @@ class BreakpointUnit(implicit p: Parameters) extends CoreModule()(p) {
|
|||||||
io.xcpt_ld := false
|
io.xcpt_ld := false
|
||||||
io.xcpt_st := false
|
io.xcpt_st := false
|
||||||
|
|
||||||
for (((bpc, bpa), i) <- io.bpcontrol zip io.bpaddress zipWithIndex) {
|
for (bp <- io.bp) {
|
||||||
var mask: UInt = bpc.bpmatch(1)
|
when (bp.control.enabled(io.status)) {
|
||||||
for (i <- 1 until bpc.bpaMaskMax)
|
when (bp.pow2AddressMatch(io.pc) && bp.control.x) { io.xcpt_if := true }
|
||||||
mask = Cat(mask(i-1) && bpa(i-1), mask)
|
when (bp.pow2AddressMatch(io.ea) && bp.control.r) { io.xcpt_ld := true }
|
||||||
|
when (bp.pow2AddressMatch(io.ea) && bp.control.w) { io.xcpt_st := true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def matches(x: UInt) = (~x | mask) === (~bpa | mask)
|
if (!io.bp.isEmpty) for ((bpl, bph) <- io.bp zip io.bp.tail) {
|
||||||
when (Cat(bpc.m, bpc.h, bpc.s, bpc.u)(io.status.prv)) {
|
def matches(x: UInt) = !(x < bpl.address) && x < bph.address
|
||||||
when (matches(io.pc) && bpc.x) { io.xcpt_if := true }
|
when (bph.control.enabled(io.status) && bph.control.bpmatch === 1) {
|
||||||
when (matches(io.ea) && bpc.r) { io.xcpt_ld := true }
|
when (matches(io.pc) && bph.control.x) { io.xcpt_if := true }
|
||||||
when (matches(io.ea) && bpc.w) { io.xcpt_st := true }
|
when (matches(io.ea) && bph.control.r) { io.xcpt_ld := true }
|
||||||
|
when (matches(io.ea) && bph.control.w) { io.xcpt_st := true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,8 +126,7 @@ class CSRFileIO(implicit p: Parameters) extends CoreBundle {
|
|||||||
val rocc = new RoCCInterface().flip
|
val rocc = new RoCCInterface().flip
|
||||||
val interrupt = Bool(OUTPUT)
|
val interrupt = Bool(OUTPUT)
|
||||||
val interrupt_cause = UInt(OUTPUT, xLen)
|
val interrupt_cause = UInt(OUTPUT, xLen)
|
||||||
val bpcontrol = Vec(p(NBreakpoints), new BPControl).asOutput
|
val bp = Vec(p(NBreakpoints), new BP).asOutput
|
||||||
val bpaddress = Vec(p(NBreakpoints), UInt(width = vaddrBits)).asOutput
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
||||||
@ -174,8 +173,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
val reg_dscratch = Reg(UInt(width = xLen))
|
val reg_dscratch = Reg(UInt(width = xLen))
|
||||||
|
|
||||||
val reg_tdrselect = Reg(new TDRSelect)
|
val reg_tdrselect = Reg(new TDRSelect)
|
||||||
val reg_bpcontrol = Reg(Vec(p(NBreakpoints), new BPControl))
|
val reg_bp = Reg(Vec(1 << log2Up(p(NBreakpoints)), new BP))
|
||||||
val reg_bpaddress = Reg(Vec(p(NBreakpoints), UInt(width = vaddrBits)))
|
|
||||||
|
|
||||||
val reg_mie = Reg(init=UInt(0, xLen))
|
val reg_mie = Reg(init=UInt(0, xLen))
|
||||||
val reg_mideleg = Reg(init=UInt(0, xLen))
|
val reg_mideleg = Reg(init=UInt(0, xLen))
|
||||||
@ -214,8 +212,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
val interruptCause = interruptMSB + PriorityEncoder(all_interrupts)
|
val interruptCause = interruptMSB + PriorityEncoder(all_interrupts)
|
||||||
io.interrupt := all_interrupts.orR
|
io.interrupt := all_interrupts.orR
|
||||||
io.interrupt_cause := interruptCause
|
io.interrupt_cause := interruptCause
|
||||||
io.bpcontrol := reg_bpcontrol
|
io.bp := reg_bp take p(NBreakpoints)
|
||||||
io.bpaddress := reg_bpaddress
|
|
||||||
|
|
||||||
val debugIntCause = reg_mip.getWidth
|
val debugIntCause = reg_mip.getWidth
|
||||||
// debug interrupts are only masked by being in debug mode
|
// debug interrupts are only masked by being in debug mode
|
||||||
@ -238,8 +235,8 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
|
|
||||||
val read_mapping = collection.mutable.LinkedHashMap[Int,Bits](
|
val read_mapping = collection.mutable.LinkedHashMap[Int,Bits](
|
||||||
CSRs.tdrselect -> reg_tdrselect.toBits,
|
CSRs.tdrselect -> reg_tdrselect.toBits,
|
||||||
CSRs.tdrdata1 -> (if (p(NBreakpoints) > 0) reg_bpcontrol(reg_tdrselect.tdrindex).toBits else UInt(0)),
|
CSRs.tdrdata1 -> reg_bp(reg_tdrselect.tdrindex).control.toBits,
|
||||||
CSRs.tdrdata2 -> (if (p(NBreakpoints) > 0) reg_bpaddress(reg_tdrselect.tdrindex) else UInt(0)),
|
CSRs.tdrdata2 -> reg_bp(reg_tdrselect.tdrindex).address,
|
||||||
CSRs.mimpid -> UInt(0),
|
CSRs.mimpid -> UInt(0),
|
||||||
CSRs.marchid -> UInt(0),
|
CSRs.marchid -> UInt(0),
|
||||||
CSRs.mvendorid -> UInt(0),
|
CSRs.mvendorid -> UInt(0),
|
||||||
@ -340,9 +337,10 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
val read_only = io.rw.addr(11,10).andR
|
val read_only = io.rw.addr(11,10).andR
|
||||||
val cpu_wen = cpu_ren && io.rw.cmd =/= CSR.R && priv_sufficient
|
val cpu_wen = cpu_ren && io.rw.cmd =/= CSR.R && priv_sufficient
|
||||||
val wen = cpu_wen && !read_only
|
val wen = cpu_wen && !read_only
|
||||||
val wdata = Mux(io.rw.cmd === CSR.S, io.rw.rdata | io.rw.wdata,
|
|
||||||
Mux(io.rw.cmd === CSR.C, io.rw.rdata & ~io.rw.wdata,
|
val wdata = (Mux((io.rw.cmd === CSR.S || io.rw.cmd === CSR.C), io.rw.rdata, UInt(0)) |
|
||||||
io.rw.wdata))
|
Mux(io.rw.cmd =/= CSR.C, io.rw.wdata, UInt(0))) &
|
||||||
|
~Mux(io.rw.cmd === CSR.C, io.rw.wdata, UInt(0))
|
||||||
|
|
||||||
val do_system_insn = priv_sufficient && system_insn
|
val do_system_insn = priv_sufficient && system_insn
|
||||||
val opcode = UInt(1) << io.rw.addr(2,0)
|
val opcode = UInt(1) << io.rw.addr(2,0)
|
||||||
@ -525,15 +523,17 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
when (decoded_addr(CSRs.medeleg)) { reg_medeleg := wdata & delegable_exceptions }
|
when (decoded_addr(CSRs.medeleg)) { reg_medeleg := wdata & delegable_exceptions }
|
||||||
}
|
}
|
||||||
if (p(NBreakpoints) > 0) {
|
if (p(NBreakpoints) > 0) {
|
||||||
val canWrite = reg_tdrselect.tdrmode || reg_debug
|
|
||||||
val newTDR = new TDRSelect().fromBits(wdata)
|
val newTDR = new TDRSelect().fromBits(wdata)
|
||||||
when (decoded_addr(CSRs.tdrselect) && newTDR.tdrindex < newTDR.nTDR) { reg_tdrselect.tdrindex := newTDR.tdrindex }
|
when (decoded_addr(CSRs.tdrselect)) { reg_tdrselect.tdrindex := newTDR.tdrindex }
|
||||||
when (decoded_addr(CSRs.tdrdata1) && canWrite) {
|
|
||||||
|
when (reg_tdrselect.tdrmode || reg_debug) {
|
||||||
|
when (decoded_addr(CSRs.tdrdata1)) {
|
||||||
val newBPC = new BPControl().fromBits(wdata)
|
val newBPC = new BPControl().fromBits(wdata)
|
||||||
reg_bpcontrol(reg_tdrselect.tdrindex) := newBPC
|
reg_bp(reg_tdrselect.tdrindex).control := newBPC
|
||||||
reg_bpcontrol(reg_tdrselect.tdrindex).bpmatch := newBPC.bpmatch & 2 /* exact/NAPOT only */
|
reg_bp(reg_tdrselect.tdrindex).control.bpmatch := newBPC.bpmatch & 2 /* exact/NAPOT only */
|
||||||
|
}
|
||||||
|
when (decoded_addr(CSRs.tdrdata2)) { reg_bp(reg_tdrselect.tdrindex).address := wdata }
|
||||||
}
|
}
|
||||||
when (decoded_addr(CSRs.tdrdata2) && canWrite) { reg_bpaddress(reg_tdrselect.tdrindex) := wdata }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -553,7 +553,8 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
|
|
||||||
reg_tdrselect.reserved := 0
|
reg_tdrselect.reserved := 0
|
||||||
reg_tdrselect.tdrmode := true // TODO support D-mode breakpoint theft
|
reg_tdrselect.tdrmode := true // TODO support D-mode breakpoint theft
|
||||||
for (bpc <- reg_bpcontrol) {
|
if (reg_bp.isEmpty) reg_tdrselect.tdrindex := 0
|
||||||
|
for (bpc <- reg_bp map {_.control}) {
|
||||||
bpc.tdrtype := bpc.tdrType
|
bpc.tdrtype := bpc.tdrType
|
||||||
bpc.bpamaskmax := bpc.bpaMaskMax
|
bpc.bpamaskmax := bpc.bpaMaskMax
|
||||||
bpc.reserved := 0
|
bpc.reserved := 0
|
||||||
@ -568,4 +569,6 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
bpc.x := false
|
bpc.x := false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (bp <- reg_bp drop p(NBreakpoints))
|
||||||
|
bp := new BP().fromBits(0)
|
||||||
}
|
}
|
||||||
|
@ -228,8 +228,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) {
|
|||||||
|
|
||||||
val bpu = Module(new BreakpointUnit)
|
val bpu = Module(new BreakpointUnit)
|
||||||
bpu.io.status := csr.io.status
|
bpu.io.status := csr.io.status
|
||||||
bpu.io.bpcontrol := csr.io.bpcontrol
|
bpu.io.bp := csr.io.bp
|
||||||
bpu.io.bpaddress := csr.io.bpaddress
|
|
||||||
bpu.io.pc := id_pc
|
bpu.io.pc := id_pc
|
||||||
bpu.io.ea := mem_reg_wdata
|
bpu.io.ea := mem_reg_wdata
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user