cs_n and cke in sdram need to match in length
[soc.git] / src / soc / litex / florent / ls180soc.py
1 #!/usr/bin/env python3
2
3 import os
4 import argparse
5 from functools import reduce
6 from operator import or_
7
8 from migen import (Signal, FSM, If, Display, Finish, NextValue, NextState,
9 Cat, Record, ClockSignal, wrap)
10
11 from litex.build.generic_platform import Pins, Subsignal
12 from litex.build.sim import SimPlatform
13 from litex.build.io import CRG
14 from litex.build.sim.config import SimConfig
15
16 from litex.soc.integration.soc import SoCRegion
17 from litex.soc.integration.soc_core import SoCCore
18 from litex.soc.integration.soc_sdram import SoCSDRAM
19 from litex.soc.integration.builder import Builder
20 from litex.soc.integration.common import get_mem_data
21
22 from litedram import modules as litedram_modules
23 from litedram.phy.model import SDRAMPHYModel
24 #from litedram.phy.gensdrphy import GENSDRPHY, HalfRateGENSDRPHY
25 from litedram.common import PHYPadsCombiner, PhySettings
26 from litedram.phy.dfi import Interface as DFIInterface
27 from litex.soc.cores.spi import SPIMaster
28 from litex.soc.cores.pwm import PWM
29 from litex.soc.cores.bitbang import I2CMaster
30
31 from litex.tools.litex_sim import sdram_module_nphases, get_sdram_phy_settings
32
33 from litex.tools.litex_sim import Platform
34 from libresoc.ls180 import LS180Platform
35
36 from migen import Module
37 from litex.soc.interconnect.csr import AutoCSR
38
39 from libresoc import LibreSoC
40 from microwatt import Microwatt
41
42 # HACK!
43 from litex.soc.integration.soc import SoCCSRHandler
44 SoCCSRHandler.supported_address_width.append(12)
45
46 # GPIO Tristate -------------------------------------------------------
47 # doesn't work properly.
48 #from litex.soc.cores.gpio import GPIOTristate
49 from litex.soc.interconnect.csr import CSRStorage, CSRStatus
50 from migen.genlib.cdc import MultiReg
51
52 # Imports
53 from litex.soc.interconnect import wishbone
54 from litesdcard.phy import (SDPHY, SDPHYClocker,
55 SDPHYInit, SDPHYCMDW, SDPHYCMDR,
56 SDPHYDATAW, SDPHYDATAR,
57 _sdpads_layout)
58 from litesdcard.core import SDCore
59 from litesdcard.frontend.dma import SDBlock2MemDMA, SDMem2BlockDMA
60 from litex.build.io import SDROutput, SDRInput
61
62
63 class GPIOTristateASIC(Module, AutoCSR):
64 def __init__(self, pads):
65 nbits = len(pads.oe) # hack
66 self._oe = CSRStorage(nbits, description="GPIO Tristate(s) Control.")
67 self._in = CSRStatus(nbits, description="GPIO Input(s) Status.")
68 self._out = CSRStorage(nbits, description="GPIO Ouptut(s) Control.")
69
70 # # #
71
72 _pads = Record( (("i", nbits),
73 ("o", nbits),
74 ("oe", nbits)))
75 self.comb += _pads.i.eq(pads.i)
76 self.comb += pads.o.eq(_pads.o)
77 self.comb += pads.oe.eq(_pads.oe)
78
79 self.comb += _pads.oe.eq(self._oe.storage)
80 self.comb += _pads.o.eq(self._out.storage)
81 for i in range(nbits):
82 self.specials += MultiReg(_pads.i[i], self._in.status[i])
83
84 # SDCard PHY IO -------------------------------------------------------
85
86 class SDRPad(Module):
87 def __init__(self, pad, name, o, oe, i):
88 clk = ClockSignal()
89 _o = getattr(pad, "%s_o" % name)
90 _oe = getattr(pad, "%s_oe" % name)
91 _i = getattr(pad, "%s_i" % name)
92 for j in range(len(_o)):
93 self.specials += SDROutput(clk=clk, i=o[j], o=_o[j])
94 self.specials += SDROutput(clk=clk, i=oe, o=_oe[j])
95 self.specials += SDRInput(clk=clk, i=_i[j], o=i[j])
96
97
98 class SDPHYIOGen(Module):
99 def __init__(self, clocker, sdpads, pads):
100 # Rst
101 if hasattr(pads, "rst"):
102 self.comb += pads.rst.eq(0)
103
104 # Clk
105 self.specials += SDROutput(
106 clk = ClockSignal(),
107 i = ~clocker.clk & sdpads.clk,
108 o = pads.clk
109 )
110
111 # Cmd
112 c = sdpads.cmd
113 self.submodules.sd_cmd = SDRPad(pads, "cmd", c.o, c.oe, c.i)
114
115 # Data
116 d = sdpads.data
117 self.submodules.sd_data = SDRPad(pads, "data", d.o, d.oe, d.i)
118
119
120 class SDPHY(Module, AutoCSR):
121 def __init__(self, pads, device, sys_clk_freq,
122 cmd_timeout=10e-3, data_timeout=10e-3):
123 self.card_detect = CSRStatus() # Assume SDCard is present if no cd pin.
124 self.comb += self.card_detect.status.eq(getattr(pads, "cd", 0))
125
126 self.submodules.clocker = clocker = SDPHYClocker()
127 self.submodules.init = init = SDPHYInit()
128 self.submodules.cmdw = cmdw = SDPHYCMDW()
129 self.submodules.cmdr = cmdr = SDPHYCMDR(sys_clk_freq,
130 cmd_timeout, cmdw)
131 self.submodules.dataw = dataw = SDPHYDATAW()
132 self.submodules.datar = datar = SDPHYDATAR(sys_clk_freq,
133 data_timeout)
134
135 # # #
136
137 self.sdpads = sdpads = Record(_sdpads_layout)
138
139 # IOs
140 sdphy_cls = SDPHYIOGen
141 self.submodules.io = sdphy_cls(clocker, sdpads, pads)
142
143 # Connect pads_out of submodules to physical pads --------------
144 pl = [init, cmdw, cmdr, dataw, datar]
145 self.comb += [
146 sdpads.clk.eq( reduce(or_, [m.pads_out.clk for m in pl])),
147 sdpads.cmd.oe.eq( reduce(or_, [m.pads_out.cmd.oe for m in pl])),
148 sdpads.cmd.o.eq( reduce(or_, [m.pads_out.cmd.o for m in pl])),
149 sdpads.data.oe.eq(reduce(or_, [m.pads_out.data.oe for m in pl])),
150 sdpads.data.o.eq( reduce(or_, [m.pads_out.data.o for m in pl])),
151 ]
152 for m in pl:
153 self.comb += m.pads_out.ready.eq(self.clocker.ce)
154
155 # Connect physical pads to pads_in of submodules ---------------
156 for m in pl:
157 self.comb += m.pads_in.valid.eq(self.clocker.ce)
158 self.comb += m.pads_in.cmd.i.eq(sdpads.cmd.i)
159 self.comb += m.pads_in.data.i.eq(sdpads.data.i)
160
161 # Speed Throttling -------------------------------------------
162 self.comb += clocker.stop.eq(dataw.stop | datar.stop)
163
164
165 # Generic SDR PHY ---------------------------------------------------------
166
167 class GENSDRPHY(Module):
168 def __init__(self, pads, cl=2, cmd_latency=1):
169 pads = PHYPadsCombiner(pads)
170 addressbits = len(pads.a)
171 bankbits = len(pads.ba)
172 nranks = 1 if not hasattr(pads, "cs_n") else len(pads.cs_n)
173 databits = len(pads.dq_i)
174 assert cl in [2, 3]
175 assert databits%8 == 0
176
177 # PHY settings ----------------------------------------------------
178 self.settings = PhySettings(
179 phytype = "GENSDRPHY",
180 memtype = "SDR",
181 databits = databits,
182 dfi_databits = databits,
183 nranks = nranks,
184 nphases = 1,
185 rdphase = 0,
186 wrphase = 0,
187 rdcmdphase = 0,
188 wrcmdphase = 0,
189 cl = cl,
190 read_latency = cl + cmd_latency,
191 write_latency = 0
192 )
193
194 # DFI Interface ---------------------------------------------------
195 self.dfi = dfi = DFIInterface(addressbits, bankbits, nranks, databits)
196
197 # # #
198
199 # Iterate on pads groups ------------------------------------------
200 for pads_group in range(len(pads.groups)):
201 pads.sel_group(pads_group)
202
203 # Addresses and Commands --------------------------------------
204 p0 = dfi.p0
205 self.specials += [SDROutput(i=p0.address[i], o=pads.a[i])
206 for i in range(len(pads.a))]
207 self.specials += [SDROutput(i=p0.bank[i], o=pads.ba[i])
208 for i in range(len(pads.ba))]
209 self.specials += SDROutput(i=p0.cas_n, o=pads.cas_n)
210 self.specials += SDROutput(i=p0.ras_n, o=pads.ras_n)
211 self.specials += SDROutput(i=p0.we_n, o=pads.we_n)
212 if hasattr(pads, "cke"):
213 for i in range(len(pads.cke)):
214 self.specials += SDROutput(i=p0.cke[i], o=pads.cke[i])
215 if hasattr(pads, "cs_n"):
216 for i in range(len(pads.cs_n)):
217 self.specials += SDROutput(i=p0.cs_n[i], o=pads.cs_n[i])
218
219 # DQ/DM Data Path -------------------------------------------------
220
221 d = dfi.p0
222 self.submodules.dq = SDRPad(pads, "dq", d.wrdata, d.wrdata_en, d.rddata)
223
224 if hasattr(pads, "dm"):
225 for i in range(len(pads.dm)):
226 self.comb += pads.dm[i].eq(0) # FIXME
227
228 # DQ/DM Control Path ----------------------------------------------
229 rddata_en = Signal(cl + cmd_latency)
230 self.sync += rddata_en.eq(Cat(dfi.p0.rddata_en, rddata_en))
231 self.sync += dfi.p0.rddata_valid.eq(rddata_en[-1])
232
233
234 # LibreSoC 180nm ASIC -------------------------------------------------------
235
236 class LibreSoCSim(SoCCore):
237 def __init__(self, cpu="libresoc", debug=False, with_sdram=True,
238 sdram_module = "AS4C16M16",
239 #sdram_data_width = 16,
240 #sdram_module = "MT48LC16M16",
241 sdram_data_width = 16,
242 irq_reserved_irqs = {'uart': 0},
243 platform='sim',
244 ):
245 assert cpu in ["libresoc", "microwatt"]
246 sys_clk_freq = int(50e6)
247
248 if platform == 'sim':
249 platform = Platform()
250 uart_name = "sim"
251 elif platform == 'ls180':
252 platform = LS180Platform()
253 uart_name = "serial"
254
255 #cpu_data_width = 32
256 cpu_data_width = 64
257
258 variant = "ls180"
259
260 # reserve XICS ICP and XICS memory addresses.
261 self.mem_map['icp'] = 0xc0010000
262 self.mem_map['ics'] = 0xc0011000
263 #self.csr_map["icp"] = 8 # 8 x 0x800 == 0x4000
264 #self.csr_map["ics"] = 10 # 10 x 0x800 == 0x5000
265
266 ram_init = []
267 if False:
268 #ram_init = get_mem_data({
269 # ram_fname: "0x00000000",
270 # }, "little")
271 ram_init = get_mem_data(ram_fname, "little")
272
273 # remap the main RAM to reset-start-address
274
275 # without sram nothing works, therefore move it to higher up
276 self.mem_map["sram"] = 0x90000000
277
278 # put UART at 0xc000200 (w00t! this works!)
279 self.csr_map["uart"] = 4
280
281 self.mem_map["main_ram"] = 0x90000000
282 self.mem_map["sram"] = 0x00000000
283
284 # SoCCore -------------------------------------------------------------
285 SoCCore.__init__(self, platform, clk_freq=sys_clk_freq,
286 cpu_type = "microwatt",
287 cpu_cls = LibreSoC if cpu == "libresoc" \
288 else Microwatt,
289 #bus_data_width = 64,
290 csr_address_width = 14, # limit to 0x8000
291 cpu_variant = variant,
292 csr_data_width = 8,
293 l2_size = 0,
294 uart_name = uart_name,
295 with_sdram = with_sdram,
296 sdram_module = sdram_module,
297 sdram_data_width = sdram_data_width,
298 integrated_rom_size = 0, # if ram_fname else 0x10000,
299 integrated_sram_size = 0x200,
300 #integrated_main_ram_init = ram_init,
301 integrated_main_ram_size = 0x00000000 if with_sdram \
302 else 0x10000000 , # 256MB
303 )
304 self.platform.name = "ls180"
305
306 # SDR SDRAM ----------------------------------------------
307 if False: # not self.integrated_main_ram_size:
308 self.submodules.sdrphy = sdrphy_cls(platform.request("sdram"))
309
310 if cpu == "libresoc":
311 # XICS interrupt devices
312 icp_addr = self.mem_map['icp']
313 icp_wb = self.cpu.xics_icp
314 icp_region = SoCRegion(origin=icp_addr, size=0x20, cached=False)
315 self.bus.add_slave(name='icp', slave=icp_wb, region=icp_region)
316
317 ics_addr = self.mem_map['ics']
318 ics_wb = self.cpu.xics_ics
319 ics_region = SoCRegion(origin=ics_addr, size=0x1000, cached=False)
320 self.bus.add_slave(name='ics', slave=ics_wb, region=ics_region)
321
322 # CRG -----------------------------------------------------------------
323 self.submodules.crg = CRG(platform.request("sys_clk"),
324 platform.request("sys_rst"))
325
326 #ram_init = []
327
328 # SDRAM ----------------------------------------------------
329 if with_sdram:
330 sdram_clk_freq = int(100e6) # FIXME: use 100MHz timings
331 sdram_module_cls = getattr(litedram_modules, sdram_module)
332 sdram_rate = "1:{}".format(
333 sdram_module_nphases[sdram_module_cls.memtype])
334 sdram_module = sdram_module_cls(sdram_clk_freq, sdram_rate)
335 phy_settings = get_sdram_phy_settings(
336 memtype = sdram_module.memtype,
337 data_width = sdram_data_width,
338 clk_freq = sdram_clk_freq)
339 #sdrphy_cls = HalfRateGENSDRPHY
340 sdrphy_cls = GENSDRPHY
341 self.submodules.sdrphy = sdrphy_cls(platform.request("sdram"))
342 #self.submodules.sdrphy = sdrphy_cls(sdram_module,
343 # phy_settings,
344 # init=ram_init
345 # )
346 self.add_sdram("sdram",
347 phy = self.sdrphy,
348 module = sdram_module,
349 origin = self.mem_map["main_ram"],
350 size = 0x80000000,
351 l2_cache_size = 0, # 8192
352 l2_cache_min_data_width = 128,
353 l2_cache_reverse = True
354 )
355 # FIXME: skip memtest to avoid corrupting memory
356 self.add_constant("MEMTEST_BUS_SIZE", 128//16)
357 self.add_constant("MEMTEST_DATA_SIZE", 128//16)
358 self.add_constant("MEMTEST_ADDR_SIZE", 128//16)
359 self.add_constant("MEMTEST_BUS_DEBUG", 1)
360 self.add_constant("MEMTEST_ADDR_DEBUG", 1)
361 self.add_constant("MEMTEST_DATA_DEBUG", 1)
362
363 # GPIOs (bi-directional)
364 self.submodules.gpio = GPIOTristateASIC(platform.request("gpio"))
365 self.add_csr("gpio")
366
367 # SPI Master
368 self.submodules.spi_master = SPIMaster(
369 pads = platform.request("spi_master"),
370 data_width = 8,
371 sys_clk_freq = sys_clk_freq,
372 spi_clk_freq = 8e6,
373 )
374 self.add_csr("spi_master")
375
376 # EINTs - very simple, wire up top 3 bits to ls180 "eint" pins
377 self.comb += self.cpu.interrupt[12:16].eq(platform.request("eint"))
378
379 # JTAG
380 jtagpads = platform.request("jtag")
381 self.comb += self.cpu.jtag_tck.eq(jtagpads.tck)
382 self.comb += self.cpu.jtag_tms.eq(jtagpads.tms)
383 self.comb += self.cpu.jtag_tdi.eq(jtagpads.tdi)
384 self.comb += jtagpads.tdo.eq(self.cpu.jtag_tdo)
385
386 # PWM
387 for i in range(2):
388 name = "pwm%d" % i
389 setattr(self.submodules, name, PWM(platform.request("pwm", i)))
390 self.add_csr(name)
391
392 # I2C Master
393 self.submodules.i2c = I2CMaster(platform.request("i2c"))
394 self.add_csr("i2c")
395
396 # SDCard -----------------------------------------------------
397
398 # Emulator / Pads
399 sdcard_pads = self.platform.request("sdcard")
400
401 # Core
402 self.submodules.sdphy = SDPHY(sdcard_pads,
403 self.platform.device, self.clk_freq)
404 self.submodules.sdcore = SDCore(self.sdphy)
405 self.add_csr("sdphy")
406 self.add_csr("sdcore")
407
408 # Block2Mem DMA
409 bus = wishbone.Interface(data_width=self.bus.data_width,
410 adr_width=self.bus.address_width)
411 self.submodules.sdblock2mem = SDBlock2MemDMA(bus=bus,
412 endianness=self.cpu.endianness)
413 self.comb += self.sdcore.source.connect(self.sdblock2mem.sink)
414 dma_bus = self.bus if not hasattr(self, "dma_bus") else self.dma_bus
415 dma_bus.add_master("sdblock2mem", master=bus)
416 self.add_csr("sdblock2mem")
417
418 # Mem2Block DMA
419 bus = wishbone.Interface(data_width=self.bus.data_width,
420 adr_width=self.bus.address_width)
421 self.submodules.sdmem2block = SDMem2BlockDMA(bus=bus,
422 endianness=self.cpu.endianness)
423 self.comb += self.sdmem2block.source.connect(self.sdcore.sink)
424 dma_bus = self.bus if not hasattr(self, "dma_bus") else self.dma_bus
425 dma_bus.add_master("sdmem2block", master=bus)
426 self.add_csr("sdmem2block")
427
428 # Debug ---------------------------------------------------------------
429 if not debug:
430 return
431
432 # setup running of DMI FSM
433 dmi_addr = Signal(4)
434 dmi_din = Signal(64)
435 dmi_dout = Signal(64)
436 dmi_wen = Signal(1)
437 dmi_req = Signal(1)
438
439 # debug log out
440 dbg_addr = Signal(4)
441 dbg_dout = Signal(64)
442 dbg_msg = Signal(1)
443
444 # capture pc from dmi
445 pc = Signal(64)
446 active_dbg = Signal()
447 active_dbg_cr = Signal()
448 active_dbg_xer = Signal()
449
450 # xer flags
451 xer_so = Signal()
452 xer_ca = Signal()
453 xer_ca32 = Signal()
454 xer_ov = Signal()
455 xer_ov32 = Signal()
456
457 # increment counter, Stop after 100000 cycles
458 uptime = Signal(64)
459 self.sync += uptime.eq(uptime + 1)
460 #self.sync += If(uptime == 1000000000000, Finish())
461
462 # DMI FSM counter and FSM itself
463 dmicount = Signal(10)
464 dmirunning = Signal(1)
465 dmi_monitor = Signal(1)
466 dmifsm = FSM()
467 self.submodules += dmifsm
468
469 # DMI FSM
470 dmifsm.act("START",
471 If(dmi_req & dmi_wen,
472 (self.cpu.dmi_addr.eq(dmi_addr), # DMI Addr
473 self.cpu.dmi_din.eq(dmi_din), # DMI in
474 self.cpu.dmi_req.eq(1), # DMI request
475 self.cpu.dmi_wr.eq(1), # DMI write
476 If(self.cpu.dmi_ack,
477 (NextState("IDLE"),
478 )
479 ),
480 ),
481 ),
482 If(dmi_req & ~dmi_wen,
483 (self.cpu.dmi_addr.eq(dmi_addr), # DMI Addr
484 self.cpu.dmi_req.eq(1), # DMI request
485 self.cpu.dmi_wr.eq(0), # DMI read
486 If(self.cpu.dmi_ack,
487 # acknowledge received: capture data.
488 (NextState("IDLE"),
489 NextValue(dbg_addr, dmi_addr),
490 NextValue(dbg_dout, self.cpu.dmi_dout),
491 NextValue(dbg_msg, 1),
492 ),
493 ),
494 ),
495 )
496 )
497
498 # DMI response received: reset the dmi request and check if
499 # in "monitor" mode
500 dmifsm.act("IDLE",
501 If(dmi_monitor,
502 NextState("FIRE_MONITOR"), # fire "monitor" on next cycle
503 ).Else(
504 NextState("START"), # back to start on next cycle
505 ),
506 NextValue(dmi_req, 0),
507 NextValue(dmi_addr, 0),
508 NextValue(dmi_din, 0),
509 NextValue(dmi_wen, 0),
510 )
511
512 # "monitor" mode fires off a STAT request
513 dmifsm.act("FIRE_MONITOR",
514 (NextValue(dmi_req, 1),
515 NextValue(dmi_addr, 1), # DMI STAT address
516 NextValue(dmi_din, 0),
517 NextValue(dmi_wen, 0), # read STAT
518 NextState("START"), # back to start on next cycle
519 )
520 )
521
522 self.comb += xer_so.eq((dbg_dout & 1) == 1)
523 self.comb += xer_ca.eq((dbg_dout & 4) == 4)
524 self.comb += xer_ca32.eq((dbg_dout & 8) == 8)
525 self.comb += xer_ov.eq((dbg_dout & 16) == 16)
526 self.comb += xer_ov32.eq((dbg_dout & 32) == 32)
527
528 # debug messages out
529 self.sync += If(dbg_msg,
530 (If(active_dbg & (dbg_addr == 0b10), # PC
531 Display("pc : %016x", dbg_dout),
532 ),
533 If(dbg_addr == 0b10, # PC
534 pc.eq(dbg_dout), # capture PC
535 ),
536 #If(dbg_addr == 0b11, # MSR
537 # Display(" msr: %016x", dbg_dout),
538 #),
539 If(dbg_addr == 0b1000, # CR
540 Display(" cr : %016x", dbg_dout),
541 ),
542 If(dbg_addr == 0b1001, # XER
543 Display(" xer: so %d ca %d 32 %d ov %d 32 %d",
544 xer_so, xer_ca, xer_ca32, xer_ov, xer_ov32),
545 ),
546 If(dbg_addr == 0b101, # GPR
547 Display(" gpr: %016x", dbg_dout),
548 ),
549 # also check if this is a "stat"
550 If(dbg_addr == 1, # requested a STAT
551 #Display(" stat: %x", dbg_dout),
552 If(dbg_dout & 2, # bit 2 of STAT is "stopped" mode
553 dmirunning.eq(1), # continue running
554 dmi_monitor.eq(0), # and stop monitor mode
555 ),
556 ),
557 dbg_msg.eq(0)
558 )
559 )
560
561 # kick off a "stop"
562 self.sync += If(uptime == 0,
563 (dmi_addr.eq(0), # CTRL
564 dmi_din.eq(1<<0), # STOP
565 dmi_req.eq(1),
566 dmi_wen.eq(1),
567 )
568 )
569
570 self.sync += If(uptime == 4,
571 dmirunning.eq(1),
572 )
573
574 self.sync += If(dmirunning,
575 dmicount.eq(dmicount + 1),
576 )
577
578 # loop every 1<<N cycles
579 cyclewid = 9
580
581 # get the PC
582 self.sync += If(dmicount == 4,
583 (dmi_addr.eq(0b10), # NIA
584 dmi_req.eq(1),
585 dmi_wen.eq(0),
586 )
587 )
588
589 # kick off a "step"
590 self.sync += If(dmicount == 8,
591 (dmi_addr.eq(0), # CTRL
592 dmi_din.eq(1<<3), # STEP
593 dmi_req.eq(1),
594 dmi_wen.eq(1),
595 dmirunning.eq(0), # stop counter, need to fire "monitor"
596 dmi_monitor.eq(1), # start "monitor" instead
597 )
598 )
599
600 # limit range of pc for debug reporting
601 #self.comb += active_dbg.eq((0x378c <= pc) & (pc <= 0x38d8))
602 #self.comb += active_dbg.eq((0x0 < pc) & (pc < 0x58))
603 self.comb += active_dbg.eq(1)
604
605
606 # get the MSR
607 self.sync += If(active_dbg & (dmicount == 12),
608 (dmi_addr.eq(0b11), # MSR
609 dmi_req.eq(1),
610 dmi_wen.eq(0),
611 )
612 )
613
614 if cpu == "libresoc":
615 #self.comb += active_dbg_cr.eq((0x10300 <= pc) & (pc <= 0x12600))
616 self.comb += active_dbg_cr.eq(0)
617
618 # get the CR
619 self.sync += If(active_dbg_cr & (dmicount == 16),
620 (dmi_addr.eq(0b1000), # CR
621 dmi_req.eq(1),
622 dmi_wen.eq(0),
623 )
624 )
625
626 #self.comb += active_dbg_xer.eq((0x10300 <= pc) & (pc <= 0x1094c))
627 self.comb += active_dbg_xer.eq(active_dbg_cr)
628
629 # get the CR
630 self.sync += If(active_dbg_xer & (dmicount == 20),
631 (dmi_addr.eq(0b1001), # XER
632 dmi_req.eq(1),
633 dmi_wen.eq(0),
634 )
635 )
636
637 # read all 32 GPRs
638 for i in range(32):
639 self.sync += If(active_dbg & (dmicount == 24+(i*8)),
640 (dmi_addr.eq(0b100), # GSPR addr
641 dmi_din.eq(i), # r1
642 dmi_req.eq(1),
643 dmi_wen.eq(1),
644 )
645 )
646
647 self.sync += If(active_dbg & (dmicount == 28+(i*8)),
648 (dmi_addr.eq(0b101), # GSPR data
649 dmi_req.eq(1),
650 dmi_wen.eq(0),
651 )
652 )
653
654 # monitor bbus read/write
655 self.sync += If(active_dbg & self.cpu.dbus.stb & self.cpu.dbus.ack,
656 Display(" [%06x] dadr: %8x, we %d s %01x w %016x r: %016x",
657 #uptime,
658 0,
659 self.cpu.dbus.adr,
660 self.cpu.dbus.we,
661 self.cpu.dbus.sel,
662 self.cpu.dbus.dat_w,
663 self.cpu.dbus.dat_r
664 )
665 )
666
667 return
668
669 # monitor ibus write
670 self.sync += If(active_dbg & self.cpu.ibus.stb & self.cpu.ibus.ack &
671 self.cpu.ibus.we,
672 Display(" [%06x] iadr: %8x, s %01x w %016x",
673 #uptime,
674 0,
675 self.cpu.ibus.adr,
676 self.cpu.ibus.sel,
677 self.cpu.ibus.dat_w,
678 )
679 )
680 # monitor ibus read
681 self.sync += If(active_dbg & self.cpu.ibus.stb & self.cpu.ibus.ack &
682 ~self.cpu.ibus.we,
683 Display(" [%06x] iadr: %8x, s %01x r %016x",
684 #uptime,
685 0,
686 self.cpu.ibus.adr,
687 self.cpu.ibus.sel,
688 self.cpu.ibus.dat_r
689 )
690 )
691
692 # Build -----------------------------------------------------------------------
693
694 def main():
695 parser = argparse.ArgumentParser(description="LiteX LibreSoC CPU Sim")
696 parser.add_argument("--cpu", default="libresoc",
697 help="CPU to use: libresoc (default) or microwatt")
698 parser.add_argument("--platform", default="sim",
699 help="platform (sim or ls180)")
700 parser.add_argument("--debug", action="store_true",
701 help="Enable debug traces")
702 parser.add_argument("--trace", action="store_true",
703 help="Enable tracing")
704 parser.add_argument("--trace-start", default=0,
705 help="Cycle to start FST tracing")
706 parser.add_argument("--trace-end", default=-1,
707 help="Cycle to end FST tracing")
708 parser.add_argument("--build", action="store_true", help="Build bitstream")
709 args = parser.parse_args()
710
711
712 if args.platform == 'ls180':
713 soc = LibreSoCSim(cpu=args.cpu, debug=args.debug,
714 platform=args.platform)
715 soc.add_spi_sdcard()
716 builder = Builder(soc, compile_gateware = True)
717 builder.build(run = True)
718 os.chdir("../")
719 else:
720
721 sim_config = SimConfig(default_clk="sys_clk")
722 sim_config.add_module("serial2console", "serial")
723
724 for i in range(2):
725 soc = LibreSoCSim(cpu=args.cpu, debug=args.debug,
726 platform=args.platform)
727 builder = Builder(soc, compile_gateware = i!=0)
728 builder.build(sim_config=sim_config,
729 run = i!=0,
730 trace = args.trace,
731 trace_start = int(args.trace_start),
732 trace_end = int(args.trace_end),
733 trace_fst = 0)
734 os.chdir("../")
735
736 if __name__ == "__main__":
737 main()