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
= 16,
36 assert cpu
in ["libresoc", "microwatt"]
38 sys_clk_freq
= int(100e6
)
43 if cpu_data_width
== 32:
44 variant
= "standard32"
48 # SoCCore -------------------------------------------------------------
49 SoCSDRAM
.__init
__(self
, platform
, clk_freq
=sys_clk_freq
,
50 cpu_type
= "microwatt",
51 cpu_cls
= LibreSoC
if cpu
== "libresoc" \
54 cpu_variant
= variant
,
58 with_sdram
= with_sdram
,
59 sdram_module
= sdram_module
,
60 sdram_data_width
= sdram_data_width
,
61 integrated_rom_size
= 0x10000,
62 integrated_main_ram_size
= 0x00000000 if with_sdram \
63 else 0x10000000 , # 256MB
65 self
.platform
.name
= "sim"
67 # CRG -----------------------------------------------------------------
68 self
.submodules
.crg
= CRG(platform
.request("sys_clk"))
72 # SDRAM ----------------------------------------------------
74 sdram_clk_freq
= int(100e6
) # FIXME: use 100MHz timings
75 sdram_module_cls
= getattr(litedram_modules
, sdram_module
)
76 sdram_rate
= "1:{}".format(
77 sdram_module_nphases
[sdram_module_cls
.memtype
])
78 sdram_module
= sdram_module_cls(sdram_clk_freq
, sdram_rate
)
79 phy_settings
= get_sdram_phy_settings(
80 memtype
= sdram_module
.memtype
,
81 data_width
= sdram_data_width
,
82 clk_freq
= sdram_clk_freq
)
83 self
.submodules
.sdrphy
= SDRAMPHYModel(sdram_module
,
89 sdram_module
.geom_settings
,
90 sdram_module
.timing_settings
)
91 # FIXME: skip memtest to avoid corrupting memory
92 self
.add_constant("MEMTEST_BUS_SIZE", 128//16)
93 self
.add_constant("MEMTEST_DATA_SIZE", 128//16)
94 self
.add_constant("MEMTEST_ADDR_SIZE", 128//16)
95 self
.add_constant("MEMTEST_BUS_DEBUG", 1)
96 self
.add_constant("MEMTEST_ADDR_DEBUG", 1)
97 self
.add_constant("MEMTEST_DATA_DEBUG", 1)
100 # Debug ---------------------------------------------------------------
104 # setup running of DMI FSM
107 dmi_dout
= Signal(64)
113 dbg_dout
= Signal(64)
116 # capture pc from dmi
118 active_dbg
= Signal()
120 # increment counter, Stop after 100000 cycles
122 self
.sync
+= uptime
.eq(uptime
+ 1)
123 #self.sync += If(uptime == 1000000000000, Finish())
126 self
.submodules
+= dmifsm
130 If(dmi_req
& dmi_wen
,
131 (self
.cpu
.dmi_addr
.eq(dmi_addr
), # DMI Addr
132 self
.cpu
.dmi_din
.eq(dmi_din
), # DMI in
133 self
.cpu
.dmi_req
.eq(1), # DMI request
134 self
.cpu
.dmi_wr
.eq(1), # DMI write
141 If(dmi_req
& ~dmi_wen
,
142 (self
.cpu
.dmi_addr
.eq(dmi_addr
), # DMI Addr
143 self
.cpu
.dmi_req
.eq(1), # DMI request
144 self
.cpu
.dmi_wr
.eq(0), # DMI read
147 NextValue(dbg_addr
, dmi_addr
),
148 NextValue(dbg_dout
, self
.cpu
.dmi_dout
),
149 NextValue(dbg_msg
, 1),
157 (NextValue(dmi_req
, 0),
158 NextValue(dmi_addr
, 0),
159 NextValue(dmi_din
, 0),
160 NextValue(dmi_wen
, 0),
161 NextState("START"), # back to start on next cycle
166 self
.sync
+= If(dbg_msg
,
167 (If(active_dbg
& (dbg_addr
== 0b10), # PC
168 Display("pc : %016x", dbg_dout
),
170 If(dbg_addr
== 0b10, # PC
171 pc
.eq(dbg_dout
), # capture PC
173 If(dbg_addr
== 0b11, # MSR
174 Display(" msr: %016x", dbg_dout
),
176 If(dbg_addr
== 0b101, # GPR
177 Display(" gpr: %016x", dbg_dout
),
184 self
.sync
+= If(uptime
== 0,
185 (dmi_addr
.eq(0), # CTRL
186 dmi_din
.eq(1<<0), # STOP
192 # loop every 1<<N cycles
196 self
.sync
+= If(uptime
[0:cyclewid
] == 4,
197 (dmi_addr
.eq(0b10), # NIA
204 self
.sync
+= If(uptime
[0:cyclewid
] == 8,
205 (dmi_addr
.eq(0), # CTRL
206 dmi_din
.eq(1<<3), # STEP
212 # limit range of pc for debug reporting
213 #self.comb += active_dbg.eq((0x5108 <= pc) & (pc <= 0x5234))
214 #self.comb += active_dbg.eq((0x0 < pc) & (pc < 0x58))
215 self
.comb
+= active_dbg
.eq(1)
218 self
.sync
+= If(active_dbg
& (uptime
[0:cyclewid
] == 28),
219 (dmi_addr
.eq(0b11), # MSR
227 self
.sync
+= If(active_dbg
& (uptime
[0:cyclewid
] == 30+(i
*8)),
228 (dmi_addr
.eq(0b100), # GSPR addr
235 self
.sync
+= If(active_dbg
& (uptime
[0:cyclewid
] == 34+(i
*8)),
236 (dmi_addr
.eq(0b101), # GSPR data
243 self
.sync
+= If(active_dbg
& self
.cpu
.ibus
.stb
& self
.cpu
.ibus
.ack
&
245 Display(" [%06x] iadr: %8x, s %01x w %016x",
253 self
.sync
+= If(active_dbg
& self
.cpu
.ibus
.stb
& self
.cpu
.ibus
.ack
&
255 Display(" [%06x] iadr: %8x, s %01x r %016x",
263 # monitor bbus read/write
264 self
.sync
+= If(active_dbg
& self
.cpu
.dbus
.stb
& self
.cpu
.dbus
.ack
,
265 Display(" [%06x] dadr: %8x, we %d s %01x w %016x r: %016x",
275 # Build -----------------------------------------------------------------------
278 parser
= argparse
.ArgumentParser(description
="LiteX LibreSoC CPU Sim")
279 parser
.add_argument("--cpu", default
="libresoc",
280 help="CPU to use: libresoc (default) or microwatt")
281 parser
.add_argument("--debug", action
="store_true",
282 help="Enable debug traces")
283 parser
.add_argument("--trace", action
="store_true",
284 help="Enable tracing")
285 parser
.add_argument("--trace-start", default
=0,
286 help="Cycle to start FST tracing")
287 parser
.add_argument("--trace-end", default
=-1,
288 help="Cycle to end FST tracing")
289 args
= parser
.parse_args()
291 sim_config
= SimConfig(default_clk
="sys_clk")
292 sim_config
.add_module("serial2console", "serial")
295 soc
= LibreSoCSim(cpu
=args
.cpu
, debug
=args
.debug
)
296 builder
= Builder(soc
,compile_gateware
= i
!=0)
297 builder
.build(sim_config
=sim_config
,
300 trace_start
= int(args
.trace_start
),
301 trace_end
= int(args
.trace_end
),
305 if __name__
== "__main__":