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