from nmigen.utils import log2_int
from nmigen.cli import rtlil
from soc.config.state import CoreState
+from openpower.consts import FastRegsEnum
# DMI register addresses
self.core_stopped_i = Signal()
self.state = CoreState("core_dbg")
- # GSPR register read port
- self.d_gpr = DbgReg("d_gpr")
-
- # CR register read port
- self.d_cr = DbgReg("d_cr")
-
- # XER register read port
- self.d_xer = DbgReg("d_xer")
+ self.d_gpr = DbgReg("d_gpr") # GSPR register read port
+ self.d_fast = DbgReg("d_fast") # GSPR register read port
+ self.d_cr = DbgReg("d_cr") # CR register read port
+ self.d_xer = DbgReg("d_xer") # XER register read port
# Core logging data
self.log_data_i = Signal(256)
m = Module()
comb, sync = m.d.comb, m.d.sync
dmi, d_gpr, d_cr, d_xer, = self.dmi, self.d_gpr, self.d_cr, self.d_xer
+ d_fast = self.d_fast
# DMI needs fixing... make a one clock pulse
dmi_req_i_1 = Signal()
do_icreset = Signal()
terminated = Signal()
do_gspr_rd = Signal()
+ # select either GPRs or FAST regs to read, based on GSPR_IDX
gspr_index = Signal.like(d_gpr.addr)
+ fast_index = Signal.like(d_gpr.addr)
+ gspr_en = Signal()
+ fast_en = Signal()
log_dmi_addr = Signal(32)
log_dmi_data = Signal(64)
# Single cycle register accesses on DMI except for registers
with m.Switch(dmi.addr_i):
with m.Case(DBGCore.GSPR_DATA):
- comb += dmi.ack_o.eq(d_gpr.ack)
- comb += d_gpr.req.eq(dmi.req_i)
+ with m.If(gspr_en): # GPR requested, acknowledge GPR
+ comb += dmi.ack_o.eq(d_gpr.ack)
+ comb += d_gpr.req.eq(dmi.req_i)
+ with m.If(fast_en): # FAST requested
+ comb += dmi.ack_o.eq(d_fast.ack)
+ comb += d_fast.req.eq(dmi.req_i)
with m.Case(DBGCore.CR):
comb += dmi.ack_o.eq(d_cr.ack)
comb += d_cr.req.eq(dmi.req_i)
comb += dmi.dout.eq(self.state.msr)
with m.Case( DBGCore.SVSTATE): # SVSTATE
comb += dmi.dout.eq(self.state.svstate)
- with m.Case( DBGCore.GSPR_DATA): # GPR
- comb += dmi.dout.eq(d_gpr.data)
+ with m.Case( DBGCore.GSPR_DATA): # GPR/FAST regs
+ with m.If(gspr_en):
+ comb += dmi.dout.eq(d_gpr.data) # GPR data selected
+ with m.If(fast_en):
+ comb += dmi.dout.eq(d_fast.data) # FAST reg read selected
with m.Case( DBGCore.LOG_ADDR): # Logging
comb += dmi.dout.eq(Cat(log_dmi_addr, self.log_write_addr_o))
with m.Case( DBGCore.LOG_DATA):
# GSPR address
with m.Elif(dmi.addr_i == DBGCore.GSPR_IDX):
- sync += gspr_index.eq(dmi.din)
+ sync += gspr_index.eq(0)
+ sync += fast_index.eq(0)
+ sync += gspr_en.eq(0)
+ sync += fast_en.eq(0)
+ with m.If(dmi.din <= 31):
+ sync += gspr_index.eq(dmi.din)
+ sync += gspr_en.eq(1)
+ with m.If(dmi.din == 32): # LR
+ sync += fast_index.eq(FastRegsEnum.LR)
+ sync += fast_en.eq(1)
+ with m.If(dmi.din == 33): # CTR
+ sync += fast_index.eq(FastRegsEnum.CTR)
+ sync += fast_en.eq(1)
+ with m.If(dmi.din == 34): # SRR0
+ sync += fast_index.eq(FastRegsEnum.SRR0)
+ sync += fast_en.eq(1)
+ with m.If(dmi.din == 35): # SRR1
+ sync += fast_index.eq(FastRegsEnum.SRR1)
+ sync += fast_en.eq(1)
+ with m.If(dmi.din == 44): # XER
+ sync += fast_index.eq(FastRegsEnum.XER)
+ sync += fast_en.eq(1)
+ with m.If(dmi.din == 45): # TAR
+ sync += fast_index.eq(FastRegsEnum.XER)
+ sync += fast_en.eq(1)
+
+ # numbering from microwatt:
+ """
+ If(regnum == 32, Display(" LR: %016x", dbg_dout),), # LR
+ If(regnum == 33, Display(" CTR: %016x", dbg_dout),), # CTR
+ If(regnum == 34, Display(" SRR0: %016x", dbg_dout),), # SRR0
+ If(regnum == 35, Display(" SRR1: %016x", dbg_dout),), # SRR1
+ If(regnum == 36, Display(" HSRR0: %016x", dbg_dout),), # HSRR0
+ If(regnum == 37, Display(" HSRR1: %016x", dbg_dout),), # HSRR1
+ If(regnum == 38, Display(" SPRG0: %016x", dbg_dout),), # SPRG0
+ If(regnum == 39, Display(" SPRG1: %016x", dbg_dout),), # SPRG1
+ If(regnum == 40, Display(" SPRG2: %016x", dbg_dout),), # SPRG2
+ If(regnum == 41, Display(" SPRG3: %016x", dbg_dout),), # SPRG3
+ If(regnum == 42, Display(" HSPRG0: %016x", dbg_dout),), # HSPRG0
+ If(regnum == 43, Display(" HSPRG1: %016x", dbg_dout),), # HSPRG1
+ If(regnum == 44, Display(" XER: %016x", dbg_dout),), # XER
+ If(regnum == 45, Display(" TAR: %016x", dbg_dout),), # TAR
+ """
# Log address
with m.Elif(dmi.addr_i == DBGCore.LOG_ADDR):
sync += terminated.eq(1)
comb += d_gpr.addr.eq(gspr_index)
+ comb += d_fast.addr.eq(fast_index)
# Core control signals generated by the debug module
comb += self.core_stop_o.eq((stopping & ~do_step) | self.terminate_i)
yield from self.d_gpr
yield from self.d_cr
yield from self.d_xer
+ yield from self.d_fast
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']
+ fastrf = self.core.regs.rf['fast']
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
+ self.int_r = intrf.r_ports['dmi'] # INT DMI read
+ self.cr_r = crrf.r_ports['full_cr_dbg'] # CR DMI read
+ self.xer_r = xerrf.r_ports['full_xer'] # XER DMI read
+ self.fast_r = fastrf.r_ports['dmi'] # FAST DMI read
if self.svp64_en:
# for predication
if self.svp64_en:
m.submodules.svp64 = svp64 = csd(self.svp64)
- # convenience
- 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
cd_por = ClockDomain(reset_less=True)
cd_sync = ClockDomain()
comb = m.d.comb
sync = m.d.sync
dmi, d_reg, d_cr, d_xer, = dbg.dmi, dbg.d_gpr, dbg.d_cr, dbg.d_xer
+ d_fast = dbg.d_fast
intrf = self.core.regs.rf['int']
+ fastrf = self.core.regs.rf['fast']
with m.If(d_reg.req): # request for regfile access being made
# TODO: error-check this
comb += d_reg.data.eq(self.int_r.o_data)
comb += d_reg.ack.eq(1)
+ # fast regfile
+ with m.If(d_fast.req): # request for regfile access being made
+ if fastrf.unary:
+ comb += self.fast_r.ren.eq(1 << d_fast.addr)
+ else:
+ comb += self.fast_r.addr.eq(d_fast.addr)
+ comb += self.fast_r.ren.eq(1)
+ d_fast_delay = Signal()
+ sync += d_fast_delay.eq(d_fast.req)
+ with m.If(d_fast_delay):
+ # data arrives one clock later
+ comb += d_fast.data.eq(self.fast_r.o_data)
+ comb += d_fast.ack.eq(1)
+
# sigh same thing for CR debug
with m.If(d_cr.req): # request for regfile access being made
comb += self.cr_r.ren.eq(0b11111111) # enable all