5 from functools
import reduce
6 from operator
import or_
8 from migen
import (Signal
, FSM
, If
, Display
, Finish
, NextValue
, NextState
,
9 Cat
, Record
, ClockSignal
, wrap
, ResetInserter
)
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
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
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
32 from litex
.tools
.litex_sim
import sdram_module_nphases
, get_sdram_phy_settings
34 from litex
.tools
.litex_sim
import Platform
35 from libresoc
.ls180
import LS180Platform
37 from migen
import Module
38 from litex
.soc
.interconnect
.csr
import AutoCSR
40 from libresoc
import LibreSoC
41 from microwatt
import Microwatt
44 from litex
.soc
.integration
.soc
import SoCCSRHandler
45 SoCCSRHandler
.supported_address_width
.append(12)
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
54 from litex
.soc
.interconnect
import wishbone
55 from litesdcard
.phy
import (SDPHY
, SDPHYClocker
,
56 SDPHYInit
, SDPHYCMDW
, SDPHYCMDR
,
57 SDPHYDATAW
, SDPHYDATAR
,
59 from litesdcard
.core
import SDCore
60 from litesdcard
.frontend
.dma
import SDBlock2MemDMA
, SDMem2BlockDMA
61 from litex
.build
.io
import SDROutput
, SDRInput
64 # I2C Master Bit-Banging --------------------------------------------------
66 class I2CMaster(Module
, AutoCSR
):
67 """I2C Master Bit-Banging
69 Provides the minimal hardware to do software I2C Master bit banging.
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).
75 pads_layout
= [("scl", 1), ("sda", 1)]
76 def __init__(self
, 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)],
83 self
._r
= CSRStatus(fields
=[
84 CSRField("sda", size
=1, offset
=0)],
89 def connect(self
, pads
):
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
),
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.")
110 _pads
= Record( (("i", 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
)
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
])
122 # SDCard PHY IO -------------------------------------------------------
124 class SDRPad(Module
):
125 def __init__(self
, pad
, name
, o
, oe
, i
):
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
])
136 class SDPHYIOGen(Module
):
137 def __init__(self
, clocker
, sdpads
, pads
):
139 if hasattr(pads
, "rst"):
140 self
.comb
+= pads
.rst
.eq(0)
143 self
.specials
+= SDROutput(
145 i
= ~clocker
.clk
& sdpads
.clk
,
151 self
.submodules
.sd_cmd
= SDRPad(pads
, "cmd", c
.o
, c
.oe
, c
.i
)
155 self
.submodules
.sd_data
= SDRPad(pads
, "data", d
.o
, d
.oe
, d
.i
)
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))
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
,
169 self
.submodules
.dataw
= dataw
= SDPHYDATAW()
170 self
.submodules
.datar
= datar
= SDPHYDATAR(sys_clk_freq
,
175 self
.sdpads
= sdpads
= Record(_sdpads_layout
)
178 sdphy_cls
= SDPHYIOGen
179 self
.submodules
.io
= sdphy_cls(clocker
, sdpads
, pads
)
181 # Connect pads_out of submodules to physical pads --------------
182 pl
= [init
, cmdw
, cmdr
, dataw
, datar
]
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
])),
191 self
.comb
+= m
.pads_out
.ready
.eq(self
.clocker
.ce
)
193 # Connect physical pads to pads_in of submodules ---------------
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
)
199 # Speed Throttling -------------------------------------------
200 self
.comb
+= clocker
.stop
.eq(dataw
.stop | datar
.stop
)
203 # Generic SDR PHY ---------------------------------------------------------
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
)
213 assert databits
%8 == 0
215 # PHY settings ----------------------------------------------------
216 self
.settings
= PhySettings(
217 phytype
= "GENSDRPHY",
220 dfi_databits
= databits
,
228 read_latency
= cl
+ cmd_latency
,
232 # DFI Interface ---------------------------------------------------
233 self
.dfi
= dfi
= DFIInterface(addressbits
, bankbits
, nranks
, databits
)
237 # Iterate on pads groups ------------------------------------------
238 for pads_group
in range(len(pads
.groups
)):
239 pads
.sel_group(pads_group
)
241 # Addresses and Commands --------------------------------------
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
])
257 # DQ/DM Data Path -------------------------------------------------
261 self
.submodules
.dq
= SDRPad(pads
, "dq", d
.wrdata
, d
.wrdata_en
, d
.rddata
)
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
])
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])
273 # LibreSoC 180nm ASIC -------------------------------------------------------
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},
284 assert cpu
in ["libresoc", "microwatt"]
285 sys_clk_freq
= int(50e6
)
287 if platform
== 'sim':
288 platform
= Platform()
290 elif platform
== 'ls180':
291 platform
= LS180Platform()
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
307 #ram_init = get_mem_data({
308 # ram_fname: "0x00000000",
310 ram_init
= get_mem_data(ram_fname
, "little")
312 # remap the main RAM to reset-start-address
314 # without sram nothing works, therefore move it to higher up
315 self
.mem_map
["sram"] = 0x90000000
317 # put UART at 0xc000200 (w00t! this works!)
318 self
.csr_map
["uart"] = 4
320 self
.mem_map
["main_ram"] = 0x90000000
321 self
.mem_map
["sram"] = 0x00000000
323 # SoCCore -------------------------------------------------------------
324 SoCCore
.__init
__(self
, platform
, clk_freq
=sys_clk_freq
,
325 cpu_type
= "microwatt",
326 cpu_cls
= LibreSoC
if cpu
== "libresoc" \
328 #bus_data_width = 64,
329 csr_address_width
= 14, # limit to 0x8000
330 cpu_variant
= variant
,
335 with_sdram
= with_sdram
,
336 sdram_module
= sdram_module
,
337 sdram_data_width
= sdram_data_width
,
338 integrated_rom_size
= 0, # if ram_fname else 0x10000,
339 integrated_sram_size
= 0x200,
340 #integrated_main_ram_init = ram_init,
341 integrated_main_ram_size
= 0x00000000 if with_sdram \
342 else 0x10000000 , # 256MB
344 self
.platform
.name
= "ls180"
346 # SDR SDRAM ----------------------------------------------
347 if False: # not self.integrated_main_ram_size:
348 self
.submodules
.sdrphy
= sdrphy_cls(platform
.request("sdram"))
350 if cpu
== "libresoc":
351 # XICS interrupt devices
352 icp_addr
= self
.mem_map
['icp']
353 icp_wb
= self
.cpu
.xics_icp
354 icp_region
= SoCRegion(origin
=icp_addr
, size
=0x20, cached
=False)
355 self
.bus
.add_slave(name
='icp', slave
=icp_wb
, region
=icp_region
)
357 ics_addr
= self
.mem_map
['ics']
358 ics_wb
= self
.cpu
.xics_ics
359 ics_region
= SoCRegion(origin
=ics_addr
, size
=0x1000, cached
=False)
360 self
.bus
.add_slave(name
='ics', slave
=ics_wb
, region
=ics_region
)
362 # CRG -----------------------------------------------------------------
363 self
.submodules
.crg
= CRG(platform
.request("sys_clk"),
364 platform
.request("sys_rst"))
367 clksel_i
= platform
.request("sys_clksel_i")
368 pll48_o
= platform
.request("sys_pll_48_o")
370 self
.comb
+= self
.cpu
.clk_sel
.eq(clksel_i
) # allow clock src select
371 self
.comb
+= pll48_o
.eq(self
.cpu
.pll_48_o
) # "test feed" from the PLL
375 # SDRAM ----------------------------------------------------
377 sdram_clk_freq
= int(100e6
) # FIXME: use 100MHz timings
378 sdram_module_cls
= getattr(litedram_modules
, sdram_module
)
379 sdram_rate
= "1:{}".format(
380 sdram_module_nphases
[sdram_module_cls
.memtype
])
381 sdram_module
= sdram_module_cls(sdram_clk_freq
, sdram_rate
)
382 phy_settings
= get_sdram_phy_settings(
383 memtype
= sdram_module
.memtype
,
384 data_width
= sdram_data_width
,
385 clk_freq
= sdram_clk_freq
)
386 #sdrphy_cls = HalfRateGENSDRPHY
387 sdrphy_cls
= GENSDRPHY
388 self
.submodules
.sdrphy
= sdrphy_cls(platform
.request("sdram"))
389 #self.submodules.sdrphy = sdrphy_cls(sdram_module,
393 self
.add_sdram("sdram",
395 module
= sdram_module
,
396 origin
= self
.mem_map
["main_ram"],
398 l2_cache_size
= 0, # 8192
399 l2_cache_min_data_width
= 128,
400 l2_cache_reverse
= True
402 # FIXME: skip memtest to avoid corrupting memory
403 self
.add_constant("MEMTEST_BUS_SIZE", 128//16)
404 self
.add_constant("MEMTEST_DATA_SIZE", 128//16)
405 self
.add_constant("MEMTEST_ADDR_SIZE", 128//16)
406 self
.add_constant("MEMTEST_BUS_DEBUG", 1)
407 self
.add_constant("MEMTEST_ADDR_DEBUG", 1)
408 self
.add_constant("MEMTEST_DATA_DEBUG", 1)
411 sys_clk
= ClockSignal()
412 sdr_clk
= platform
.request("sdram_clock")
413 #self.specials += DDROutput(1, 0, , sdram_clk)
414 self
.specials
+= SDROutput(clk
=sys_clk
, i
=sys_clk
, o
=sdr_clk
)
417 uart_core_pads
= self
.cpu
.cpupads
['uart']
418 self
.submodules
.uart_phy
= uart
.UARTPHY(
419 pads
= uart_core_pads
,
420 clk_freq
= self
.sys_clk_freq
,
422 self
.submodules
.uart
= ResetInserter()(uart
.UART(self
.uart_phy
,
426 self
.csr
.add("uart_phy", use_loc_if_exists
=True)
427 self
.csr
.add("uart", use_loc_if_exists
=True)
428 self
.irq
.add("uart", use_loc_if_exists
=True)
430 # GPIOs (bi-directional)
431 gpio_core_pads
= self
.cpu
.cpupads
['gpio']
432 self
.submodules
.gpio
= GPIOTristateASIC(gpio_core_pads
)
436 self
.submodules
.spi_master
= SPIMaster(
437 pads
= platform
.request("spi_master"),
439 sys_clk_freq
= sys_clk_freq
,
442 self
.add_csr("spi_master")
444 # EINTs - very simple, wire up top 3 bits to ls180 "eint" pins
445 self
.comb
+= self
.cpu
.interrupt
[12:16].eq(platform
.request("eint"))
448 jtagpads
= platform
.request("jtag")
449 self
.comb
+= self
.cpu
.jtag_tck
.eq(jtagpads
.tck
)
450 self
.comb
+= self
.cpu
.jtag_tms
.eq(jtagpads
.tms
)
451 self
.comb
+= self
.cpu
.jtag_tdi
.eq(jtagpads
.tdi
)
452 self
.comb
+= jtagpads
.tdo
.eq(self
.cpu
.jtag_tdo
)
454 # NC - allows some iopads to be connected up
455 # sigh, just do something, anything, to stop yosys optimising these out
456 nc_pads
= platform
.request("nc")
457 num_nc
= len(nc_pads
)
458 self
.nc
= Signal(num_nc
)
459 self
.comb
+= self
.nc
.eq(nc_pads
)
460 self
.dummy
= Signal(num_nc
)
461 for i
in range(num_nc
):
462 self
.sync
+= self
.dummy
[i
].eq(self
.nc
[i
] | self
.cpu
.interrupt
[0])
467 setattr(self
.submodules
, name
, PWM(platform
.request("pwm", i
)))
471 self
.submodules
.i2c
= I2CMaster(platform
.request("i2c"))
474 # SDCard -----------------------------------------------------
477 sdcard_pads
= self
.platform
.request("sdcard")
480 self
.submodules
.sdphy
= SDPHY(sdcard_pads
,
481 self
.platform
.device
, self
.clk_freq
)
482 self
.submodules
.sdcore
= SDCore(self
.sdphy
)
483 self
.add_csr("sdphy")
484 self
.add_csr("sdcore")
487 bus
= wishbone
.Interface(data_width
=self
.bus
.data_width
,
488 adr_width
=self
.bus
.address_width
)
489 self
.submodules
.sdblock2mem
= SDBlock2MemDMA(bus
=bus
,
490 endianness
=self
.cpu
.endianness
)
491 self
.comb
+= self
.sdcore
.source
.connect(self
.sdblock2mem
.sink
)
492 dma_bus
= self
.bus
if not hasattr(self
, "dma_bus") else self
.dma_bus
493 dma_bus
.add_master("sdblock2mem", master
=bus
)
494 self
.add_csr("sdblock2mem")
497 bus
= wishbone
.Interface(data_width
=self
.bus
.data_width
,
498 adr_width
=self
.bus
.address_width
)
499 self
.submodules
.sdmem2block
= SDMem2BlockDMA(bus
=bus
,
500 endianness
=self
.cpu
.endianness
)
501 self
.comb
+= self
.sdmem2block
.source
.connect(self
.sdcore
.sink
)
502 dma_bus
= self
.bus
if not hasattr(self
, "dma_bus") else self
.dma_bus
503 dma_bus
.add_master("sdmem2block", master
=bus
)
504 self
.add_csr("sdmem2block")
506 # Debug ---------------------------------------------------------------
510 # setup running of DMI FSM
513 dmi_dout
= Signal(64)
519 dbg_dout
= Signal(64)
522 # capture pc from dmi
524 active_dbg
= Signal()
525 active_dbg_cr
= Signal()
526 active_dbg_xer
= Signal()
535 # increment counter, Stop after 100000 cycles
537 self
.sync
+= uptime
.eq(uptime
+ 1)
538 #self.sync += If(uptime == 1000000000000, Finish())
540 # DMI FSM counter and FSM itself
541 dmicount
= Signal(10)
542 dmirunning
= Signal(1)
543 dmi_monitor
= Signal(1)
545 self
.submodules
+= dmifsm
549 If(dmi_req
& dmi_wen
,
550 (self
.cpu
.dmi_addr
.eq(dmi_addr
), # DMI Addr
551 self
.cpu
.dmi_din
.eq(dmi_din
), # DMI in
552 self
.cpu
.dmi_req
.eq(1), # DMI request
553 self
.cpu
.dmi_wr
.eq(1), # DMI write
560 If(dmi_req
& ~dmi_wen
,
561 (self
.cpu
.dmi_addr
.eq(dmi_addr
), # DMI Addr
562 self
.cpu
.dmi_req
.eq(1), # DMI request
563 self
.cpu
.dmi_wr
.eq(0), # DMI read
565 # acknowledge received: capture data.
567 NextValue(dbg_addr
, dmi_addr
),
568 NextValue(dbg_dout
, self
.cpu
.dmi_dout
),
569 NextValue(dbg_msg
, 1),
576 # DMI response received: reset the dmi request and check if
580 NextState("FIRE_MONITOR"), # fire "monitor" on next cycle
582 NextState("START"), # back to start on next cycle
584 NextValue(dmi_req
, 0),
585 NextValue(dmi_addr
, 0),
586 NextValue(dmi_din
, 0),
587 NextValue(dmi_wen
, 0),
590 # "monitor" mode fires off a STAT request
591 dmifsm
.act("FIRE_MONITOR",
592 (NextValue(dmi_req
, 1),
593 NextValue(dmi_addr
, 1), # DMI STAT address
594 NextValue(dmi_din
, 0),
595 NextValue(dmi_wen
, 0), # read STAT
596 NextState("START"), # back to start on next cycle
600 self
.comb
+= xer_so
.eq((dbg_dout
& 1) == 1)
601 self
.comb
+= xer_ca
.eq((dbg_dout
& 4) == 4)
602 self
.comb
+= xer_ca32
.eq((dbg_dout
& 8) == 8)
603 self
.comb
+= xer_ov
.eq((dbg_dout
& 16) == 16)
604 self
.comb
+= xer_ov32
.eq((dbg_dout
& 32) == 32)
607 self
.sync
+= If(dbg_msg
,
608 (If(active_dbg
& (dbg_addr
== 0b10), # PC
609 Display("pc : %016x", dbg_dout
),
611 If(dbg_addr
== 0b10, # PC
612 pc
.eq(dbg_dout
), # capture PC
614 #If(dbg_addr == 0b11, # MSR
615 # Display(" msr: %016x", dbg_dout),
617 If(dbg_addr
== 0b1000, # CR
618 Display(" cr : %016x", dbg_dout
),
620 If(dbg_addr
== 0b1001, # XER
621 Display(" xer: so %d ca %d 32 %d ov %d 32 %d",
622 xer_so
, xer_ca
, xer_ca32
, xer_ov
, xer_ov32
),
624 If(dbg_addr
== 0b101, # GPR
625 Display(" gpr: %016x", dbg_dout
),
627 # also check if this is a "stat"
628 If(dbg_addr
== 1, # requested a STAT
629 #Display(" stat: %x", dbg_dout),
630 If(dbg_dout
& 2, # bit 2 of STAT is "stopped" mode
631 dmirunning
.eq(1), # continue running
632 dmi_monitor
.eq(0), # and stop monitor mode
640 self
.sync
+= If(uptime
== 0,
641 (dmi_addr
.eq(0), # CTRL
642 dmi_din
.eq(1<<0), # STOP
648 self
.sync
+= If(uptime
== 4,
652 self
.sync
+= If(dmirunning
,
653 dmicount
.eq(dmicount
+ 1),
656 # loop every 1<<N cycles
660 self
.sync
+= If(dmicount
== 4,
661 (dmi_addr
.eq(0b10), # NIA
668 self
.sync
+= If(dmicount
== 8,
669 (dmi_addr
.eq(0), # CTRL
670 dmi_din
.eq(1<<3), # STEP
673 dmirunning
.eq(0), # stop counter, need to fire "monitor"
674 dmi_monitor
.eq(1), # start "monitor" instead
678 # limit range of pc for debug reporting
679 #self.comb += active_dbg.eq((0x378c <= pc) & (pc <= 0x38d8))
680 #self.comb += active_dbg.eq((0x0 < pc) & (pc < 0x58))
681 self
.comb
+= active_dbg
.eq(1)
685 self
.sync
+= If(active_dbg
& (dmicount
== 12),
686 (dmi_addr
.eq(0b11), # MSR
692 if cpu
== "libresoc":
693 #self.comb += active_dbg_cr.eq((0x10300 <= pc) & (pc <= 0x12600))
694 self
.comb
+= active_dbg_cr
.eq(0)
697 self
.sync
+= If(active_dbg_cr
& (dmicount
== 16),
698 (dmi_addr
.eq(0b1000), # CR
704 #self.comb += active_dbg_xer.eq((0x10300 <= pc) & (pc <= 0x1094c))
705 self
.comb
+= active_dbg_xer
.eq(active_dbg_cr
)
708 self
.sync
+= If(active_dbg_xer
& (dmicount
== 20),
709 (dmi_addr
.eq(0b1001), # XER
717 self
.sync
+= If(active_dbg
& (dmicount
== 24+(i
*8)),
718 (dmi_addr
.eq(0b100), # GSPR addr
725 self
.sync
+= If(active_dbg
& (dmicount
== 28+(i
*8)),
726 (dmi_addr
.eq(0b101), # GSPR data
732 # monitor bbus read/write
733 self
.sync
+= If(active_dbg
& self
.cpu
.dbus
.stb
& self
.cpu
.dbus
.ack
,
734 Display(" [%06x] dadr: %8x, we %d s %01x w %016x r: %016x",
748 self
.sync
+= If(active_dbg
& self
.cpu
.ibus
.stb
& self
.cpu
.ibus
.ack
&
750 Display(" [%06x] iadr: %8x, s %01x w %016x",
759 self
.sync
+= If(active_dbg
& self
.cpu
.ibus
.stb
& self
.cpu
.ibus
.ack
&
761 Display(" [%06x] iadr: %8x, s %01x r %016x",
770 # Build -----------------------------------------------------------------------
773 parser
= argparse
.ArgumentParser(description
="LiteX LibreSoC CPU Sim")
774 parser
.add_argument("--cpu", default
="libresoc",
775 help="CPU to use: libresoc (default) or microwatt")
776 parser
.add_argument("--platform", default
="sim",
777 help="platform (sim or ls180)")
778 parser
.add_argument("--debug", action
="store_true",
779 help="Enable debug traces")
780 parser
.add_argument("--trace", action
="store_true",
781 help="Enable tracing")
782 parser
.add_argument("--trace-start", default
=0,
783 help="Cycle to start FST tracing")
784 parser
.add_argument("--trace-end", default
=-1,
785 help="Cycle to end FST tracing")
786 parser
.add_argument("--build", action
="store_true", help="Build bitstream")
787 args
= parser
.parse_args()
790 if args
.platform
== 'ls180':
791 soc
= LibreSoCSim(cpu
=args
.cpu
, debug
=args
.debug
,
792 platform
=args
.platform
)
794 builder
= Builder(soc
, compile_gateware
= True)
795 builder
.build(run
= True)
799 sim_config
= SimConfig(default_clk
="sys_clk")
800 sim_config
.add_module("serial2console", "serial")
803 soc
= LibreSoCSim(cpu
=args
.cpu
, debug
=args
.debug
,
804 platform
=args
.platform
)
805 builder
= Builder(soc
, compile_gateware
= i
!=0)
806 builder
.build(sim_config
=sim_config
,
809 trace_start
= int(args
.trace_start
),
810 trace_end
= int(args
.trace_end
),
814 if __name__
== "__main__":