LOG_ADDR = 0b0110 # Log buffer address register
LOG_DATA = 0b0111 # Log buffer data register
CR = 0b1000 # CR (read only)
+ XER = 0b1001 # XER (read only) - note this is a TEMPORARY hack
# CTRL register (direct actions, write 1 to act, read back 0)
self.state = CoreState("core_dbg")
# GSPR register read port
- self.dbg_gpr = DbgReg("dbg_gpr")
+ self.d_gpr = DbgReg("d_gpr")
# CR register read port
- self.dbg_cr = DbgReg("dbg_cr")
+ self.d_cr = DbgReg("d_cr")
+
+ # XER register read port
+ self.d_xer = DbgReg("d_xer")
# Core logging data
self.log_data_i = Signal(256)
m = Module()
comb, sync = m.d.comb, m.d.sync
- dmi, dbg_gpr, dbg_cr = self.dmi, self.dbg_gpr, self.dbg_cr
+ dmi, d_gpr, d_cr, d_xer, = self.dmi, self.d_gpr, self.d_cr, self.d_xer
# DMI needs fixing... make a one clock pulse
dmi_req_i_1 = Signal()
do_icreset = Signal()
terminated = Signal()
do_gspr_rd = Signal()
- gspr_index = Signal.like(dbg_gpr.addr)
+ gspr_index = Signal.like(d_gpr.addr)
log_dmi_addr = Signal(32)
log_dmi_data = Signal(64)
# Single cycle register accesses on DMI except for GSPR data
with m.Switch(dmi.addr_i):
with m.Case(DBGCore.GSPR_DATA):
- comb += dmi.ack_o.eq(dbg_gpr.ack)
- comb += dbg_gpr.req.eq(dmi.req_i)
+ comb += dmi.ack_o.eq(d_gpr.ack)
+ comb += d_gpr.req.eq(dmi.req_i)
with m.Case(DBGCore.CR):
- comb += dmi.ack_o.eq(dbg_cr.ack)
- comb += dbg_cr.req.eq(dmi.req_i)
+ comb += dmi.ack_o.eq(d_cr.ack)
+ comb += d_cr.req.eq(dmi.req_i)
+ with m.Case(DBGCore.XER):
+ comb += dmi.ack_o.eq(d_xer.ack)
+ comb += d_xer.req.eq(dmi.req_i)
with m.Default():
comb += dmi.ack_o.eq(dmi.req_i)
with m.Case( DBGCore.MSR):
comb += dmi.dout.eq(self.state.msr)
with m.Case( DBGCore.GSPR_DATA):
- comb += dmi.dout.eq(dbg_gpr.data)
+ comb += dmi.dout.eq(d_gpr.data)
with m.Case( DBGCore.LOG_ADDR):
comb += dmi.dout.eq(Cat(log_dmi_addr, self.log_write_addr_o))
with m.Case( DBGCore.LOG_DATA):
comb += dmi.dout.eq(log_dmi_data)
with m.Case(DBGCore.CR):
- comb += dmi.dout.eq(dbg_cr.data)
+ comb += dmi.dout.eq(d_cr.data)
+ with m.Case(DBGCore.XER):
+ comb += dmi.dout.eq(d_xer.data)
# DMI writes
# Reset the 1-cycle "do" signals
sync += stopping.eq(1)
sync += terminated.eq(1)
- comb += dbg_gpr.addr.eq(gspr_index)
+ comb += d_gpr.addr.eq(gspr_index)
# Core control signals generated by the debug module
comb += self.core_stop_o.eq(stopping & ~do_step)
yield self.terminate_i
yield self.core_stopped_i
yield from self.state
- yield from self.dbg_gpr
+ yield from self.d_gpr
+ yield from self.d_cr
+ yield from self.d_xer
yield self.log_data_i
yield self.log_read_addr_i
yield self.log_read_data_o
# DMI interface access
intrf = self.core.regs.rf['int']
crrf = self.core.regs.rf['cr']
+ xerrf = self.core.regs.rf['xer']
self.int_r = intrf.r_ports['dmi'] # INT read
self.cr_r = crrf.r_ports['full_cr_dbg'] # CR read
+ self.xer_r = xerrf.r_ports['full_xer'] # XER read
# hack method of keeping an eye on whether branch/trap set the PC
self.state_nia = self.core.regs.rf['state'].w_ports['nia']
m.submodules.dec2 = pdecode2 = self.pdecode2
# convenience
- dmi, d_reg, d_cr = dbg.dmi, dbg.dbg_gpr, dbg.dbg_cr
+ dmi, d_reg, d_cr, d_xer, = dbg.dmi, dbg.d_gpr, dbg.d_cr, dbg.d_xer
intrf = self.core.regs.rf['int']
# clock delay power-on reset
comb += d_cr.data.eq(self.cr_r.data_o)
comb += d_cr.ack.eq(1)
+ # aaand XER...
+ with m.If(d_xer.req): # request for regfile access being made
+ comb += self.xer_r.ren.eq(0b111) # enable all
+ d_xer_delay = Signal()
+ sync += d_xer_delay.eq(d_xer.req)
+ with m.If(d_xer_delay):
+ # data arrives one clock later
+ comb += d_xer.data.eq(self.xer_r.data_o)
+ comb += d_xer.ack.eq(1)
+
return m
def __iter__(self):