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