dcache.py commit first full tranlation pass, about five percent left
[soc.git] / src / soc / litex / florent / sim.py
1 #!/usr/bin/env python3
2
3 import os
4 import argparse
5
6 from migen import (Signal, FSM, If, Display, Finish, NextValue, NextState)
7
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
12
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
17
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
21
22 from litex.tools.litex_sim import Platform
23
24 from libresoc import LibreSoC
25 from microwatt import Microwatt
26
27 # LibreSoCSim -----------------------------------------------------------------
28
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,
35 ):
36 assert cpu in ["libresoc", "microwatt"]
37 platform = Platform()
38 sys_clk_freq = int(100e6)
39
40 cpu_data_width = 32
41 #cpu_data_width = 64
42
43 if cpu_data_width == 32:
44 variant = "standard32"
45 else:
46 variant = "standard"
47
48 # SoCCore -------------------------------------------------------------
49 SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq,
50 cpu_type = "microwatt",
51 cpu_cls = LibreSoC if cpu == "libresoc" \
52 else Microwatt,
53 #bus_data_width = 64,
54 cpu_variant = variant,
55 csr_data_width = 32,
56 l2_cache_size = 0,
57 uart_name = "sim",
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
64 )
65 self.platform.name = "sim"
66
67 # CRG -----------------------------------------------------------------
68 self.submodules.crg = CRG(platform.request("sys_clk"))
69
70 ram_init = []
71
72 # SDRAM ----------------------------------------------------
73 if with_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,
84 phy_settings,
85 init=ram_init
86 )
87 self.register_sdram(
88 self.sdrphy,
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)
98
99
100 # Debug ---------------------------------------------------------------
101 if not debug:
102 return
103
104 # setup running of DMI FSM
105 dmi_addr = Signal(3)
106 dmi_din = Signal(64)
107 dmi_dout = Signal(64)
108 dmi_wen = Signal(1)
109 dmi_req = Signal(1)
110
111 # debug log out
112 dbg_addr = Signal(3)
113 dbg_dout = Signal(64)
114 dbg_msg = Signal(1)
115
116 # capture pc from dmi
117 pc = Signal(64)
118 active_dbg = Signal()
119
120 # increment counter, Stop after 100000 cycles
121 uptime = Signal(64)
122 self.sync += uptime.eq(uptime + 1)
123 #self.sync += If(uptime == 1000000000000, Finish())
124
125 dmifsm = FSM()
126 self.submodules += dmifsm
127
128 # DMI FSM
129 dmifsm.act("START",
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
135 If(self.cpu.dmi_ack,
136 (NextState("IDLE"),
137 )
138 ),
139 ),
140 ),
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
145 If(self.cpu.dmi_ack,
146 (NextState("IDLE"),
147 NextValue(dbg_addr, dmi_addr),
148 NextValue(dbg_dout, self.cpu.dmi_dout),
149 NextValue(dbg_msg, 1),
150 )
151 ),
152 ),
153 )
154 )
155
156 dmifsm.act("IDLE",
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
162 )
163 )
164
165 # debug messages out
166 self.sync += If(dbg_msg,
167 (If(active_dbg & (dbg_addr == 0b10), # PC
168 Display("pc : %016x", dbg_dout),
169 ),
170 If(dbg_addr == 0b10, # PC
171 pc.eq(dbg_dout), # capture PC
172 ),
173 If(dbg_addr == 0b11, # MSR
174 Display(" msr: %016x", dbg_dout),
175 ),
176 If(dbg_addr == 0b101, # GPR
177 Display(" gpr: %016x", dbg_dout),
178 ),
179 dbg_msg.eq(0)
180 )
181 )
182
183 # kick off a "stop"
184 self.sync += If(uptime == 0,
185 (dmi_addr.eq(0), # CTRL
186 dmi_din.eq(1<<0), # STOP
187 dmi_req.eq(1),
188 dmi_wen.eq(1),
189 )
190 )
191
192 # loop every 1<<N cycles
193 cyclewid = 9
194
195 # get the PC
196 self.sync += If(uptime[0:cyclewid] == 4,
197 (dmi_addr.eq(0b10), # NIA
198 dmi_req.eq(1),
199 dmi_wen.eq(0),
200 )
201 )
202
203 # kick off a "step"
204 self.sync += If(uptime[0:cyclewid] == 8,
205 (dmi_addr.eq(0), # CTRL
206 dmi_din.eq(1<<3), # STEP
207 dmi_req.eq(1),
208 dmi_wen.eq(1),
209 )
210 )
211
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)
216
217 # get the MSR
218 self.sync += If(active_dbg & (uptime[0:cyclewid] == 28),
219 (dmi_addr.eq(0b11), # MSR
220 dmi_req.eq(1),
221 dmi_wen.eq(0),
222 )
223 )
224
225 # read all 32 GPRs
226 for i in range(32):
227 self.sync += If(active_dbg & (uptime[0:cyclewid] == 30+(i*8)),
228 (dmi_addr.eq(0b100), # GSPR addr
229 dmi_din.eq(i), # r1
230 dmi_req.eq(1),
231 dmi_wen.eq(1),
232 )
233 )
234
235 self.sync += If(active_dbg & (uptime[0:cyclewid] == 34+(i*8)),
236 (dmi_addr.eq(0b101), # GSPR data
237 dmi_req.eq(1),
238 dmi_wen.eq(0),
239 )
240 )
241
242 # monitor ibus write
243 self.sync += If(active_dbg & self.cpu.ibus.stb & self.cpu.ibus.ack &
244 self.cpu.ibus.we,
245 Display(" [%06x] iadr: %8x, s %01x w %016x",
246 uptime,
247 self.cpu.ibus.adr,
248 self.cpu.ibus.sel,
249 self.cpu.ibus.dat_w,
250 )
251 )
252 # monitor ibus read
253 self.sync += If(active_dbg & self.cpu.ibus.stb & self.cpu.ibus.ack &
254 ~self.cpu.ibus.we,
255 Display(" [%06x] iadr: %8x, s %01x r %016x",
256 uptime,
257 self.cpu.ibus.adr,
258 self.cpu.ibus.sel,
259 self.cpu.ibus.dat_r
260 )
261 )
262
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",
266 uptime,
267 self.cpu.dbus.adr,
268 self.cpu.dbus.we,
269 self.cpu.dbus.sel,
270 self.cpu.dbus.dat_w,
271 self.cpu.dbus.dat_r
272 )
273 )
274
275 # Build -----------------------------------------------------------------------
276
277 def main():
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()
290
291 sim_config = SimConfig(default_clk="sys_clk")
292 sim_config.add_module("serial2console", "serial")
293
294 for i in range(2):
295 soc = LibreSoCSim(cpu=args.cpu, debug=args.debug)
296 builder = Builder(soc,compile_gateware = i!=0)
297 builder.build(sim_config=sim_config,
298 run = i!=0,
299 trace = args.trace,
300 trace_start = int(args.trace_start),
301 trace_end = int(args.trace_end),
302 trace_fst = 0)
303 os.chdir("../")
304
305 if __name__ == "__main__":
306 main()