debugging ls180 litex hell
[libresoc-litex.git] / 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, ResetInserter)
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 from litex.soc.cores import uart
31
32 from litex.tools.litex_sim import sdram_module_nphases, get_sdram_phy_settings
33
34 from litex.tools.litex_sim import Platform
35 from libresoc.ls180 import LS180Platform
36
37 from migen import Module
38 from litex.soc.interconnect.csr import AutoCSR
39
40 from libresoc import LibreSoC
41 from microwatt import Microwatt
42
43 # HACK!
44 from litex.soc.integration.soc import SoCCSRHandler
45 SoCCSRHandler.supported_address_width.append(12)
46
47 # GPIO Tristate -------------------------------------------------------
48 # doesn't work properly.
49 #from litex.soc.cores.gpio import GPIOTristate
50 from litex.soc.interconnect.csr import CSRStorage, CSRStatus, CSRField
51 from migen.genlib.cdc import MultiReg
52
53 # Imports
54 from litex.soc.interconnect import wishbone
55 from litesdcard.phy import (SDPHY, SDPHYClocker,
56 SDPHYInit, SDPHYCMDW, SDPHYCMDR,
57 SDPHYDATAW, SDPHYDATAR,
58 _sdpads_layout)
59 from litesdcard.core import SDCore
60 from litesdcard.frontend.dma import SDBlock2MemDMA, SDMem2BlockDMA
61 from litex.build.io import SDROutput, SDRInput
62
63
64 # I2C Master Bit-Banging --------------------------------------------------
65
66 class I2CMaster(Module, AutoCSR):
67 """I2C Master Bit-Banging
68
69 Provides the minimal hardware to do software I2C Master bit banging.
70
71 On the same write CSRStorage (_w), software can control SCL (I2C_SCL),
72 SDA direction and value (I2C_OE, I2C_W). Software get back SDA value
73 with the read CSRStatus (_r).
74 """
75 pads_layout = [("scl", 1), ("sda", 1)]
76 def __init__(self, pads):
77 self.pads = pads
78 self._w = CSRStorage(fields=[
79 CSRField("scl", size=1, offset=0),
80 CSRField("oe", size=1, offset=1),
81 CSRField("sda", size=1, offset=2)],
82 name="w")
83 self._r = CSRStatus(fields=[
84 CSRField("sda", size=1, offset=0)],
85 name="r")
86
87 self.connect(pads)
88
89 def connect(self, pads):
90 _sda_w = Signal()
91 _sda_oe = Signal()
92 _sda_r = Signal()
93 self.comb += [
94 pads.scl.eq(self._w.fields.scl),
95 pads.sda_oe.eq( self._w.fields.oe),
96 pads.sda_o.eq( self._w.fields.sda),
97 self._r.fields.sda.eq(pads.sda_i),
98 ]
99
100
101 class GPIOTristateASIC(Module, AutoCSR):
102 def __init__(self, name, pads, prange=None):
103 if prange is None:
104 prange = range(nbits)
105 nbits = len(prange)
106
107 self._oe = CSRStorage(nbits, description="GPIO Tristate(s) Control.")
108 self._in = CSRStatus(nbits, description="GPIO Input(s) Status.")
109 self._out = CSRStorage(nbits, description="GPIO Ouptut(s) Control.")
110
111 # # #
112
113 _pads = Record( ((name+"i", nbits),
114 (name+"o", nbits),
115 (name+"oe", nbits)))
116 _o = getattr(_pads, name+"o")
117 _oe = getattr(_pads, name+"oe")
118 _i = getattr(_pads, name+"i")
119 for j, i in enumerate(prange):
120 self.comb += _i[j].eq(pads.i[i])
121 self.comb += pads.o[i].eq(_o[j])
122 self.comb += pads.oe[i].eq(_oe[j])
123
124 clk = ClockSignal()
125 o = self._out.storage
126 oe = self._oe.storage
127 i = self._in.status
128 for j in range(nbits):
129 self.specials += SDROutput(clk=clk, i=oe[j], o=_oe[j])
130 self.specials += SDROutput(clk=clk, i=o[j], o=_o[j])
131 self.specials += SDRInput(clk=clk, i=_i[j], o=i[j])
132 #for i in range(nbits):
133 #self.comb += _pads.oe[i].eq(self._oe.storage[i])
134 #self.comb += _pads.o[i].eq(self._out.storage[i])
135 #self.specials += MultiReg(_pads.i[i], self._in.status[i])
136
137 # SDCard PHY IO -------------------------------------------------------
138
139 class SDRPad(Module):
140 def __init__(self, pad, name, o, oe, i):
141 clk = ClockSignal()
142 _o = getattr(pad, "%s_o" % name)
143 _oe = getattr(pad, "%s_oe" % name)
144 _i = getattr(pad, "%s_i" % name)
145 self.specials += SDROutput(clk=clk, i=oe, o=_oe)
146 for j in range(len(_o)):
147 self.specials += SDROutput(clk=clk, i=o[j], o=_o[j])
148 self.specials += SDRInput(clk=clk, i=_i[j], o=i[j])
149
150
151 class SDPHYIOGen(Module):
152 def __init__(self, clocker, sdpads, pads):
153 # Rst
154 if hasattr(pads, "rst"):
155 self.comb += pads.rst.eq(0)
156
157 # Clk
158 self.specials += SDROutput(
159 clk = ClockSignal(),
160 i = ~clocker.clk & sdpads.clk,
161 o = pads.clk
162 )
163
164 # Cmd
165 c = sdpads.cmd
166 self.submodules.sd_cmd = SDRPad(pads, "cmd", c.o, c.oe, c.i)
167
168 # Data
169 d = sdpads.data
170 self.submodules.sd_data = SDRPad(pads, "data", d.o, d.oe, d.i)
171
172
173 class SDPHY(Module, AutoCSR):
174 def __init__(self, pads, device, sys_clk_freq,
175 cmd_timeout=10e-3, data_timeout=10e-3):
176 self.card_detect = CSRStatus() # Assume SDCard is present if no cd pin.
177 self.comb += self.card_detect.status.eq(getattr(pads, "cd", 0))
178
179 self.submodules.clocker = clocker = SDPHYClocker()
180 self.submodules.init = init = SDPHYInit()
181 self.submodules.cmdw = cmdw = SDPHYCMDW()
182 self.submodules.cmdr = cmdr = SDPHYCMDR(sys_clk_freq,
183 cmd_timeout, cmdw)
184 self.submodules.dataw = dataw = SDPHYDATAW()
185 self.submodules.datar = datar = SDPHYDATAR(sys_clk_freq,
186 data_timeout)
187
188 # # #
189
190 self.sdpads = sdpads = Record(_sdpads_layout)
191
192 # IOs
193 sdphy_cls = SDPHYIOGen
194 self.submodules.io = sdphy_cls(clocker, sdpads, pads)
195
196 # Connect pads_out of submodules to physical pads --------------
197 pl = [init, cmdw, cmdr, dataw, datar]
198 self.comb += [
199 sdpads.clk.eq( reduce(or_, [m.pads_out.clk for m in pl])),
200 sdpads.cmd.oe.eq( reduce(or_, [m.pads_out.cmd.oe for m in pl])),
201 sdpads.cmd.o.eq( reduce(or_, [m.pads_out.cmd.o for m in pl])),
202 sdpads.data.oe.eq(reduce(or_, [m.pads_out.data.oe for m in pl])),
203 sdpads.data.o.eq( reduce(or_, [m.pads_out.data.o for m in pl])),
204 ]
205 for m in pl:
206 self.comb += m.pads_out.ready.eq(self.clocker.ce)
207
208 # Connect physical pads to pads_in of submodules ---------------
209 for m in pl:
210 self.comb += m.pads_in.valid.eq(self.clocker.ce)
211 self.comb += m.pads_in.cmd.i.eq(sdpads.cmd.i)
212 self.comb += m.pads_in.data.i.eq(sdpads.data.i)
213
214 # Speed Throttling -------------------------------------------
215 self.comb += clocker.stop.eq(dataw.stop | datar.stop)
216
217
218 # Generic SDR PHY ---------------------------------------------------------
219
220 class GENSDRPHY(Module):
221 def __init__(self, pads, cl=2, cmd_latency=1):
222 pads = PHYPadsCombiner(pads)
223 addressbits = len(pads.a)
224 bankbits = len(pads.ba)
225 nranks = 1 if not hasattr(pads, "cs_n") else len(pads.cs_n)
226 databits = len(pads.dq_i)
227 assert cl in [2, 3]
228 assert databits%8 == 0
229
230 # PHY settings ----------------------------------------------------
231 self.settings = PhySettings(
232 phytype = "GENSDRPHY",
233 memtype = "SDR",
234 databits = databits,
235 dfi_databits = databits,
236 nranks = nranks,
237 nphases = 1,
238 rdphase = 0,
239 wrphase = 0,
240 rdcmdphase = 0,
241 wrcmdphase = 0,
242 cl = cl,
243 read_latency = cl + cmd_latency,
244 write_latency = 0
245 )
246
247 # DFI Interface ---------------------------------------------------
248 self.dfi = dfi = DFIInterface(addressbits, bankbits, nranks, databits)
249
250 # # #
251
252 # Iterate on pads groups ------------------------------------------
253 for pads_group in range(len(pads.groups)):
254 pads.sel_group(pads_group)
255
256 # Addresses and Commands --------------------------------------
257 p0 = dfi.p0
258 self.specials += [SDROutput(i=p0.address[i], o=pads.a[i])
259 for i in range(len(pads.a))]
260 self.specials += [SDROutput(i=p0.bank[i], o=pads.ba[i])
261 for i in range(len(pads.ba))]
262 self.specials += SDROutput(i=p0.cas_n, o=pads.cas_n)
263 self.specials += SDROutput(i=p0.ras_n, o=pads.ras_n)
264 self.specials += SDROutput(i=p0.we_n, o=pads.we_n)
265 if hasattr(pads, "cke"):
266 for i in range(len(pads.cke)):
267 self.specials += SDROutput(i=p0.cke[i], o=pads.cke[i])
268 if hasattr(pads, "cs_n"):
269 for i in range(len(pads.cs_n)):
270 self.specials += SDROutput(i=p0.cs_n[i], o=pads.cs_n[i])
271
272 # DQ/DM Data Path -------------------------------------------------
273
274 d = dfi.p0
275 wren = []
276 self.submodules.dq = SDRPad(pads, "dq", d.wrdata, d.wrdata_en, d.rddata)
277
278 if hasattr(pads, "dm"):
279 print ("sdr pads dm len", pads.dm, len(pads.dm))
280 for i in range(len(pads.dm)):
281 self.specials += SDROutput(i=d.wrdata_en&d.wrdata_mask[i],
282 o=pads.dm[i])
283
284 # DQ/DM Control Path ----------------------------------------------
285 rddata_en = Signal(cl + cmd_latency)
286 self.sync += rddata_en.eq(Cat(dfi.p0.rddata_en, rddata_en))
287 self.sync += dfi.p0.rddata_valid.eq(rddata_en[-1])
288
289
290 # LibreSoC 180nm ASIC -------------------------------------------------------
291
292 class LibreSoCSim(SoCCore):
293 def __init__(self, cpu="libresoc", debug=False, with_sdram=True,
294 sdram_module = "AS4C16M16",
295 #sdram_data_width = 16,
296 #sdram_module = "MT48LC16M16",
297 sdram_data_width = 16,
298 irq_reserved_irqs = {'uart': 0},
299 platform='sim',
300 dff_srams=5,
301 srams_4k=4,
302 ):
303 assert cpu in ["libresoc", "microwatt"]
304 sys_clk_freq = int(50e6)
305
306 platform_name = platform
307 if platform == 'sim':
308 platform = Platform()
309 self.platform.name = 'ls180'
310 uart_name = "sim"
311 elif 'ls180' in platform:
312 platform = LS180Platform()
313 uart_name = "uart"
314
315 #cpu_data_width = 32
316 cpu_data_width = 64
317
318 variant = "ls180"
319
320 # reserve XICS ICP and XICS memory addresses.
321 self.mem_map['icp'] = 0xc0010000
322 self.mem_map['ics'] = 0xc0011000
323 #self.csr_map["icp"] = 8 # 8 x 0x800 == 0x4000
324 #self.csr_map["ics"] = 10 # 10 x 0x800 == 0x5000
325
326 ram_init = []
327 if False:
328 #ram_init = get_mem_data({
329 # ram_fname: "0x00000000",
330 # }, "little")
331 ram_init = get_mem_data(ram_fname, "little")
332
333 # remap the main RAM to reset-start-address
334
335 # without sram nothing works, therefore move it to higher up
336 self.mem_map["sram"] = 0x90000000
337
338 # put UART at 0xc000200 (w00t! this works!)
339 self.csr_map["uart"] = 4
340
341 self.mem_map["main_ram"] = 0x90000000
342 if dff_srams == 5:
343 self.mem_map["sram"] = 0x00000000
344 self.mem_map["sram1"] = 0x00000200
345 self.mem_map["sram2"] = 0x00000400
346 self.mem_map["sram3"] = 0x00000600
347 self.mem_map["sram4"] = 0x00000800
348 sram_size = 0x200
349 else:
350 sram_size = 0x80 # ridiculously small
351 if "sram4k" not in variant:
352 sram_size = 0x200 # no 4k SRAMs, make slightly bigger
353 self.mem_map["sram"] = 0x00000000
354 self.mem_map["sram1"] = 0x00000700
355 self.mem_map["sram4k_0"] = 0x00001000
356 self.mem_map["sram4k_1"] = 0x00002000
357 self.mem_map["sram4k_2"] = 0x00003000
358 self.mem_map["sram4k_3"] = 0x00004000
359
360 # SoCCore -------------------------------------------------------------
361 SoCCore.__init__(self, platform, clk_freq=sys_clk_freq,
362 cpu_type = "microwatt",
363 cpu_cls = LibreSoC if cpu == "libresoc" \
364 else Microwatt,
365 bus_data_width = 64,
366 csr_address_width = 14, # limit to 0x8000
367 cpu_variant = variant,
368 csr_data_width = 8,
369 l2_size = 0,
370 with_uart = False,
371 uart_name = None,
372 with_sdram = with_sdram,
373 sdram_module = sdram_module,
374 sdram_data_width = sdram_data_width,
375 integrated_rom_size = 0, # if ram_fname else 0x10000,
376 #integrated_sram_size = 0x1000, - problem with yosys ABC
377 integrated_sram_size = sram_size,
378 #integrated_main_ram_init = ram_init,
379 integrated_main_ram_size = 0x00000000 if with_sdram \
380 else 0x10000000 , # 256MB
381 )
382
383 self.platform.name = platform_name
384
385 if dff_srams == 5:
386 # add 4 more 4k integrated SRAMs
387 self.add_ram("sram1", self.mem_map["sram1"], 0x200)
388 self.add_ram("sram2", self.mem_map["sram2"], 0x200)
389 self.add_ram("sram3", self.mem_map["sram3"], 0x200)
390 self.add_ram("sram4", self.mem_map["sram4"], 0x200)
391 else:
392 self.add_ram("sram1", self.mem_map["sram1"], 0x80) # tiny!
393
394 # SDR SDRAM ----------------------------------------------
395 if False: # not self.integrated_main_ram_size:
396 self.submodules.sdrphy = sdrphy_cls(platform.request("sdram"))
397
398 if cpu == "libresoc":
399 # XICS interrupt devices
400 icp_addr = self.mem_map['icp']
401 icp_wb = self.cpu.xics_icp
402 icp_region = SoCRegion(origin=icp_addr, size=0x20, cached=False)
403 self.bus.add_slave(name='icp', slave=icp_wb, region=icp_region)
404
405 ics_addr = self.mem_map['ics']
406 ics_wb = self.cpu.xics_ics
407 ics_region = SoCRegion(origin=ics_addr, size=0x1000, cached=False)
408 self.bus.add_slave(name='ics', slave=ics_wb, region=ics_region)
409
410 # add 4x 4k SRAMs
411 for i, sram_wb in enumerate(self.cpu.srams):
412 name = 'sram4k_%d' % i
413 sram_adr = self.mem_map[name]
414 ics_region = SoCRegion(origin=sram_adr, size=0x1000)
415 self.bus.add_slave(name=name, slave=sram_wb, region=ics_region)
416
417 # CRG -----------------------------------------------------------------
418 self.submodules.crg = CRG(platform.request("sys_clk"),
419 platform.request("sys_rst"))
420
421 # PLL/Clock Select
422 clksel_i = platform.request("sys_clksel_i")
423 pll18_o = platform.request("sys_pll_18_o")
424 pll_lck_o = platform.request("sys_pll_lck_o")
425
426 self.comb += self.cpu.clk_sel.eq(clksel_i) # allow clock src select
427 self.comb += pll18_o.eq(self.cpu.pll_18_o) # "test feed" from the PLL
428 self.comb += pll_lck_o.eq(self.cpu.pll_lck_o) # PLL lock flag
429
430 #ram_init = []
431
432 # SDRAM ----------------------------------------------------
433 if with_sdram:
434 sdram_clk_freq = int(100e6) # FIXME: use 100MHz timings
435 sdram_module_cls = getattr(litedram_modules, sdram_module)
436 sdram_rate = "1:{}".format(
437 sdram_module_nphases[sdram_module_cls.memtype])
438 sdram_module = sdram_module_cls(sdram_clk_freq, sdram_rate)
439 phy_settings = get_sdram_phy_settings(
440 memtype = sdram_module.memtype,
441 data_width = sdram_data_width,
442 clk_freq = sdram_clk_freq)
443 #sdrphy_cls = HalfRateGENSDRPHY
444 sdrphy_cls = GENSDRPHY
445 sdram_pads = self.cpu.cpupads['sdr']
446 self.submodules.sdrphy = sdrphy_cls(sdram_pads)
447 #self.submodules.sdrphy = sdrphy_cls(sdram_module,
448 # phy_settings,
449 # init=ram_init
450 # )
451 self.add_sdram("sdram",
452 phy = self.sdrphy,
453 module = sdram_module,
454 origin = self.mem_map["main_ram"],
455 size = 0x80000000,
456 l2_cache_size = 0, # 8192
457 l2_cache_min_data_width = 128,
458 l2_cache_reverse = True
459 )
460 # FIXME: skip memtest to avoid corrupting memory
461 self.add_constant("MEMTEST_BUS_SIZE", 128//16)
462 self.add_constant("MEMTEST_DATA_SIZE", 128//16)
463 self.add_constant("MEMTEST_ADDR_SIZE", 128//16)
464 self.add_constant("MEMTEST_BUS_DEBUG", 1)
465 self.add_constant("MEMTEST_ADDR_DEBUG", 1)
466 self.add_constant("MEMTEST_DATA_DEBUG", 1)
467
468 # SDRAM clock
469 sys_clk = ClockSignal()
470 sdr_clk = self.cpu.cpupads['sdram_clock']
471 #self.specials += DDROutput(1, 0, , sdram_clk)
472 self.specials += SDROutput(clk=sys_clk, i=sys_clk, o=sdr_clk)
473
474 # UART
475 uart_core_pads = self.cpu.cpupads['uart']
476 self.submodules.uart_phy = uart.UARTPHY(
477 pads = uart_core_pads,
478 clk_freq = self.sys_clk_freq,
479 baudrate = 115200)
480 self.submodules.uart = ResetInserter()(uart.UART(self.uart_phy,
481 tx_fifo_depth = 16,
482 rx_fifo_depth = 16))
483
484 self.csr.add("uart_phy", use_loc_if_exists=True)
485 self.csr.add("uart", use_loc_if_exists=True)
486 self.irq.add("uart", use_loc_if_exists=True)
487
488 # GPIOs (bi-directional)
489 gpio_core_pads = self.cpu.cpupads['gpio']
490 self.submodules.gpio0 = GPIOTristateASIC("gpio0", gpio_core_pads,
491 range(8))
492 self.add_csr("gpio0")
493
494 self.submodules.gpio1 = GPIOTristateASIC("gpio1", gpio_core_pads,
495 range(8, 16))
496 self.add_csr("gpio1")
497
498 # SPI Master
499 print ("cpupadkeys", self.cpu.cpupads.keys())
500 sd_clk_freq = 8e6
501 pads = self.cpu.cpupads['mspi0']
502 spimaster = SPIMaster(pads, 8, self.sys_clk_freq, sd_clk_freq)
503 spimaster.add_clk_divider()
504 setattr(self.submodules, 'spimaster', spimaster)
505 self.add_csr('spimaster')
506
507 # SPI SDCard (1 wide)
508 spi_clk_freq = 400e3
509 pads = self.cpu.cpupads['mspi1']
510 spisdcard = SPIMaster(pads, 8, self.sys_clk_freq, spi_clk_freq)
511 spisdcard.add_clk_divider()
512 setattr(self.submodules, 'spisdcard', spisdcard)
513 self.add_csr('spisdcard')
514
515 # EINTs - very simple, wire up top 3 bits to ls180 "eint" pins
516 eintpads = self.cpu.cpupads['eint']
517 print ("eintpads", eintpads)
518 self.comb += self.cpu.interrupt[12:16].eq(eintpads)
519
520 # JTAG
521 jtagpads = platform.request("jtag")
522 self.comb += self.cpu.jtag_tck.eq(jtagpads.tck)
523 self.comb += self.cpu.jtag_tms.eq(jtagpads.tms)
524 self.comb += self.cpu.jtag_tdi.eq(jtagpads.tdi)
525 self.comb += jtagpads.tdo.eq(self.cpu.jtag_tdo)
526
527 # NC - allows some iopads to be connected up
528 # sigh, just do something, anything, to stop yosys optimising these out
529 nc_pads = platform.request("nc")
530 num_nc = len(nc_pads)
531 self.nc = Signal(num_nc)
532 self.comb += self.nc.eq(nc_pads)
533 self.dummy = Signal(num_nc)
534 for i in range(num_nc):
535 self.sync += self.dummy[i].eq(self.nc[i] | self.cpu.interrupt[0])
536
537 # PWM
538 pwmpads = self.cpu.cpupads['pwm']
539 for i in range(2):
540 name = "pwm%d" % i
541 setattr(self.submodules, name, PWM(pwmpads[i]))
542 self.add_csr(name)
543
544 # I2C Master
545 i2c_core_pads = self.cpu.cpupads['mtwi']
546 self.submodules.i2c = I2CMaster(i2c_core_pads)
547 self.add_csr("i2c")
548
549 # SDCard -----------------------------------------------------
550
551 # Emulator / Pads
552 sdcard_pads = self.cpu.cpupads['sd0']
553
554 # Core
555 self.submodules.sdphy = SDPHY(sdcard_pads,
556 self.platform.device, self.clk_freq)
557 self.submodules.sdcore = SDCore(self.sdphy)
558 self.add_csr("sdphy")
559 self.add_csr("sdcore")
560
561 # Block2Mem DMA
562 bus = wishbone.Interface(data_width=self.bus.data_width,
563 adr_width=self.bus.address_width)
564 self.submodules.sdblock2mem = SDBlock2MemDMA(bus=bus,
565 endianness=self.cpu.endianness)
566 self.comb += self.sdcore.source.connect(self.sdblock2mem.sink)
567 dma_bus = self.bus if not hasattr(self, "dma_bus") else self.dma_bus
568 dma_bus.add_master("sdblock2mem", master=bus)
569 self.add_csr("sdblock2mem")
570
571 # Mem2Block DMA
572 bus = wishbone.Interface(data_width=self.bus.data_width,
573 adr_width=self.bus.address_width)
574 self.submodules.sdmem2block = SDMem2BlockDMA(bus=bus,
575 endianness=self.cpu.endianness)
576 self.comb += self.sdmem2block.source.connect(self.sdcore.sink)
577 dma_bus = self.bus if not hasattr(self, "dma_bus") else self.dma_bus
578 dma_bus.add_master("sdmem2block", master=bus)
579 self.add_csr("sdmem2block")
580
581 # Debug ---------------------------------------------------------------
582 if not debug:
583 return
584
585 jtag_en = ('jtag' in variant) or ('ls180' in variant)
586
587 # setup running of DMI FSM
588 dmi_addr = Signal(4)
589 dmi_din = Signal(64)
590 dmi_dout = Signal(64)
591 dmi_wen = Signal(1)
592 dmi_req = Signal(1)
593
594 # debug log out
595 dbg_addr = Signal(4)
596 dbg_dout = Signal(64)
597 dbg_msg = Signal(1)
598
599 # capture pc from dmi
600 pc = Signal(64)
601 active_dbg = Signal()
602 active_dbg_cr = Signal()
603 active_dbg_xer = Signal()
604
605 # xer flags
606 xer_so = Signal()
607 xer_ca = Signal()
608 xer_ca32 = Signal()
609 xer_ov = Signal()
610 xer_ov32 = Signal()
611
612 # increment counter, Stop after 100000 cycles
613 uptime = Signal(64)
614 self.sync += uptime.eq(uptime + 1)
615 #self.sync += If(uptime == 1000000000000, Finish())
616
617 # DMI FSM counter and FSM itself
618 dmicount = Signal(10)
619 dmirunning = Signal(1)
620 dmi_monitor = Signal(1)
621 dmifsm = FSM()
622 self.submodules += dmifsm
623
624 # DMI FSM
625 dmifsm.act("START",
626 If(dmi_req & dmi_wen,
627 (self.cpu.dmi_addr.eq(dmi_addr), # DMI Addr
628 self.cpu.dmi_din.eq(dmi_din), # DMI in
629 self.cpu.dmi_req.eq(1), # DMI request
630 self.cpu.dmi_wr.eq(1), # DMI write
631 If(self.cpu.dmi_ack,
632 (NextState("IDLE"),
633 )
634 ),
635 ),
636 ),
637 If(dmi_req & ~dmi_wen,
638 (self.cpu.dmi_addr.eq(dmi_addr), # DMI Addr
639 self.cpu.dmi_req.eq(1), # DMI request
640 self.cpu.dmi_wr.eq(0), # DMI read
641 If(self.cpu.dmi_ack,
642 # acknowledge received: capture data.
643 (NextState("IDLE"),
644 NextValue(dbg_addr, dmi_addr),
645 NextValue(dbg_dout, self.cpu.dmi_dout),
646 NextValue(dbg_msg, 1),
647 ),
648 ),
649 ),
650 )
651 )
652
653 # DMI response received: reset the dmi request and check if
654 # in "monitor" mode
655 dmifsm.act("IDLE",
656 If(dmi_monitor,
657 NextState("FIRE_MONITOR"), # fire "monitor" on next cycle
658 ).Else(
659 NextState("START"), # back to start on next cycle
660 ),
661 NextValue(dmi_req, 0),
662 NextValue(dmi_addr, 0),
663 NextValue(dmi_din, 0),
664 NextValue(dmi_wen, 0),
665 )
666
667 # "monitor" mode fires off a STAT request
668 dmifsm.act("FIRE_MONITOR",
669 (NextValue(dmi_req, 1),
670 NextValue(dmi_addr, 1), # DMI STAT address
671 NextValue(dmi_din, 0),
672 NextValue(dmi_wen, 0), # read STAT
673 NextState("START"), # back to start on next cycle
674 )
675 )
676
677 self.comb += xer_so.eq((dbg_dout & 1) == 1)
678 self.comb += xer_ca.eq((dbg_dout & 4) == 4)
679 self.comb += xer_ca32.eq((dbg_dout & 8) == 8)
680 self.comb += xer_ov.eq((dbg_dout & 16) == 16)
681 self.comb += xer_ov32.eq((dbg_dout & 32) == 32)
682
683 # debug messages out
684 self.sync += If(dbg_msg,
685 (If(active_dbg & (dbg_addr == 0b10), # PC
686 Display("pc : %016x", dbg_dout),
687 ),
688 If(dbg_addr == 0b10, # PC
689 pc.eq(dbg_dout), # capture PC
690 ),
691 #If(dbg_addr == 0b11, # MSR
692 # Display(" msr: %016x", dbg_dout),
693 #),
694 If(dbg_addr == 0b1000, # CR
695 Display(" cr : %016x", dbg_dout),
696 ),
697 If(dbg_addr == 0b1001, # XER
698 Display(" xer: so %d ca %d 32 %d ov %d 32 %d",
699 xer_so, xer_ca, xer_ca32, xer_ov, xer_ov32),
700 ),
701 If(dbg_addr == 0b101, # GPR
702 Display(" gpr: %016x", dbg_dout),
703 ),
704 # also check if this is a "stat"
705 If(dbg_addr == 1, # requested a STAT
706 #Display(" stat: %x", dbg_dout),
707 If(dbg_dout & 2, # bit 2 of STAT is "stopped" mode
708 dmirunning.eq(1), # continue running
709 dmi_monitor.eq(0), # and stop monitor mode
710 ),
711 ),
712 dbg_msg.eq(0)
713 )
714 )
715
716 # kick off a "stop"
717 self.sync += If(uptime == 0,
718 (dmi_addr.eq(0), # CTRL
719 dmi_din.eq(1<<0), # STOP
720 dmi_req.eq(1),
721 dmi_wen.eq(1),
722 )
723 )
724
725 self.sync += If(uptime == 4,
726 dmirunning.eq(1),
727 )
728
729 self.sync += If(dmirunning,
730 dmicount.eq(dmicount + 1),
731 )
732
733 # loop every 1<<N cycles
734 cyclewid = 9
735
736 # get the PC
737 self.sync += If(dmicount == 4,
738 (dmi_addr.eq(0b10), # NIA
739 dmi_req.eq(1),
740 dmi_wen.eq(0),
741 )
742 )
743
744 # kick off a "step"
745 self.sync += If(dmicount == 8,
746 (dmi_addr.eq(0), # CTRL
747 dmi_din.eq(1<<3), # STEP
748 dmi_req.eq(1),
749 dmi_wen.eq(1),
750 dmirunning.eq(0), # stop counter, need to fire "monitor"
751 dmi_monitor.eq(1), # start "monitor" instead
752 )
753 )
754
755 # limit range of pc for debug reporting
756 #self.comb += active_dbg.eq((0x378c <= pc) & (pc <= 0x38d8))
757 #self.comb += active_dbg.eq((0x0 < pc) & (pc < 0x58))
758 self.comb += active_dbg.eq(1)
759
760
761 # get the MSR
762 self.sync += If(active_dbg & (dmicount == 12),
763 (dmi_addr.eq(0b11), # MSR
764 dmi_req.eq(1),
765 dmi_wen.eq(0),
766 )
767 )
768
769 if cpu == "libresoc":
770 #self.comb += active_dbg_cr.eq((0x10300 <= pc) & (pc <= 0x12600))
771 self.comb += active_dbg_cr.eq(0)
772
773 # get the CR
774 self.sync += If(active_dbg_cr & (dmicount == 16),
775 (dmi_addr.eq(0b1000), # CR
776 dmi_req.eq(1),
777 dmi_wen.eq(0),
778 )
779 )
780
781 #self.comb += active_dbg_xer.eq((0x10300 <= pc) & (pc <= 0x1094c))
782 self.comb += active_dbg_xer.eq(active_dbg_cr)
783
784 # get the CR
785 self.sync += If(active_dbg_xer & (dmicount == 20),
786 (dmi_addr.eq(0b1001), # XER
787 dmi_req.eq(1),
788 dmi_wen.eq(0),
789 )
790 )
791
792 # read all 32 GPRs
793 for i in range(32):
794 self.sync += If(active_dbg & (dmicount == 24+(i*8)),
795 (dmi_addr.eq(0b100), # GSPR addr
796 dmi_din.eq(i), # r1
797 dmi_req.eq(1),
798 dmi_wen.eq(1),
799 )
800 )
801
802 self.sync += If(active_dbg & (dmicount == 28+(i*8)),
803 (dmi_addr.eq(0b101), # GSPR data
804 dmi_req.eq(1),
805 dmi_wen.eq(0),
806 )
807 )
808
809 # monitor bbus read/write
810 self.sync += If(active_dbg & self.cpu.dbus.stb & self.cpu.dbus.ack,
811 Display(" [%06x] dadr: %8x, we %d s %01x w %016x r: %016x",
812 #uptime,
813 0,
814 self.cpu.dbus.adr,
815 self.cpu.dbus.we,
816 self.cpu.dbus.sel,
817 self.cpu.dbus.dat_w,
818 self.cpu.dbus.dat_r
819 )
820 )
821
822 return
823
824 # monitor ibus write
825 self.sync += If(active_dbg & self.cpu.ibus.stb & self.cpu.ibus.ack &
826 self.cpu.ibus.we,
827 Display(" [%06x] iadr: %8x, s %01x w %016x",
828 #uptime,
829 0,
830 self.cpu.ibus.adr,
831 self.cpu.ibus.sel,
832 self.cpu.ibus.dat_w,
833 )
834 )
835 # monitor ibus read
836 self.sync += If(active_dbg & self.cpu.ibus.stb & self.cpu.ibus.ack &
837 ~self.cpu.ibus.we,
838 Display(" [%06x] iadr: %8x, s %01x r %016x",
839 #uptime,
840 0,
841 self.cpu.ibus.adr,
842 self.cpu.ibus.sel,
843 self.cpu.ibus.dat_r
844 )
845 )
846
847 # Build -----------------------------------------------------------------------
848
849 def main():
850 parser = argparse.ArgumentParser(description="LiteX LibreSoC CPU Sim")
851 parser.add_argument("--cpu", default="libresoc",
852 help="CPU to use: libresoc (default) or microwatt")
853 parser.add_argument("--platform", default="sim",
854 help="platform (sim or ls180)")
855 parser.add_argument("--debug", action="store_true",
856 help="Enable debug traces")
857 parser.add_argument("--trace", action="store_true",
858 help="Enable tracing")
859 parser.add_argument("--trace-start", default=0,
860 help="Cycle to start FST tracing")
861 parser.add_argument("--trace-end", default=-1,
862 help="Cycle to end FST tracing")
863 parser.add_argument("--num-srams", default=5,
864 help="number of srams")
865 parser.add_argument("--build", action="store_true", help="Build bitstream")
866 args = parser.parse_args()
867
868 print ("number of SRAMs", args.num_srams)
869
870 if 'ls180' in args.platform:
871 soc = LibreSoCSim(cpu=args.cpu, debug=args.debug,
872 platform=args.platform,
873 dff_srams=args.num_srams)
874 builder = Builder(soc, compile_gateware = True)
875 builder.build(run = True)
876 os.chdir("../")
877 else:
878
879 sim_config = SimConfig(default_clk="sys_clk")
880 sim_config.add_module("serial2console", "serial")
881
882 for i in range(2):
883 soc = LibreSoCSim(cpu=args.cpu, debug=args.debug,
884 platform=args.platform,
885 dff_srams=args.num_srams)
886 builder = Builder(soc, compile_gateware = i!=0)
887 builder.build(sim_config=sim_config,
888 run = i!=0,
889 trace = args.trace,
890 trace_start = int(args.trace_start),
891 trace_end = int(args.trace_end),
892 trace_fst = 0)
893 os.chdir("../")
894
895 if __name__ == "__main__":
896 main()