from litex.soc.integration.soc_core import SoCCore
from litex.soc.integration.soc_sdram import SoCSDRAM
from litex.soc.integration.builder import Builder
+from litex.soc.integration.common import get_mem_data
from litedram import modules as litedram_modules
from litedram.phy.model import SDRAMPHYModel
class LibreSoCSim(SoCSDRAM):
def __init__(self, cpu="libresoc", debug=False, with_sdram=True,
- #sdram_module = "AS4C16M16",
+ sdram_module = "AS4C16M16",
#sdram_data_width = 16,
- sdram_module = "MT48LC16M16",
- sdram_data_width = 32,
+ #sdram_module = "MT48LC16M16",
+ sdram_data_width = 16,
):
assert cpu in ["libresoc", "microwatt"]
platform = Platform()
sys_clk_freq = int(100e6)
+ #cpu_data_width = 32
+ cpu_data_width = 64
+
+ if cpu_data_width == 32:
+ variant = "standard32"
+ else:
+ variant = "standard"
+
+ #ram_fname = "/home/lkcl/src/libresoc/microwatt/" \
+ # "hello_world/hello_world.bin"
+ ram_fname = "/home/lkcl/src/libresoc/microwatt/" \
+ "tests/1.bin"
+ #ram_fname = None
+
+ ram_init = []
+ if ram_fname:
+ #ram_init = get_mem_data({
+ # ram_fname: "0x00000000",
+ # }, "little")
+ ram_init = get_mem_data(ram_fname, "little")
+
+ # remap the main RAM to reset-start-address
+ self.mem_map["main_ram"] = 0x00000000
+
+ # without sram nothing works, therefore move it to higher up
+ self.mem_map["sram"] = 0x90000000
+
+
# SoCCore -------------------------------------------------------------
SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq,
cpu_type = "microwatt",
cpu_cls = LibreSoC if cpu == "libresoc" \
else Microwatt,
#bus_data_width = 64,
+ cpu_variant = variant,
+ csr_data_width = 32,
+ l2_size = 0,
uart_name = "sim",
with_sdram = with_sdram,
sdram_module = sdram_module,
sdram_data_width = sdram_data_width,
- integrated_rom_size = 0x10000,
+ integrated_rom_size = 0 if ram_fname else 0x10000,
+ integrated_sram_size = 0x40000,
+ #integrated_main_ram_init = ram_init,
integrated_main_ram_size = 0x00000000 if with_sdram \
else 0x10000000 , # 256MB
- )
+ )
self.platform.name = "sim"
# CRG -----------------------------------------------------------------
self.submodules.crg = CRG(platform.request("sys_clk"))
- ram_init = []
+ #ram_init = []
# SDRAM ----------------------------------------------------
if with_sdram:
sdram_module.geom_settings,
sdram_module.timing_settings)
# FIXME: skip memtest to avoid corrupting memory
- self.add_constant("MEMTEST_BUS_SIZE", 64//16)
- self.add_constant("MEMTEST_DATA_SIZE", 64//16)
- self.add_constant("MEMTEST_ADDR_SIZE", 64//16)
+ self.add_constant("MEMTEST_BUS_SIZE", 128//16)
+ self.add_constant("MEMTEST_DATA_SIZE", 128//16)
+ self.add_constant("MEMTEST_ADDR_SIZE", 128//16)
+ self.add_constant("MEMTEST_BUS_DEBUG", 1)
+ self.add_constant("MEMTEST_ADDR_DEBUG", 1)
+ self.add_constant("MEMTEST_DATA_DEBUG", 1)
# Debug ---------------------------------------------------------------
dbg_dout = Signal(64)
dbg_msg = Signal(1)
- uptime = Signal(64)
+ # capture pc from dmi
+ pc = Signal(64)
+ active_dbg = Signal()
+
# increment counter, Stop after 100000 cycles
uptime = Signal(64)
self.sync += uptime.eq(uptime + 1)
- self.sync += If(uptime == 100000, Finish())
+ #self.sync += If(uptime == 1000000000000, Finish())
+ # DMI FSM counter and FSM itself
+ dmicount = Signal(10)
+ dmirunning = Signal(1)
+ dmi_monitor = Signal(1)
dmifsm = FSM()
self.submodules += dmifsm
self.cpu.dmi_req.eq(1), # DMI request
self.cpu.dmi_wr.eq(0), # DMI read
If(self.cpu.dmi_ack,
+ # acknowledge received: capture data.
(NextState("IDLE"),
NextValue(dbg_addr, dmi_addr),
NextValue(dbg_dout, self.cpu.dmi_dout),
NextValue(dbg_msg, 1),
- )
+ ),
),
),
)
)
+ # DMI response received: reset the dmi request and check if
+ # in "monitor" mode
dmifsm.act("IDLE",
- (NextValue(dmi_req, 0),
- NextValue(dmi_addr, 0),
+ If(dmi_monitor,
+ NextState("FIRE_MONITOR"), # fire "monitor" on next cycle
+ ).Else(
+ NextState("START"), # back to start on next cycle
+ ),
+ NextValue(dmi_req, 0),
+ NextValue(dmi_addr, 0),
+ NextValue(dmi_din, 0),
+ NextValue(dmi_wen, 0),
+ )
+
+ # "monitor" mode fires off a STAT request
+ dmifsm.act("FIRE_MONITOR",
+ (NextValue(dmi_req, 1),
+ NextValue(dmi_addr, 1), # DMI STAT address
NextValue(dmi_din, 0),
- NextValue(dmi_wen, 0),
+ NextValue(dmi_wen, 0), # read STAT
NextState("START"), # back to start on next cycle
)
)
# debug messages out
self.sync += If(dbg_msg,
- (If(dbg_addr == 0b10, # PC
+ (If(active_dbg & (dbg_addr == 0b10), # PC
Display("pc : %016x", dbg_dout),
),
- If(dbg_addr == 0b11, # PC
- Display(" msr: %016x", dbg_dout),
+ If(dbg_addr == 0b10, # PC
+ pc.eq(dbg_dout), # capture PC
),
+ #If(dbg_addr == 0b11, # MSR
+ # Display(" msr: %016x", dbg_dout),
+ #),
If(dbg_addr == 0b101, # GPR
Display(" gpr: %016x", dbg_dout),
),
+ # also check if this is a "stat"
+ If(dbg_addr == 1, # requested a STAT
+ #Display(" stat: %x", dbg_dout),
+ If(dbg_dout & 2, # bit 2 of STAT is "stopped" mode
+ dmirunning.eq(1), # continue running
+ dmi_monitor.eq(0), # and stop monitor mode
+ ),
+ ),
dbg_msg.eq(0)
)
)
)
)
+ self.sync += If(uptime == 4,
+ dmirunning.eq(1),
+ )
+
+ self.sync += If(dmirunning,
+ dmicount.eq(dmicount + 1),
+ )
+
# loop every 1<<N cycles
cyclewid = 9
# get the PC
- self.sync += If(uptime[0:cyclewid] == 4,
+ self.sync += If(dmicount == 4,
(dmi_addr.eq(0b10), # NIA
dmi_req.eq(1),
dmi_wen.eq(0),
)
# kick off a "step"
- self.sync += If(uptime[0:cyclewid] == 8,
+ self.sync += If(dmicount == 8,
(dmi_addr.eq(0), # CTRL
dmi_din.eq(1<<3), # STEP
dmi_req.eq(1),
dmi_wen.eq(1),
+ dmirunning.eq(0), # stop counter, need to fire "monitor"
+ dmi_monitor.eq(1), # start "monitor" instead
)
)
+ # limit range of pc for debug reporting
+ #self.comb += active_dbg.eq((0x378c <= pc) & (pc <= 0x38d8))
+ #self.comb += active_dbg.eq((0x0 < pc) & (pc < 0x58))
+ self.comb += active_dbg.eq(1)
+
# get the MSR
- self.sync += If(uptime[0:cyclewid] == 28,
+ self.sync += If(active_dbg & (dmicount == 12),
(dmi_addr.eq(0b11), # MSR
dmi_req.eq(1),
dmi_wen.eq(0),
# read all 32 GPRs
for i in range(32):
- self.sync += If(uptime[0:cyclewid] == 30+(i*8),
+ self.sync += If(active_dbg & (dmicount == 16+(i*8)),
(dmi_addr.eq(0b100), # GSPR addr
dmi_din.eq(i), # r1
dmi_req.eq(1),
)
)
- self.sync += If(uptime[0:cyclewid] == 34+(i*8),
+ self.sync += If(active_dbg & (dmicount == 20+(i*8)),
(dmi_addr.eq(0b101), # GSPR data
dmi_req.eq(1),
dmi_wen.eq(0),
)
)
+ # monitor bbus read/write
+ self.sync += If(active_dbg & self.cpu.dbus.stb & self.cpu.dbus.ack,
+ Display(" [%06x] dadr: %8x, we %d s %01x w %016x r: %016x",
+ #uptime,
+ 0,
+ self.cpu.dbus.adr,
+ self.cpu.dbus.we,
+ self.cpu.dbus.sel,
+ self.cpu.dbus.dat_w,
+ self.cpu.dbus.dat_r
+ )
+ )
+
+ return
+
# monitor ibus write
- self.sync += If(self.cpu.ibus.stb & self.cpu.ibus.ack &
+ self.sync += If(active_dbg & self.cpu.ibus.stb & self.cpu.ibus.ack &
self.cpu.ibus.we,
Display(" [%06x] iadr: %8x, s %01x w %016x",
- uptime,
+ #uptime,
+ 0,
self.cpu.ibus.adr,
self.cpu.ibus.sel,
self.cpu.ibus.dat_w,
)
)
# monitor ibus read
- self.sync += If(self.cpu.ibus.stb & self.cpu.ibus.ack &
+ self.sync += If(active_dbg & self.cpu.ibus.stb & self.cpu.ibus.ack &
~self.cpu.ibus.we,
Display(" [%06x] iadr: %8x, s %01x r %016x",
- uptime,
+ #uptime,
+ 0,
self.cpu.ibus.adr,
self.cpu.ibus.sel,
self.cpu.ibus.dat_r
)
)
- # monitor bbus read/write
- self.sync += If(self.cpu.dbus.stb & self.cpu.dbus.ack,
- Display(" [%06x] dadr: %8x, we %d s %01x w %016x r: %016x",
- uptime,
- self.cpu.dbus.adr,
- self.cpu.dbus.we,
- self.cpu.dbus.sel,
- self.cpu.dbus.dat_w,
- self.cpu.dbus.dat_r
- )
- )
-
# Build -----------------------------------------------------------------------
def main():