# DMI register addresses
class DBGCore:
- CTRL = 0b0000
- STAT = 0b0001
- NIA = 0b0010 # NIA register (read only for now)
- MSR = 0b0011 # MSR (read only)
- GSPR_INDEX = 0b0100 # GSPR register index
- GSPR_DATA = 0b0101 # GSPR register data
- LOG_ADDR = 0b0110 # Log buffer address register
- LOG_DATA = 0b0111 # Log buffer data register
+ CTRL = 0b0000
+ STAT = 0b0001
+ NIA = 0b0010 # NIA register (read only for now)
+ MSR = 0b0011 # MSR (read only)
+ GSPR_IDX = 0b0100 # GSPR register index
+ GSPR_DATA = 0b0101 # GSPR register data
+ LOG_ADDR = 0b0110 # Log buffer address register
+ LOG_DATA = 0b0111 # Log buffer data register
# CTRL register (direct actions, write 1 to act, read back 0)
class DbgReg(RecordObject):
def __init__(self, name):
super().__init__(name=name)
- self.req_o = Signal()
- self.ack_i = Signal()
- self.addr_o = Signal(7) # includes fast SPRs, others?
- self.data_i = Signal(64)
+ self.req = Signal()
+ self.ack = Signal()
+ self.addr = Signal(7) # includes fast SPRs, others?
+ self.data = Signal(64)
class CoreDebug(Elaboratable):
do_icreset = Signal()
terminated = Signal()
do_gspr_rd = Signal()
- gspr_index = Signal.like(self.dbg_gpr.addr_o)
+ gspr_index = Signal.like(self.dbg_gpr.addr)
log_dmi_addr = Signal(32)
log_dmi_data = Signal(64)
# Single cycle register accesses on DMI except for GSPR data
comb += self.dmi.ack_o.eq(Mux(self.dmi.addr_i == DBGCore.GSPR_DATA,
- self.dbg_gpr.ack_i, self.dmi.req_i))
- comb += self.dbg_gpr.req_o.eq(Mux(self.dmi.addr_i == DBGCore.GSPR_DATA,
+ self.dbg_gpr.ack, self.dmi.req_i))
+ comb += self.dbg_gpr.req.eq(Mux(self.dmi.addr_i == DBGCore.GSPR_DATA,
self.dmi.req_i, 0))
# Status register read composition (DBUG_CORE_STAT_xxx)
with m.Case( DBGCore.MSR):
comb += self.dmi.dout.eq(self.state.msr)
with m.Case( DBGCore.GSPR_DATA):
- comb += self.dmi.dout.eq(self.dbg_gpr.data_i)
+ comb += self.dmi.dout.eq(self.dbg_gpr.data)
with m.Case( DBGCore.LOG_ADDR):
comb += self.dmi.dout.eq(Cat(log_dmi_addr,
self.log_write_addr_o))
sync += terminated.eq(0)
# GSPR address
- with m.Elif(self.dmi.addr_i == DBGCore.GSPR_INDEX):
+ with m.Elif(self.dmi.addr_i == DBGCore.GSPR_IDX):
sync += gspr_index.eq(self.dmi.din)
# Log address
sync += stopping.eq(1)
sync += terminated.eq(1)
- comb += self.dbg_gpr.addr_o.eq(gspr_index)
+ comb += self.dbg_gpr.addr.eq(gspr_index)
# Core control signals generated by the debug module
comb += self.core_stop_o.eq(stopping & ~do_step)
# DMI interface
self.dbg = CoreDebug()
- self.dmi = self.dbg.dmi
# instruction go/monitor
self.pc_o = Signal(64, reset_less=True)
self.fast_w_pc = self.core.regs.rf['fast'].w_ports['d_wr1'] # PC wr
self.fast_r_msr = self.core.regs.rf['fast'].r_ports['msr'] # MSR rd
+ # DMI interface access
+ self.int_r = self.core.regs.rf['int'].r_ports['dmi'] # INT read
+
# hack method of keeping an eye on whether branch/trap set the PC
self.fast_nia = self.core.regs.rf['fast'].w_ports['nia']
self.fast_nia.wen.name = 'fast_nia_wen'
m.submodules.imem = imem = self.imem
m.submodules.dbg = dbg = self.dbg
+ # convenience
+ dmi = dbg.dmi
+ d_reg = dbg.dbg_gpr
+
# clock delay power-on reset
cd_por = ClockDomain(reset_less=True)
cd_sync = ClockDomain()
comb += self.fast_w_pc.data_i.eq(nia)
m.next = "IDLE" # back to idle
+ # this bit doesn't have to be in the FSM: connect up to read
+ # regfiles on demand from DMI
+
+ with m.If(d_reg.req): # request for regfile access being made
+ # TODO: error-check this
+ # XXX should this be combinatorial? sync better?
+ comb += self.int_r.ren.eq(1<<d_reg.addr)
+ comb += d_reg.data.eq(self.int_r.data_o)
+ comb += d_reg.ack.eq(1)
+
return m
def __iter__(self):
yield dmi.we_i.eq(0)
+def get_dmi(dmi, addr):
+ yield dmi.req_i.eq(1)
+ yield dmi.addr_i.eq(addr)
+ yield dmi.din.eq(0)
+ yield dmi.we_i.eq(1)
+ while True:
+ ack = yield dmi.ack_o
+ if ack:
+ break
+ yield
+ yield # wait one
+ data = yield dmi.dout # get data after ack valid for 1 cycle
+ yield dmi.req_i.eq(0)
+ yield dmi.addr_i.eq(0)
+ yield dmi.we_i.eq(0)
+ return data
+
+
class TestRunner(FHDLTestCase):
def __init__(self, tst_data):
super().__init__("run_all")
if terminated:
break
+ # test of dmi reg get
+ int_reg = 9
+ yield from set_dmi(dmi, DBGCore.GSPR_IDX, int_reg) # int reg 9
+ value = yield from get_dmi(dmi, DBGCore.GSPR_DATA) # get data
+
+ print ("after test %s reg %x value %s" % \
+ (test.name, int_reg, value))
+
sim.add_sync_process(process)
with sim.write_vcd("issuer_simulator.vcd",
traces=[]):