6 from migen
import (Signal
, FSM
, If
, Display
, Finish
, NextValue
, NextState
)
8 from litex
.build
.generic_platform
import Pins
, Subsignal
9 from litex
.build
.sim
import SimPlatform
10 from litex
.build
.io
import CRG
11 from litex
.build
.sim
.config
import SimConfig
13 from litex
.soc
.integration
.soc
import SoCRegion
14 from litex
.soc
.integration
.soc_core
import SoCCore
15 from litex
.soc
.integration
.soc_sdram
import SoCSDRAM
16 from litex
.soc
.integration
.builder
import Builder
18 from litedram
import modules
as litedram_modules
19 from litedram
.phy
.model
import SDRAMPHYModel
20 from litex
.tools
.litex_sim
import sdram_module_nphases
, get_sdram_phy_settings
22 from litex
.tools
.litex_sim
import Platform
24 from libresoc
import LibreSoC
25 from microwatt
import Microwatt
27 # LibreSoCSim -----------------------------------------------------------------
29 class LibreSoCSim(SoCSDRAM
):
30 def __init__(self
, cpu
="libresoc", debug
=False, with_sdram
=True,
31 #sdram_module = "AS4C16M16",
32 #sdram_data_width = 16,
33 sdram_module
= "MT48LC16M16",
34 sdram_data_width
= 32,
36 assert cpu
in ["libresoc", "microwatt"]
38 sys_clk_freq
= int(100e6
)
40 # SoCCore -------------------------------------------------------------
41 SoCSDRAM
.__init
__(self
, platform
, clk_freq
=sys_clk_freq
,
42 cpu_type
= "microwatt",
43 cpu_cls
= LibreSoC
if cpu
== "libresoc" \
47 with_sdram
= with_sdram
,
48 sdram_module
= sdram_module
,
49 sdram_data_width
= sdram_data_width
,
50 integrated_rom_size
= 0x10000,
51 integrated_main_ram_size
= 0x00000000 if with_sdram \
52 else 0x10000000 , # 256MB
54 self
.platform
.name
= "sim"
56 # CRG -----------------------------------------------------------------
57 self
.submodules
.crg
= CRG(platform
.request("sys_clk"))
61 # SDRAM ----------------------------------------------------
63 sdram_clk_freq
= int(100e6
) # FIXME: use 100MHz timings
64 sdram_module_cls
= getattr(litedram_modules
, sdram_module
)
65 sdram_rate
= "1:{}".format(
66 sdram_module_nphases
[sdram_module_cls
.memtype
])
67 sdram_module
= sdram_module_cls(sdram_clk_freq
, sdram_rate
)
68 phy_settings
= get_sdram_phy_settings(
69 memtype
= sdram_module
.memtype
,
70 data_width
= sdram_data_width
,
71 clk_freq
= sdram_clk_freq
)
72 self
.submodules
.sdrphy
= SDRAMPHYModel(sdram_module
,
78 sdram_module
.geom_settings
,
79 sdram_module
.timing_settings
)
80 # FIXME: skip memtest to avoid corrupting memory
81 self
.add_constant("MEMTEST_BUS_SIZE", 64//16)
82 self
.add_constant("MEMTEST_DATA_SIZE", 64//16)
83 self
.add_constant("MEMTEST_ADDR_SIZE", 64//16)
84 self
.add_constant("MEMTEST_BUS_DEBUG", 1)
87 # Debug ---------------------------------------------------------------
91 # setup running of DMI FSM
100 dbg_dout
= Signal(64)
103 # capture pc from dmi
105 active_dbg
= Signal()
107 # increment counter, Stop after 100000 cycles
109 self
.sync
+= uptime
.eq(uptime
+ 1)
110 #self.sync += If(uptime == 1000000000000, Finish())
113 self
.submodules
+= dmifsm
117 If(dmi_req
& dmi_wen
,
118 (self
.cpu
.dmi_addr
.eq(dmi_addr
), # DMI Addr
119 self
.cpu
.dmi_din
.eq(dmi_din
), # DMI in
120 self
.cpu
.dmi_req
.eq(1), # DMI request
121 self
.cpu
.dmi_wr
.eq(1), # DMI write
128 If(dmi_req
& ~dmi_wen
,
129 (self
.cpu
.dmi_addr
.eq(dmi_addr
), # DMI Addr
130 self
.cpu
.dmi_req
.eq(1), # DMI request
131 self
.cpu
.dmi_wr
.eq(0), # DMI read
134 NextValue(dbg_addr
, dmi_addr
),
135 NextValue(dbg_dout
, self
.cpu
.dmi_dout
),
136 NextValue(dbg_msg
, 1),
144 (NextValue(dmi_req
, 0),
145 NextValue(dmi_addr
, 0),
146 NextValue(dmi_din
, 0),
147 NextValue(dmi_wen
, 0),
148 NextState("START"), # back to start on next cycle
153 self
.sync
+= If(dbg_msg
,
154 (If(active_dbg
& (dbg_addr
== 0b10), # PC
155 Display("pc : %016x", dbg_dout
),
157 If(dbg_addr
== 0b10, # PC
158 pc
.eq(dbg_dout
), # capture PC
160 If(dbg_addr
== 0b11, # MSR
161 Display(" msr: %016x", dbg_dout
),
163 If(dbg_addr
== 0b101, # GPR
164 Display(" gpr: %016x", dbg_dout
),
171 self
.sync
+= If(uptime
== 0,
172 (dmi_addr
.eq(0), # CTRL
173 dmi_din
.eq(1<<0), # STOP
179 # loop every 1<<N cycles
183 self
.sync
+= If(uptime
[0:cyclewid
] == 4,
184 (dmi_addr
.eq(0b10), # NIA
191 self
.sync
+= If(uptime
[0:cyclewid
] == 8,
192 (dmi_addr
.eq(0), # CTRL
193 dmi_din
.eq(1<<3), # STEP
199 # limit range of pc for debug reporting
200 self
.comb
+= active_dbg
.eq((0x5108 <= pc
) & (pc
<= 0x5234))
201 #self.comb += active_dbg.eq((0x0 < pc) & (pc < 0x58))
204 self
.sync
+= If(active_dbg
& (uptime
[0:cyclewid
] == 28),
205 (dmi_addr
.eq(0b11), # MSR
213 self
.sync
+= If(active_dbg
& (uptime
[0:cyclewid
] == 30+(i
*8)),
214 (dmi_addr
.eq(0b100), # GSPR addr
221 self
.sync
+= If(active_dbg
& (uptime
[0:cyclewid
] == 34+(i
*8)),
222 (dmi_addr
.eq(0b101), # GSPR data
229 self
.sync
+= If(active_dbg
& self
.cpu
.ibus
.stb
& self
.cpu
.ibus
.ack
&
231 Display(" [%06x] iadr: %8x, s %01x w %016x",
239 self
.sync
+= If(active_dbg
& self
.cpu
.ibus
.stb
& self
.cpu
.ibus
.ack
&
241 Display(" [%06x] iadr: %8x, s %01x r %016x",
249 # monitor bbus read/write
250 self
.sync
+= If(active_dbg
& self
.cpu
.dbus
.stb
& self
.cpu
.dbus
.ack
,
251 Display(" [%06x] dadr: %8x, we %d s %01x w %016x r: %016x",
261 # Build -----------------------------------------------------------------------
264 parser
= argparse
.ArgumentParser(description
="LiteX LibreSoC CPU Sim")
265 parser
.add_argument("--cpu", default
="libresoc",
266 help="CPU to use: libresoc (default) or microwatt")
267 parser
.add_argument("--debug", action
="store_true",
268 help="Enable debug traces")
269 parser
.add_argument("--trace", action
="store_true",
270 help="Enable tracing")
271 parser
.add_argument("--trace-start", default
=0,
272 help="Cycle to start FST tracing")
273 parser
.add_argument("--trace-end", default
=-1,
274 help="Cycle to end FST tracing")
275 args
= parser
.parse_args()
277 sim_config
= SimConfig(default_clk
="sys_clk")
278 sim_config
.add_module("serial2console", "serial")
281 soc
= LibreSoCSim(cpu
=args
.cpu
, debug
=args
.debug
)
282 builder
= Builder(soc
,compile_gateware
= i
!=0)
283 builder
.build(sim_config
=sim_config
,
286 trace_start
= int(args
.trace_start
),
287 trace_end
= int(args
.trace_end
),
291 if __name__
== "__main__":