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)
86 # Debug ---------------------------------------------------------------
90 # setup running of DMI FSM
103 # increment counter, Stop after 100000 cycles
105 self
.sync
+= uptime
.eq(uptime
+ 1)
106 self
.sync
+= If(uptime
== 100000, Finish())
109 self
.submodules
+= dmifsm
113 If(dmi_req
& dmi_wen
,
114 (self
.cpu
.dmi_addr
.eq(dmi_addr
), # DMI Addr
115 self
.cpu
.dmi_din
.eq(dmi_din
), # DMI in
116 self
.cpu
.dmi_req
.eq(1), # DMI request
117 self
.cpu
.dmi_wr
.eq(1), # DMI write
124 If(dmi_req
& ~dmi_wen
,
125 (self
.cpu
.dmi_addr
.eq(dmi_addr
), # DMI Addr
126 self
.cpu
.dmi_req
.eq(1), # DMI request
127 self
.cpu
.dmi_wr
.eq(0), # DMI read
130 NextValue(dbg_addr
, dmi_addr
),
131 NextValue(dbg_dout
, self
.cpu
.dmi_dout
),
132 NextValue(dbg_msg
, 1),
140 (NextValue(dmi_req
, 0),
141 NextValue(dmi_addr
, 0),
142 NextValue(dmi_din
, 0),
143 NextValue(dmi_wen
, 0),
144 NextState("START"), # back to start on next cycle
149 self
.sync
+= If(dbg_msg
,
150 (If(dbg_addr
== 0b10, # PC
151 Display("pc : %016x", dbg_dout
),
153 If(dbg_addr
== 0b11, # PC
154 Display(" msr: %016x", dbg_dout
),
156 If(dbg_addr
== 0b101, # GPR
157 Display(" gpr: %016x", dbg_dout
),
164 self
.sync
+= If(uptime
== 0,
165 (dmi_addr
.eq(0), # CTRL
166 dmi_din
.eq(1<<0), # STOP
172 # loop every 1<<N cycles
176 self
.sync
+= If(uptime
[0:cyclewid
] == 4,
177 (dmi_addr
.eq(0b10), # NIA
184 self
.sync
+= If(uptime
[0:cyclewid
] == 8,
185 (dmi_addr
.eq(0), # CTRL
186 dmi_din
.eq(1<<3), # STEP
193 self
.sync
+= If(uptime
[0:cyclewid
] == 28,
194 (dmi_addr
.eq(0b11), # MSR
202 self
.sync
+= If(uptime
[0:cyclewid
] == 30+(i
*8),
203 (dmi_addr
.eq(0b100), # GSPR addr
210 self
.sync
+= If(uptime
[0:cyclewid
] == 34+(i
*8),
211 (dmi_addr
.eq(0b101), # GSPR data
218 self
.sync
+= If(self
.cpu
.ibus
.stb
& self
.cpu
.ibus
.ack
&
220 Display(" [%06x] iadr: %8x, s %01x w %016x",
228 self
.sync
+= If(self
.cpu
.ibus
.stb
& self
.cpu
.ibus
.ack
&
230 Display(" [%06x] iadr: %8x, s %01x r %016x",
238 # monitor bbus read/write
239 self
.sync
+= If(self
.cpu
.dbus
.stb
& self
.cpu
.dbus
.ack
,
240 Display(" [%06x] dadr: %8x, we %d s %01x w %016x r: %016x",
250 # Build -----------------------------------------------------------------------
253 parser
= argparse
.ArgumentParser(description
="LiteX LibreSoC CPU Sim")
254 parser
.add_argument("--cpu", default
="libresoc",
255 help="CPU to use: libresoc (default) or microwatt")
256 parser
.add_argument("--debug", action
="store_true",
257 help="Enable debug traces")
258 parser
.add_argument("--trace", action
="store_true",
259 help="Enable tracing")
260 parser
.add_argument("--trace-start", default
=0,
261 help="Cycle to start FST tracing")
262 parser
.add_argument("--trace-end", default
=-1,
263 help="Cycle to end FST tracing")
264 args
= parser
.parse_args()
266 sim_config
= SimConfig(default_clk
="sys_clk")
267 sim_config
.add_module("serial2console", "serial")
270 soc
= LibreSoCSim(cpu
=args
.cpu
, debug
=args
.debug
)
271 builder
= Builder(soc
,compile_gateware
= i
!=0)
272 builder
.build(sim_config
=sim_config
,
275 trace_start
= int(args
.trace_start
),
276 trace_end
= int(args
.trace_end
),
280 if __name__
== "__main__":