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