add 3 more 4k SRAMs, change WB bus width to 64 in ls180 litex
[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,
343 #integrated_main_ram_init = ram_init,
344 integrated_main_ram_size = 0x00000000 if with_sdram \
345 else 0x10000000 , # 256MB
346 )
347 self.platform.name = "ls180"
348
349 # add 3 more 4k integrated SRAMs
350 self.add_ram("sram1", self.mem_map["sram1"], 0x1000)
351 self.add_ram("sram2", self.mem_map["sram2"], 0x1000)
352 self.add_ram("sram3", self.mem_map["sram3"], 0x1000)
353
354 # SDR SDRAM ----------------------------------------------
355 if False: # not self.integrated_main_ram_size:
356 self.submodules.sdrphy = sdrphy_cls(platform.request("sdram"))
357
358 if cpu == "libresoc":
359 # XICS interrupt devices
360 icp_addr = self.mem_map['icp']
361 icp_wb = self.cpu.xics_icp
362 icp_region = SoCRegion(origin=icp_addr, size=0x20, cached=False)
363 self.bus.add_slave(name='icp', slave=icp_wb, region=icp_region)
364
365 ics_addr = self.mem_map['ics']
366 ics_wb = self.cpu.xics_ics
367 ics_region = SoCRegion(origin=ics_addr, size=0x1000, cached=False)
368 self.bus.add_slave(name='ics', slave=ics_wb, region=ics_region)
369
370 # CRG -----------------------------------------------------------------
371 self.submodules.crg = CRG(platform.request("sys_clk"),
372 platform.request("sys_rst"))
373
374 # PLL/Clock Select
375 clksel_i = platform.request("sys_clksel_i")
376 pll18_o = platform.request("sys_pll_18_o")
377 pll_lck_o = platform.request("sys_pll_lck_o")
378
379 self.comb += self.cpu.clk_sel.eq(clksel_i) # allow clock src select
380 self.comb += pll18_o.eq(self.cpu.pll_18_o) # "test feed" from the PLL
381 self.comb += pll_lck_o.eq(self.cpu.pll_lck_o) # PLL lock flag
382
383 #ram_init = []
384
385 # SDRAM ----------------------------------------------------
386 if with_sdram:
387 sdram_clk_freq = int(100e6) # FIXME: use 100MHz timings
388 sdram_module_cls = getattr(litedram_modules, sdram_module)
389 sdram_rate = "1:{}".format(
390 sdram_module_nphases[sdram_module_cls.memtype])
391 sdram_module = sdram_module_cls(sdram_clk_freq, sdram_rate)
392 phy_settings = get_sdram_phy_settings(
393 memtype = sdram_module.memtype,
394 data_width = sdram_data_width,
395 clk_freq = sdram_clk_freq)
396 #sdrphy_cls = HalfRateGENSDRPHY
397 sdrphy_cls = GENSDRPHY
398 sdram_pads = self.cpu.cpupads['sdr']
399 self.submodules.sdrphy = sdrphy_cls(sdram_pads)
400 #self.submodules.sdrphy = sdrphy_cls(sdram_module,
401 # phy_settings,
402 # init=ram_init
403 # )
404 self.add_sdram("sdram",
405 phy = self.sdrphy,
406 module = sdram_module,
407 origin = self.mem_map["main_ram"],
408 size = 0x80000000,
409 l2_cache_size = 0, # 8192
410 l2_cache_min_data_width = 128,
411 l2_cache_reverse = True
412 )
413 # FIXME: skip memtest to avoid corrupting memory
414 self.add_constant("MEMTEST_BUS_SIZE", 128//16)
415 self.add_constant("MEMTEST_DATA_SIZE", 128//16)
416 self.add_constant("MEMTEST_ADDR_SIZE", 128//16)
417 self.add_constant("MEMTEST_BUS_DEBUG", 1)
418 self.add_constant("MEMTEST_ADDR_DEBUG", 1)
419 self.add_constant("MEMTEST_DATA_DEBUG", 1)
420
421 # SDRAM clock
422 sys_clk = ClockSignal()
423 sdr_clk = self.cpu.cpupads['sdram_clock']
424 #self.specials += DDROutput(1, 0, , sdram_clk)
425 self.specials += SDROutput(clk=sys_clk, i=sys_clk, o=sdr_clk)
426
427 # UART
428 uart_core_pads = self.cpu.cpupads['uart']
429 self.submodules.uart_phy = uart.UARTPHY(
430 pads = uart_core_pads,
431 clk_freq = self.sys_clk_freq,
432 baudrate = 115200)
433 self.submodules.uart = ResetInserter()(uart.UART(self.uart_phy,
434 tx_fifo_depth = 16,
435 rx_fifo_depth = 16))
436
437 self.csr.add("uart_phy", use_loc_if_exists=True)
438 self.csr.add("uart", use_loc_if_exists=True)
439 self.irq.add("uart", use_loc_if_exists=True)
440
441 # GPIOs (bi-directional)
442 gpio_core_pads = self.cpu.cpupads['gpio']
443 self.submodules.gpio = GPIOTristateASIC(gpio_core_pads)
444 self.add_csr("gpio")
445
446 # SPI Master
447 print ("cpupadkeys", self.cpu.cpupads.keys())
448 self.submodules.spimaster = SPIMaster(
449 pads = self.cpu.cpupads['mspi1'],
450 data_width = 8,
451 sys_clk_freq = sys_clk_freq,
452 spi_clk_freq = 8e6,
453 )
454 self.add_csr("spimaster")
455
456 # SPI SDCard (1 wide)
457 spi_clk_freq = 400e3
458 pads = self.cpu.cpupads['mspi0']
459 spisdcard = SPIMaster(pads, 8, self.sys_clk_freq, spi_clk_freq)
460 spisdcard.add_clk_divider()
461 setattr(self.submodules, 'spisdcard', spisdcard)
462 self.add_csr('spisdcard')
463
464 # EINTs - very simple, wire up top 3 bits to ls180 "eint" pins
465 eintpads = self.cpu.cpupads['eint']
466 print ("eintpads", eintpads)
467 self.comb += self.cpu.interrupt[12:16].eq(eintpads)
468
469 # JTAG
470 jtagpads = platform.request("jtag")
471 self.comb += self.cpu.jtag_tck.eq(jtagpads.tck)
472 self.comb += self.cpu.jtag_tms.eq(jtagpads.tms)
473 self.comb += self.cpu.jtag_tdi.eq(jtagpads.tdi)
474 self.comb += jtagpads.tdo.eq(self.cpu.jtag_tdo)
475
476 # NC - allows some iopads to be connected up
477 # sigh, just do something, anything, to stop yosys optimising these out
478 nc_pads = platform.request("nc")
479 num_nc = len(nc_pads)
480 self.nc = Signal(num_nc)
481 self.comb += self.nc.eq(nc_pads)
482 self.dummy = Signal(num_nc)
483 for i in range(num_nc):
484 self.sync += self.dummy[i].eq(self.nc[i] | self.cpu.interrupt[0])
485
486 # PWM
487 pwmpads = self.cpu.cpupads['pwm']
488 for i in range(2):
489 name = "pwm%d" % i
490 setattr(self.submodules, name, PWM(pwmpads[i]))
491 self.add_csr(name)
492
493 # I2C Master
494 i2c_core_pads = self.cpu.cpupads['mtwi']
495 self.submodules.i2c = I2CMaster(i2c_core_pads)
496 self.add_csr("i2c")
497
498 # SDCard -----------------------------------------------------
499
500 # Emulator / Pads
501 sdcard_pads = self.cpu.cpupads['sd0']
502
503 # Core
504 self.submodules.sdphy = SDPHY(sdcard_pads,
505 self.platform.device, self.clk_freq)
506 self.submodules.sdcore = SDCore(self.sdphy)
507 self.add_csr("sdphy")
508 self.add_csr("sdcore")
509
510 # Block2Mem DMA
511 bus = wishbone.Interface(data_width=self.bus.data_width,
512 adr_width=self.bus.address_width)
513 self.submodules.sdblock2mem = SDBlock2MemDMA(bus=bus,
514 endianness=self.cpu.endianness)
515 self.comb += self.sdcore.source.connect(self.sdblock2mem.sink)
516 dma_bus = self.bus if not hasattr(self, "dma_bus") else self.dma_bus
517 dma_bus.add_master("sdblock2mem", master=bus)
518 self.add_csr("sdblock2mem")
519
520 # Mem2Block DMA
521 bus = wishbone.Interface(data_width=self.bus.data_width,
522 adr_width=self.bus.address_width)
523 self.submodules.sdmem2block = SDMem2BlockDMA(bus=bus,
524 endianness=self.cpu.endianness)
525 self.comb += self.sdmem2block.source.connect(self.sdcore.sink)
526 dma_bus = self.bus if not hasattr(self, "dma_bus") else self.dma_bus
527 dma_bus.add_master("sdmem2block", master=bus)
528 self.add_csr("sdmem2block")
529
530 # Debug ---------------------------------------------------------------
531 if not debug:
532 return
533
534 jtag_en = ('jtag' in variant) or variant == 'ls180'
535
536 # setup running of DMI FSM
537 dmi_addr = Signal(4)
538 dmi_din = Signal(64)
539 dmi_dout = Signal(64)
540 dmi_wen = Signal(1)
541 dmi_req = Signal(1)
542
543 # debug log out
544 dbg_addr = Signal(4)
545 dbg_dout = Signal(64)
546 dbg_msg = Signal(1)
547
548 # capture pc from dmi
549 pc = Signal(64)
550 active_dbg = Signal()
551 active_dbg_cr = Signal()
552 active_dbg_xer = Signal()
553
554 # xer flags
555 xer_so = Signal()
556 xer_ca = Signal()
557 xer_ca32 = Signal()
558 xer_ov = Signal()
559 xer_ov32 = Signal()
560
561 # increment counter, Stop after 100000 cycles
562 uptime = Signal(64)
563 self.sync += uptime.eq(uptime + 1)
564 #self.sync += If(uptime == 1000000000000, Finish())
565
566 # DMI FSM counter and FSM itself
567 dmicount = Signal(10)
568 dmirunning = Signal(1)
569 dmi_monitor = Signal(1)
570 dmifsm = FSM()
571 self.submodules += dmifsm
572
573 # DMI FSM
574 dmifsm.act("START",
575 If(dmi_req & dmi_wen,
576 (self.cpu.dmi_addr.eq(dmi_addr), # DMI Addr
577 self.cpu.dmi_din.eq(dmi_din), # DMI in
578 self.cpu.dmi_req.eq(1), # DMI request
579 self.cpu.dmi_wr.eq(1), # DMI write
580 If(self.cpu.dmi_ack,
581 (NextState("IDLE"),
582 )
583 ),
584 ),
585 ),
586 If(dmi_req & ~dmi_wen,
587 (self.cpu.dmi_addr.eq(dmi_addr), # DMI Addr
588 self.cpu.dmi_req.eq(1), # DMI request
589 self.cpu.dmi_wr.eq(0), # DMI read
590 If(self.cpu.dmi_ack,
591 # acknowledge received: capture data.
592 (NextState("IDLE"),
593 NextValue(dbg_addr, dmi_addr),
594 NextValue(dbg_dout, self.cpu.dmi_dout),
595 NextValue(dbg_msg, 1),
596 ),
597 ),
598 ),
599 )
600 )
601
602 # DMI response received: reset the dmi request and check if
603 # in "monitor" mode
604 dmifsm.act("IDLE",
605 If(dmi_monitor,
606 NextState("FIRE_MONITOR"), # fire "monitor" on next cycle
607 ).Else(
608 NextState("START"), # back to start on next cycle
609 ),
610 NextValue(dmi_req, 0),
611 NextValue(dmi_addr, 0),
612 NextValue(dmi_din, 0),
613 NextValue(dmi_wen, 0),
614 )
615
616 # "monitor" mode fires off a STAT request
617 dmifsm.act("FIRE_MONITOR",
618 (NextValue(dmi_req, 1),
619 NextValue(dmi_addr, 1), # DMI STAT address
620 NextValue(dmi_din, 0),
621 NextValue(dmi_wen, 0), # read STAT
622 NextState("START"), # back to start on next cycle
623 )
624 )
625
626 self.comb += xer_so.eq((dbg_dout & 1) == 1)
627 self.comb += xer_ca.eq((dbg_dout & 4) == 4)
628 self.comb += xer_ca32.eq((dbg_dout & 8) == 8)
629 self.comb += xer_ov.eq((dbg_dout & 16) == 16)
630 self.comb += xer_ov32.eq((dbg_dout & 32) == 32)
631
632 # debug messages out
633 self.sync += If(dbg_msg,
634 (If(active_dbg & (dbg_addr == 0b10), # PC
635 Display("pc : %016x", dbg_dout),
636 ),
637 If(dbg_addr == 0b10, # PC
638 pc.eq(dbg_dout), # capture PC
639 ),
640 #If(dbg_addr == 0b11, # MSR
641 # Display(" msr: %016x", dbg_dout),
642 #),
643 If(dbg_addr == 0b1000, # CR
644 Display(" cr : %016x", dbg_dout),
645 ),
646 If(dbg_addr == 0b1001, # XER
647 Display(" xer: so %d ca %d 32 %d ov %d 32 %d",
648 xer_so, xer_ca, xer_ca32, xer_ov, xer_ov32),
649 ),
650 If(dbg_addr == 0b101, # GPR
651 Display(" gpr: %016x", dbg_dout),
652 ),
653 # also check if this is a "stat"
654 If(dbg_addr == 1, # requested a STAT
655 #Display(" stat: %x", dbg_dout),
656 If(dbg_dout & 2, # bit 2 of STAT is "stopped" mode
657 dmirunning.eq(1), # continue running
658 dmi_monitor.eq(0), # and stop monitor mode
659 ),
660 ),
661 dbg_msg.eq(0)
662 )
663 )
664
665 # kick off a "stop"
666 self.sync += If(uptime == 0,
667 (dmi_addr.eq(0), # CTRL
668 dmi_din.eq(1<<0), # STOP
669 dmi_req.eq(1),
670 dmi_wen.eq(1),
671 )
672 )
673
674 self.sync += If(uptime == 4,
675 dmirunning.eq(1),
676 )
677
678 self.sync += If(dmirunning,
679 dmicount.eq(dmicount + 1),
680 )
681
682 # loop every 1<<N cycles
683 cyclewid = 9
684
685 # get the PC
686 self.sync += If(dmicount == 4,
687 (dmi_addr.eq(0b10), # NIA
688 dmi_req.eq(1),
689 dmi_wen.eq(0),
690 )
691 )
692
693 # kick off a "step"
694 self.sync += If(dmicount == 8,
695 (dmi_addr.eq(0), # CTRL
696 dmi_din.eq(1<<3), # STEP
697 dmi_req.eq(1),
698 dmi_wen.eq(1),
699 dmirunning.eq(0), # stop counter, need to fire "monitor"
700 dmi_monitor.eq(1), # start "monitor" instead
701 )
702 )
703
704 # limit range of pc for debug reporting
705 #self.comb += active_dbg.eq((0x378c <= pc) & (pc <= 0x38d8))
706 #self.comb += active_dbg.eq((0x0 < pc) & (pc < 0x58))
707 self.comb += active_dbg.eq(1)
708
709
710 # get the MSR
711 self.sync += If(active_dbg & (dmicount == 12),
712 (dmi_addr.eq(0b11), # MSR
713 dmi_req.eq(1),
714 dmi_wen.eq(0),
715 )
716 )
717
718 if cpu == "libresoc":
719 #self.comb += active_dbg_cr.eq((0x10300 <= pc) & (pc <= 0x12600))
720 self.comb += active_dbg_cr.eq(0)
721
722 # get the CR
723 self.sync += If(active_dbg_cr & (dmicount == 16),
724 (dmi_addr.eq(0b1000), # CR
725 dmi_req.eq(1),
726 dmi_wen.eq(0),
727 )
728 )
729
730 #self.comb += active_dbg_xer.eq((0x10300 <= pc) & (pc <= 0x1094c))
731 self.comb += active_dbg_xer.eq(active_dbg_cr)
732
733 # get the CR
734 self.sync += If(active_dbg_xer & (dmicount == 20),
735 (dmi_addr.eq(0b1001), # XER
736 dmi_req.eq(1),
737 dmi_wen.eq(0),
738 )
739 )
740
741 # read all 32 GPRs
742 for i in range(32):
743 self.sync += If(active_dbg & (dmicount == 24+(i*8)),
744 (dmi_addr.eq(0b100), # GSPR addr
745 dmi_din.eq(i), # r1
746 dmi_req.eq(1),
747 dmi_wen.eq(1),
748 )
749 )
750
751 self.sync += If(active_dbg & (dmicount == 28+(i*8)),
752 (dmi_addr.eq(0b101), # GSPR data
753 dmi_req.eq(1),
754 dmi_wen.eq(0),
755 )
756 )
757
758 # monitor bbus read/write
759 self.sync += If(active_dbg & self.cpu.dbus.stb & self.cpu.dbus.ack,
760 Display(" [%06x] dadr: %8x, we %d s %01x w %016x r: %016x",
761 #uptime,
762 0,
763 self.cpu.dbus.adr,
764 self.cpu.dbus.we,
765 self.cpu.dbus.sel,
766 self.cpu.dbus.dat_w,
767 self.cpu.dbus.dat_r
768 )
769 )
770
771 return
772
773 # monitor ibus write
774 self.sync += If(active_dbg & self.cpu.ibus.stb & self.cpu.ibus.ack &
775 self.cpu.ibus.we,
776 Display(" [%06x] iadr: %8x, s %01x w %016x",
777 #uptime,
778 0,
779 self.cpu.ibus.adr,
780 self.cpu.ibus.sel,
781 self.cpu.ibus.dat_w,
782 )
783 )
784 # monitor ibus read
785 self.sync += If(active_dbg & self.cpu.ibus.stb & self.cpu.ibus.ack &
786 ~self.cpu.ibus.we,
787 Display(" [%06x] iadr: %8x, s %01x r %016x",
788 #uptime,
789 0,
790 self.cpu.ibus.adr,
791 self.cpu.ibus.sel,
792 self.cpu.ibus.dat_r
793 )
794 )
795
796 # Build -----------------------------------------------------------------------
797
798 def main():
799 parser = argparse.ArgumentParser(description="LiteX LibreSoC CPU Sim")
800 parser.add_argument("--cpu", default="libresoc",
801 help="CPU to use: libresoc (default) or microwatt")
802 parser.add_argument("--platform", default="sim",
803 help="platform (sim or ls180)")
804 parser.add_argument("--debug", action="store_true",
805 help="Enable debug traces")
806 parser.add_argument("--trace", action="store_true",
807 help="Enable tracing")
808 parser.add_argument("--trace-start", default=0,
809 help="Cycle to start FST tracing")
810 parser.add_argument("--trace-end", default=-1,
811 help="Cycle to end FST tracing")
812 parser.add_argument("--build", action="store_true", help="Build bitstream")
813 args = parser.parse_args()
814
815
816 if args.platform == 'ls180':
817 soc = LibreSoCSim(cpu=args.cpu, debug=args.debug,
818 platform=args.platform)
819 builder = Builder(soc, compile_gateware = True)
820 builder.build(run = True)
821 os.chdir("../")
822 else:
823
824 sim_config = SimConfig(default_clk="sys_clk")
825 sim_config.add_module("serial2console", "serial")
826
827 for i in range(2):
828 soc = LibreSoCSim(cpu=args.cpu, debug=args.debug,
829 platform=args.platform)
830 builder = Builder(soc, compile_gateware = i!=0)
831 builder.build(sim_config=sim_config,
832 run = i!=0,
833 trace = args.trace,
834 trace_start = int(args.trace_start),
835 trace_end = int(args.trace_end),
836 trace_fst = 0)
837 os.chdir("../")
838
839 if __name__ == "__main__":
840 main()