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
.builder
import Builder
17 from litex
.tools
.litex_sim
import Platform
19 from libresoc
import LibreSoC
20 from microwatt
import Microwatt
22 # LibreSoCSim -----------------------------------------------------------------
24 class LibreSoCSim(SoCCore
):
25 def __init__(self
, cpu
="libresoc", debug
=False):
26 assert cpu
in ["libresoc", "microwatt"]
28 sys_clk_freq
= int(1e6
)
30 # SoCCore -------------------------------------------------------------
31 SoCCore
.__init
__(self
, platform
, clk_freq
=sys_clk_freq
,
32 cpu_type
= "microwatt",
33 cpu_cls
= LibreSoC
if cpu
== "libresoc" \
37 integrated_rom_size
= 0x10000,
38 integrated_main_ram_size
= 0x10000000) # 256MB
39 self
.platform
.name
= "sim"
41 # CRG -----------------------------------------------------------------
42 self
.submodules
.crg
= CRG(platform
.request("sys_clk"))
44 # Debug ---------------------------------------------------------------
48 # setup running of DMI FSM
61 # increment counter, Stop after 100000 cycles
63 self
.sync
+= uptime
.eq(uptime
+ 1)
64 self
.sync
+= If(uptime
== 100000, Finish())
67 self
.submodules
+= dmifsm
72 (self
.cpu
.dmi_addr
.eq(dmi_addr
), # DMI Addr
73 self
.cpu
.dmi_din
.eq(dmi_din
), # DMI in
74 self
.cpu
.dmi_req
.eq(1), # DMI request
75 self
.cpu
.dmi_wr
.eq(1), # DMI write
82 If(dmi_req
& ~dmi_wen
,
83 (self
.cpu
.dmi_addr
.eq(dmi_addr
), # DMI Addr
84 self
.cpu
.dmi_req
.eq(1), # DMI request
85 self
.cpu
.dmi_wr
.eq(0), # DMI read
88 NextValue(dbg_addr
, dmi_addr
),
89 NextValue(dbg_dout
, self
.cpu
.dmi_dout
),
90 NextValue(dbg_msg
, 1),
98 (NextValue(dmi_req
, 0),
99 NextValue(dmi_addr
, 0),
100 NextValue(dmi_din
, 0),
101 NextValue(dmi_wen
, 0),
102 NextState("START"), # back to start on next cycle
107 self
.sync
+= If(dbg_msg
,
108 (If(dbg_addr
== 0b10, # PC
109 Display("pc : %016x", dbg_dout
),
111 If(dbg_addr
== 0b11, # PC
112 Display(" msr: %016x", dbg_dout
),
114 If(dbg_addr
== 0b101, # GPR
115 Display(" gpr: %016x", dbg_dout
),
122 self
.sync
+= If(uptime
== 0,
123 (dmi_addr
.eq(0), # CTRL
124 dmi_din
.eq(1<<0), # STOP
130 # loop every 1<<N cycles
134 self
.sync
+= If(uptime
[0:cyclewid
] == 4,
135 (dmi_addr
.eq(0b10), # NIA
142 self
.sync
+= If(uptime
[0:cyclewid
] == 8,
143 (dmi_addr
.eq(0), # CTRL
144 dmi_din
.eq(1<<3), # STEP
151 self
.sync
+= If(uptime
[0:cyclewid
] == 28,
152 (dmi_addr
.eq(0b11), # MSR
160 self
.sync
+= If(uptime
[0:cyclewid
] == 30+(i
*8),
161 (dmi_addr
.eq(0b100), # GSPR addr
168 self
.sync
+= If(uptime
[0:cyclewid
] == 34+(i
*8),
169 (dmi_addr
.eq(0b101), # GSPR data
176 self
.sync
+= If(self
.cpu
.ibus
.stb
& self
.cpu
.ibus
.ack
&
178 Display(" [%06x] iadr: %8x, s %01x w %016x",
186 self
.sync
+= If(self
.cpu
.ibus
.stb
& self
.cpu
.ibus
.ack
&
188 Display(" [%06x] iadr: %8x, s %01x r %016x",
196 # monitor bbus read/write
197 self
.sync
+= If(self
.cpu
.dbus
.stb
& self
.cpu
.dbus
.ack
,
198 Display(" [%06x] dadr: %8x, we %d s %01x w %016x r: %016x",
208 # Build -----------------------------------------------------------------------
211 parser
= argparse
.ArgumentParser(description
="LiteX LibreSoC CPU Sim")
212 parser
.add_argument("--cpu", default
="libresoc",
213 help="CPU to use: libresoc (default) or microwatt")
214 parser
.add_argument("--debug", action
="store_true",
215 help="Enable debug traces")
216 parser
.add_argument("--trace", action
="store_true",
217 help="Enable tracing")
218 parser
.add_argument("--trace-start", default
=0,
219 help="Cycle to start FST tracing")
220 parser
.add_argument("--trace-end", default
=-1,
221 help="Cycle to end FST tracing")
222 args
= parser
.parse_args()
224 sim_config
= SimConfig(default_clk
="sys_clk")
225 sim_config
.add_module("serial2console", "serial")
228 soc
= LibreSoCSim(cpu
=args
.cpu
, debug
=args
.debug
)
229 builder
= Builder(soc
,compile_gateware
= i
!=0)
230 builder
.build(sim_config
=sim_config
,
233 trace_start
= int(args
.trace_start
),
234 trace_end
= int(args
.trace_end
),
238 if __name__
== "__main__":