change litex sdram pinouts to ASIC type
[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 self.specials += [SDROutput(i=dfi.p0.address[i], o=pads.a[i])
205 for i in range(len(pads.a))]
206 self.specials += [SDROutput(i=dfi.p0.bank[i], o=pads.ba[i])
207 for i in range(len(pads.ba))]
208 self.specials += SDROutput(i=dfi.p0.cas_n, o=pads.cas_n)
209 self.specials += SDROutput(i=dfi.p0.ras_n, o=pads.ras_n)
210 self.specials += SDROutput(i=dfi.p0.we_n, o=pads.we_n)
211 if hasattr(pads, "cke"):
212 self.specials += SDROutput(i=dfi.p0.cke, o=pads.cke)
213 if hasattr(pads, "cs_n"):
214 self.specials += SDROutput(i=dfi.p0.cs_n, o=pads.cs_n)
215
216 # DQ/DM Data Path -------------------------------------------------
217
218 d = dfi.p0
219 self.submodules.dq = SDRPad(pads, "dq", d.wrdata, d.wrdata_en, d.rddata)
220
221 if hasattr(pads, "dm"):
222 for i in range(len(pads.dm)):
223 self.comb += pads.dm[i].eq(0) # FIXME
224
225 # DQ/DM Control Path ----------------------------------------------
226 rddata_en = Signal(cl + cmd_latency)
227 self.sync += rddata_en.eq(Cat(dfi.p0.rddata_en, rddata_en))
228 self.sync += dfi.p0.rddata_valid.eq(rddata_en[-1])
229
230
231 # LibreSoC 180nm ASIC -------------------------------------------------------
232
233 class LibreSoCSim(SoCCore):
234 def __init__(self, cpu="libresoc", debug=False, with_sdram=True,
235 sdram_module = "AS4C16M16",
236 #sdram_data_width = 16,
237 #sdram_module = "MT48LC16M16",
238 sdram_data_width = 16,
239 irq_reserved_irqs = {'uart': 0},
240 platform='sim',
241 ):
242 assert cpu in ["libresoc", "microwatt"]
243 sys_clk_freq = int(50e6)
244
245 if platform == 'sim':
246 platform = Platform()
247 uart_name = "sim"
248 elif platform == 'ls180':
249 platform = LS180Platform()
250 uart_name = "serial"
251
252 #cpu_data_width = 32
253 cpu_data_width = 64
254
255 variant = "ls180"
256
257 # reserve XICS ICP and XICS memory addresses.
258 self.mem_map['icp'] = 0xc0010000
259 self.mem_map['ics'] = 0xc0011000
260 #self.csr_map["icp"] = 8 # 8 x 0x800 == 0x4000
261 #self.csr_map["ics"] = 10 # 10 x 0x800 == 0x5000
262
263 ram_init = []
264 if False:
265 #ram_init = get_mem_data({
266 # ram_fname: "0x00000000",
267 # }, "little")
268 ram_init = get_mem_data(ram_fname, "little")
269
270 # remap the main RAM to reset-start-address
271
272 # without sram nothing works, therefore move it to higher up
273 self.mem_map["sram"] = 0x90000000
274
275 # put UART at 0xc000200 (w00t! this works!)
276 self.csr_map["uart"] = 4
277
278 self.mem_map["main_ram"] = 0x90000000
279 self.mem_map["sram"] = 0x00000000
280
281 # SoCCore -------------------------------------------------------------
282 SoCCore.__init__(self, platform, clk_freq=sys_clk_freq,
283 cpu_type = "microwatt",
284 cpu_cls = LibreSoC if cpu == "libresoc" \
285 else Microwatt,
286 #bus_data_width = 64,
287 csr_address_width = 14, # limit to 0x8000
288 cpu_variant = variant,
289 csr_data_width = 8,
290 l2_size = 0,
291 uart_name = uart_name,
292 with_sdram = with_sdram,
293 sdram_module = sdram_module,
294 sdram_data_width = sdram_data_width,
295 integrated_rom_size = 0, # if ram_fname else 0x10000,
296 integrated_sram_size = 0x200,
297 #integrated_main_ram_init = ram_init,
298 integrated_main_ram_size = 0x00000000 if with_sdram \
299 else 0x10000000 , # 256MB
300 )
301 self.platform.name = "ls180"
302
303 # SDR SDRAM ----------------------------------------------
304 if False: # not self.integrated_main_ram_size:
305 self.submodules.sdrphy = sdrphy_cls(platform.request("sdram"))
306
307 if cpu == "libresoc":
308 # XICS interrupt devices
309 icp_addr = self.mem_map['icp']
310 icp_wb = self.cpu.xics_icp
311 icp_region = SoCRegion(origin=icp_addr, size=0x20, cached=False)
312 self.bus.add_slave(name='icp', slave=icp_wb, region=icp_region)
313
314 ics_addr = self.mem_map['ics']
315 ics_wb = self.cpu.xics_ics
316 ics_region = SoCRegion(origin=ics_addr, size=0x1000, cached=False)
317 self.bus.add_slave(name='ics', slave=ics_wb, region=ics_region)
318
319 # CRG -----------------------------------------------------------------
320 self.submodules.crg = CRG(platform.request("sys_clk"),
321 platform.request("sys_rst"))
322
323 #ram_init = []
324
325 # SDRAM ----------------------------------------------------
326 if with_sdram:
327 sdram_clk_freq = int(100e6) # FIXME: use 100MHz timings
328 sdram_module_cls = getattr(litedram_modules, sdram_module)
329 sdram_rate = "1:{}".format(
330 sdram_module_nphases[sdram_module_cls.memtype])
331 sdram_module = sdram_module_cls(sdram_clk_freq, sdram_rate)
332 phy_settings = get_sdram_phy_settings(
333 memtype = sdram_module.memtype,
334 data_width = sdram_data_width,
335 clk_freq = sdram_clk_freq)
336 #sdrphy_cls = HalfRateGENSDRPHY
337 sdrphy_cls = GENSDRPHY
338 self.submodules.sdrphy = sdrphy_cls(platform.request("sdram"))
339 #self.submodules.sdrphy = sdrphy_cls(sdram_module,
340 # phy_settings,
341 # init=ram_init
342 # )
343 self.add_sdram("sdram",
344 phy = self.sdrphy,
345 module = sdram_module,
346 origin = self.mem_map["main_ram"],
347 size = 0x80000000,
348 l2_cache_size = 0, # 8192
349 l2_cache_min_data_width = 128,
350 l2_cache_reverse = True
351 )
352 # FIXME: skip memtest to avoid corrupting memory
353 self.add_constant("MEMTEST_BUS_SIZE", 128//16)
354 self.add_constant("MEMTEST_DATA_SIZE", 128//16)
355 self.add_constant("MEMTEST_ADDR_SIZE", 128//16)
356 self.add_constant("MEMTEST_BUS_DEBUG", 1)
357 self.add_constant("MEMTEST_ADDR_DEBUG", 1)
358 self.add_constant("MEMTEST_DATA_DEBUG", 1)
359
360 # GPIOs (bi-directional)
361 self.submodules.gpio = GPIOTristateASIC(platform.request("gpio"))
362 self.add_csr("gpio")
363
364 # SPI Master
365 self.submodules.spi_master = SPIMaster(
366 pads = platform.request("spi_master"),
367 data_width = 8,
368 sys_clk_freq = sys_clk_freq,
369 spi_clk_freq = 8e6,
370 )
371 self.add_csr("spi_master")
372
373 # EINTs - very simple, wire up top 3 bits to ls180 "eint" pins
374 self.comb += self.cpu.interrupt[12:16].eq(platform.request("eint"))
375
376 # JTAG
377 jtagpads = platform.request("jtag")
378 self.comb += self.cpu.jtag_tck.eq(jtagpads.tck)
379 self.comb += self.cpu.jtag_tms.eq(jtagpads.tms)
380 self.comb += self.cpu.jtag_tdi.eq(jtagpads.tdi)
381 self.comb += jtagpads.tdo.eq(self.cpu.jtag_tdo)
382
383 # PWM
384 for i in range(2):
385 name = "pwm%d" % i
386 setattr(self.submodules, name, PWM(platform.request("pwm", i)))
387 self.add_csr(name)
388
389 # I2C Master
390 self.submodules.i2c = I2CMaster(platform.request("i2c"))
391 self.add_csr("i2c")
392
393 # SDCard -----------------------------------------------------
394
395 # Emulator / Pads
396 sdcard_pads = self.platform.request("sdcard")
397
398 # Core
399 self.submodules.sdphy = SDPHY(sdcard_pads,
400 self.platform.device, self.clk_freq)
401 self.submodules.sdcore = SDCore(self.sdphy)
402 self.add_csr("sdphy")
403 self.add_csr("sdcore")
404
405 # Block2Mem DMA
406 bus = wishbone.Interface(data_width=self.bus.data_width,
407 adr_width=self.bus.address_width)
408 self.submodules.sdblock2mem = SDBlock2MemDMA(bus=bus,
409 endianness=self.cpu.endianness)
410 self.comb += self.sdcore.source.connect(self.sdblock2mem.sink)
411 dma_bus = self.bus if not hasattr(self, "dma_bus") else self.dma_bus
412 dma_bus.add_master("sdblock2mem", master=bus)
413 self.add_csr("sdblock2mem")
414
415 # Mem2Block DMA
416 bus = wishbone.Interface(data_width=self.bus.data_width,
417 adr_width=self.bus.address_width)
418 self.submodules.sdmem2block = SDMem2BlockDMA(bus=bus,
419 endianness=self.cpu.endianness)
420 self.comb += self.sdmem2block.source.connect(self.sdcore.sink)
421 dma_bus = self.bus if not hasattr(self, "dma_bus") else self.dma_bus
422 dma_bus.add_master("sdmem2block", master=bus)
423 self.add_csr("sdmem2block")
424
425 # Debug ---------------------------------------------------------------
426 if not debug:
427 return
428
429 # setup running of DMI FSM
430 dmi_addr = Signal(4)
431 dmi_din = Signal(64)
432 dmi_dout = Signal(64)
433 dmi_wen = Signal(1)
434 dmi_req = Signal(1)
435
436 # debug log out
437 dbg_addr = Signal(4)
438 dbg_dout = Signal(64)
439 dbg_msg = Signal(1)
440
441 # capture pc from dmi
442 pc = Signal(64)
443 active_dbg = Signal()
444 active_dbg_cr = Signal()
445 active_dbg_xer = Signal()
446
447 # xer flags
448 xer_so = Signal()
449 xer_ca = Signal()
450 xer_ca32 = Signal()
451 xer_ov = Signal()
452 xer_ov32 = Signal()
453
454 # increment counter, Stop after 100000 cycles
455 uptime = Signal(64)
456 self.sync += uptime.eq(uptime + 1)
457 #self.sync += If(uptime == 1000000000000, Finish())
458
459 # DMI FSM counter and FSM itself
460 dmicount = Signal(10)
461 dmirunning = Signal(1)
462 dmi_monitor = Signal(1)
463 dmifsm = FSM()
464 self.submodules += dmifsm
465
466 # DMI FSM
467 dmifsm.act("START",
468 If(dmi_req & dmi_wen,
469 (self.cpu.dmi_addr.eq(dmi_addr), # DMI Addr
470 self.cpu.dmi_din.eq(dmi_din), # DMI in
471 self.cpu.dmi_req.eq(1), # DMI request
472 self.cpu.dmi_wr.eq(1), # DMI write
473 If(self.cpu.dmi_ack,
474 (NextState("IDLE"),
475 )
476 ),
477 ),
478 ),
479 If(dmi_req & ~dmi_wen,
480 (self.cpu.dmi_addr.eq(dmi_addr), # DMI Addr
481 self.cpu.dmi_req.eq(1), # DMI request
482 self.cpu.dmi_wr.eq(0), # DMI read
483 If(self.cpu.dmi_ack,
484 # acknowledge received: capture data.
485 (NextState("IDLE"),
486 NextValue(dbg_addr, dmi_addr),
487 NextValue(dbg_dout, self.cpu.dmi_dout),
488 NextValue(dbg_msg, 1),
489 ),
490 ),
491 ),
492 )
493 )
494
495 # DMI response received: reset the dmi request and check if
496 # in "monitor" mode
497 dmifsm.act("IDLE",
498 If(dmi_monitor,
499 NextState("FIRE_MONITOR"), # fire "monitor" on next cycle
500 ).Else(
501 NextState("START"), # back to start on next cycle
502 ),
503 NextValue(dmi_req, 0),
504 NextValue(dmi_addr, 0),
505 NextValue(dmi_din, 0),
506 NextValue(dmi_wen, 0),
507 )
508
509 # "monitor" mode fires off a STAT request
510 dmifsm.act("FIRE_MONITOR",
511 (NextValue(dmi_req, 1),
512 NextValue(dmi_addr, 1), # DMI STAT address
513 NextValue(dmi_din, 0),
514 NextValue(dmi_wen, 0), # read STAT
515 NextState("START"), # back to start on next cycle
516 )
517 )
518
519 self.comb += xer_so.eq((dbg_dout & 1) == 1)
520 self.comb += xer_ca.eq((dbg_dout & 4) == 4)
521 self.comb += xer_ca32.eq((dbg_dout & 8) == 8)
522 self.comb += xer_ov.eq((dbg_dout & 16) == 16)
523 self.comb += xer_ov32.eq((dbg_dout & 32) == 32)
524
525 # debug messages out
526 self.sync += If(dbg_msg,
527 (If(active_dbg & (dbg_addr == 0b10), # PC
528 Display("pc : %016x", dbg_dout),
529 ),
530 If(dbg_addr == 0b10, # PC
531 pc.eq(dbg_dout), # capture PC
532 ),
533 #If(dbg_addr == 0b11, # MSR
534 # Display(" msr: %016x", dbg_dout),
535 #),
536 If(dbg_addr == 0b1000, # CR
537 Display(" cr : %016x", dbg_dout),
538 ),
539 If(dbg_addr == 0b1001, # XER
540 Display(" xer: so %d ca %d 32 %d ov %d 32 %d",
541 xer_so, xer_ca, xer_ca32, xer_ov, xer_ov32),
542 ),
543 If(dbg_addr == 0b101, # GPR
544 Display(" gpr: %016x", dbg_dout),
545 ),
546 # also check if this is a "stat"
547 If(dbg_addr == 1, # requested a STAT
548 #Display(" stat: %x", dbg_dout),
549 If(dbg_dout & 2, # bit 2 of STAT is "stopped" mode
550 dmirunning.eq(1), # continue running
551 dmi_monitor.eq(0), # and stop monitor mode
552 ),
553 ),
554 dbg_msg.eq(0)
555 )
556 )
557
558 # kick off a "stop"
559 self.sync += If(uptime == 0,
560 (dmi_addr.eq(0), # CTRL
561 dmi_din.eq(1<<0), # STOP
562 dmi_req.eq(1),
563 dmi_wen.eq(1),
564 )
565 )
566
567 self.sync += If(uptime == 4,
568 dmirunning.eq(1),
569 )
570
571 self.sync += If(dmirunning,
572 dmicount.eq(dmicount + 1),
573 )
574
575 # loop every 1<<N cycles
576 cyclewid = 9
577
578 # get the PC
579 self.sync += If(dmicount == 4,
580 (dmi_addr.eq(0b10), # NIA
581 dmi_req.eq(1),
582 dmi_wen.eq(0),
583 )
584 )
585
586 # kick off a "step"
587 self.sync += If(dmicount == 8,
588 (dmi_addr.eq(0), # CTRL
589 dmi_din.eq(1<<3), # STEP
590 dmi_req.eq(1),
591 dmi_wen.eq(1),
592 dmirunning.eq(0), # stop counter, need to fire "monitor"
593 dmi_monitor.eq(1), # start "monitor" instead
594 )
595 )
596
597 # limit range of pc for debug reporting
598 #self.comb += active_dbg.eq((0x378c <= pc) & (pc <= 0x38d8))
599 #self.comb += active_dbg.eq((0x0 < pc) & (pc < 0x58))
600 self.comb += active_dbg.eq(1)
601
602
603 # get the MSR
604 self.sync += If(active_dbg & (dmicount == 12),
605 (dmi_addr.eq(0b11), # MSR
606 dmi_req.eq(1),
607 dmi_wen.eq(0),
608 )
609 )
610
611 if cpu == "libresoc":
612 #self.comb += active_dbg_cr.eq((0x10300 <= pc) & (pc <= 0x12600))
613 self.comb += active_dbg_cr.eq(0)
614
615 # get the CR
616 self.sync += If(active_dbg_cr & (dmicount == 16),
617 (dmi_addr.eq(0b1000), # CR
618 dmi_req.eq(1),
619 dmi_wen.eq(0),
620 )
621 )
622
623 #self.comb += active_dbg_xer.eq((0x10300 <= pc) & (pc <= 0x1094c))
624 self.comb += active_dbg_xer.eq(active_dbg_cr)
625
626 # get the CR
627 self.sync += If(active_dbg_xer & (dmicount == 20),
628 (dmi_addr.eq(0b1001), # XER
629 dmi_req.eq(1),
630 dmi_wen.eq(0),
631 )
632 )
633
634 # read all 32 GPRs
635 for i in range(32):
636 self.sync += If(active_dbg & (dmicount == 24+(i*8)),
637 (dmi_addr.eq(0b100), # GSPR addr
638 dmi_din.eq(i), # r1
639 dmi_req.eq(1),
640 dmi_wen.eq(1),
641 )
642 )
643
644 self.sync += If(active_dbg & (dmicount == 28+(i*8)),
645 (dmi_addr.eq(0b101), # GSPR data
646 dmi_req.eq(1),
647 dmi_wen.eq(0),
648 )
649 )
650
651 # monitor bbus read/write
652 self.sync += If(active_dbg & self.cpu.dbus.stb & self.cpu.dbus.ack,
653 Display(" [%06x] dadr: %8x, we %d s %01x w %016x r: %016x",
654 #uptime,
655 0,
656 self.cpu.dbus.adr,
657 self.cpu.dbus.we,
658 self.cpu.dbus.sel,
659 self.cpu.dbus.dat_w,
660 self.cpu.dbus.dat_r
661 )
662 )
663
664 return
665
666 # monitor ibus write
667 self.sync += If(active_dbg & self.cpu.ibus.stb & self.cpu.ibus.ack &
668 self.cpu.ibus.we,
669 Display(" [%06x] iadr: %8x, s %01x w %016x",
670 #uptime,
671 0,
672 self.cpu.ibus.adr,
673 self.cpu.ibus.sel,
674 self.cpu.ibus.dat_w,
675 )
676 )
677 # monitor ibus read
678 self.sync += If(active_dbg & self.cpu.ibus.stb & self.cpu.ibus.ack &
679 ~self.cpu.ibus.we,
680 Display(" [%06x] iadr: %8x, s %01x r %016x",
681 #uptime,
682 0,
683 self.cpu.ibus.adr,
684 self.cpu.ibus.sel,
685 self.cpu.ibus.dat_r
686 )
687 )
688
689 # Build -----------------------------------------------------------------------
690
691 def main():
692 parser = argparse.ArgumentParser(description="LiteX LibreSoC CPU Sim")
693 parser.add_argument("--cpu", default="libresoc",
694 help="CPU to use: libresoc (default) or microwatt")
695 parser.add_argument("--platform", default="sim",
696 help="platform (sim or ls180)")
697 parser.add_argument("--debug", action="store_true",
698 help="Enable debug traces")
699 parser.add_argument("--trace", action="store_true",
700 help="Enable tracing")
701 parser.add_argument("--trace-start", default=0,
702 help="Cycle to start FST tracing")
703 parser.add_argument("--trace-end", default=-1,
704 help="Cycle to end FST tracing")
705 parser.add_argument("--build", action="store_true", help="Build bitstream")
706 args = parser.parse_args()
707
708
709 if args.platform == 'ls180':
710 soc = LibreSoCSim(cpu=args.cpu, debug=args.debug,
711 platform=args.platform)
712 soc.add_spi_sdcard()
713 builder = Builder(soc, compile_gateware = True)
714 builder.build(run = True)
715 os.chdir("../")
716 else:
717
718 sim_config = SimConfig(default_clk="sys_clk")
719 sim_config.add_module("serial2console", "serial")
720
721 for i in range(2):
722 soc = LibreSoCSim(cpu=args.cpu, debug=args.debug,
723 platform=args.platform)
724 builder = Builder(soc, compile_gateware = i!=0)
725 builder.build(sim_config=sim_config,
726 run = i!=0,
727 trace = args.trace,
728 trace_start = int(args.trace_start),
729 trace_end = int(args.trace_end),
730 trace_fst = 0)
731 os.chdir("../")
732
733 if __name__ == "__main__":
734 main()