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
, prange
=None):
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
)
120 prange
= range(nbits
)
122 self
.specials
+= MultiReg(_pads
.i
[i
], self
._in
.status
[i
])
124 # SDCard PHY IO -------------------------------------------------------
126 class SDRPad(Module
):
127 def __init__(self
, pad
, name
, o
, oe
, i
):
129 _o
= getattr(pad
, "%s_o" % name
)
130 _oe
= getattr(pad
, "%s_oe" % name
)
131 _i
= getattr(pad
, "%s_i" % name
)
132 self
.specials
+= SDROutput(clk
=clk
, i
=oe
, o
=_oe
)
133 for j
in range(len(_o
)):
134 self
.specials
+= SDROutput(clk
=clk
, i
=o
[j
], o
=_o
[j
])
135 self
.specials
+= SDRInput(clk
=clk
, i
=_i
[j
], o
=i
[j
])
138 class SDPHYIOGen(Module
):
139 def __init__(self
, clocker
, sdpads
, pads
):
141 if hasattr(pads
, "rst"):
142 self
.comb
+= pads
.rst
.eq(0)
145 self
.specials
+= SDROutput(
147 i
= ~clocker
.clk
& sdpads
.clk
,
153 self
.submodules
.sd_cmd
= SDRPad(pads
, "cmd", c
.o
, c
.oe
, c
.i
)
157 self
.submodules
.sd_data
= SDRPad(pads
, "data", d
.o
, d
.oe
, d
.i
)
160 class SDPHY(Module
, AutoCSR
):
161 def __init__(self
, pads
, device
, sys_clk_freq
,
162 cmd_timeout
=10e-3, data_timeout
=10e-3):
163 self
.card_detect
= CSRStatus() # Assume SDCard is present if no cd pin.
164 self
.comb
+= self
.card_detect
.status
.eq(getattr(pads
, "cd", 0))
166 self
.submodules
.clocker
= clocker
= SDPHYClocker()
167 self
.submodules
.init
= init
= SDPHYInit()
168 self
.submodules
.cmdw
= cmdw
= SDPHYCMDW()
169 self
.submodules
.cmdr
= cmdr
= SDPHYCMDR(sys_clk_freq
,
171 self
.submodules
.dataw
= dataw
= SDPHYDATAW()
172 self
.submodules
.datar
= datar
= SDPHYDATAR(sys_clk_freq
,
177 self
.sdpads
= sdpads
= Record(_sdpads_layout
)
180 sdphy_cls
= SDPHYIOGen
181 self
.submodules
.io
= sdphy_cls(clocker
, sdpads
, pads
)
183 # Connect pads_out of submodules to physical pads --------------
184 pl
= [init
, cmdw
, cmdr
, dataw
, datar
]
186 sdpads
.clk
.eq( reduce(or_
, [m
.pads_out
.clk
for m
in pl
])),
187 sdpads
.cmd
.oe
.eq( reduce(or_
, [m
.pads_out
.cmd
.oe
for m
in pl
])),
188 sdpads
.cmd
.o
.eq( reduce(or_
, [m
.pads_out
.cmd
.o
for m
in pl
])),
189 sdpads
.data
.oe
.eq(reduce(or_
, [m
.pads_out
.data
.oe
for m
in pl
])),
190 sdpads
.data
.o
.eq( reduce(or_
, [m
.pads_out
.data
.o
for m
in pl
])),
193 self
.comb
+= m
.pads_out
.ready
.eq(self
.clocker
.ce
)
195 # Connect physical pads to pads_in of submodules ---------------
197 self
.comb
+= m
.pads_in
.valid
.eq(self
.clocker
.ce
)
198 self
.comb
+= m
.pads_in
.cmd
.i
.eq(sdpads
.cmd
.i
)
199 self
.comb
+= m
.pads_in
.data
.i
.eq(sdpads
.data
.i
)
201 # Speed Throttling -------------------------------------------
202 self
.comb
+= clocker
.stop
.eq(dataw
.stop | datar
.stop
)
205 # Generic SDR PHY ---------------------------------------------------------
207 class GENSDRPHY(Module
):
208 def __init__(self
, pads
, cl
=2, cmd_latency
=1):
209 pads
= PHYPadsCombiner(pads
)
210 addressbits
= len(pads
.a
)
211 bankbits
= len(pads
.ba
)
212 nranks
= 1 if not hasattr(pads
, "cs_n") else len(pads
.cs_n
)
213 databits
= len(pads
.dq_i
)
215 assert databits
%8 == 0
217 # PHY settings ----------------------------------------------------
218 self
.settings
= PhySettings(
219 phytype
= "GENSDRPHY",
222 dfi_databits
= databits
,
230 read_latency
= cl
+ cmd_latency
,
234 # DFI Interface ---------------------------------------------------
235 self
.dfi
= dfi
= DFIInterface(addressbits
, bankbits
, nranks
, databits
)
239 # Iterate on pads groups ------------------------------------------
240 for pads_group
in range(len(pads
.groups
)):
241 pads
.sel_group(pads_group
)
243 # Addresses and Commands --------------------------------------
245 self
.specials
+= [SDROutput(i
=p0
.address
[i
], o
=pads
.a
[i
])
246 for i
in range(len(pads
.a
))]
247 self
.specials
+= [SDROutput(i
=p0
.bank
[i
], o
=pads
.ba
[i
])
248 for i
in range(len(pads
.ba
))]
249 self
.specials
+= SDROutput(i
=p0
.cas_n
, o
=pads
.cas_n
)
250 self
.specials
+= SDROutput(i
=p0
.ras_n
, o
=pads
.ras_n
)
251 self
.specials
+= SDROutput(i
=p0
.we_n
, o
=pads
.we_n
)
252 if hasattr(pads
, "cke"):
253 for i
in range(len(pads
.cke
)):
254 self
.specials
+= SDROutput(i
=p0
.cke
[i
], o
=pads
.cke
[i
])
255 if hasattr(pads
, "cs_n"):
256 for i
in range(len(pads
.cs_n
)):
257 self
.specials
+= SDROutput(i
=p0
.cs_n
[i
], o
=pads
.cs_n
[i
])
259 # DQ/DM Data Path -------------------------------------------------
263 self
.submodules
.dq
= SDRPad(pads
, "dq", d
.wrdata
, d
.wrdata_en
, d
.rddata
)
265 if hasattr(pads
, "dm"):
266 for i
in range(len(pads
.dm
)):
267 self
.specials
+= SDROutput(i
=d
.wrdata_mask
[i
], o
=pads
.dm
[i
])
269 # DQ/DM Control Path ----------------------------------------------
270 rddata_en
= Signal(cl
+ cmd_latency
)
271 self
.sync
+= rddata_en
.eq(Cat(dfi
.p0
.rddata_en
, rddata_en
))
272 self
.sync
+= dfi
.p0
.rddata_valid
.eq(rddata_en
[-1])
275 # LibreSoC 180nm ASIC -------------------------------------------------------
277 class LibreSoCSim(SoCCore
):
278 def __init__(self
, cpu
="libresoc", debug
=False, with_sdram
=True,
279 sdram_module
= "AS4C16M16",
280 #sdram_data_width = 16,
281 #sdram_module = "MT48LC16M16",
282 sdram_data_width
= 16,
283 irq_reserved_irqs
= {'uart': 0},
286 assert cpu
in ["libresoc", "microwatt"]
287 sys_clk_freq
= int(50e6
)
289 if platform
== 'sim':
290 platform
= Platform()
292 elif platform
== 'ls180':
293 platform
= LS180Platform()
301 # reserve XICS ICP and XICS memory addresses.
302 self
.mem_map
['icp'] = 0xc0010000
303 self
.mem_map
['ics'] = 0xc0011000
304 #self.csr_map["icp"] = 8 # 8 x 0x800 == 0x4000
305 #self.csr_map["ics"] = 10 # 10 x 0x800 == 0x5000
309 #ram_init = get_mem_data({
310 # ram_fname: "0x00000000",
312 ram_init
= get_mem_data(ram_fname
, "little")
314 # remap the main RAM to reset-start-address
316 # without sram nothing works, therefore move it to higher up
317 self
.mem_map
["sram"] = 0x90000000
319 # put UART at 0xc000200 (w00t! this works!)
320 self
.csr_map
["uart"] = 4
322 self
.mem_map
["main_ram"] = 0x90000000
323 self
.mem_map
["sram"] = 0x00000000
324 self
.mem_map
["sram1"] = 0x00000200
325 self
.mem_map
["sram2"] = 0x00000400
326 self
.mem_map
["sram3"] = 0x00000600
327 self
.mem_map
["sram4"] = 0x00000800
328 self
.mem_map
["sram4k_0"] = 0x00001000
329 self
.mem_map
["sram4k_1"] = 0x00002000
330 self
.mem_map
["sram4k_2"] = 0x00003000
331 self
.mem_map
["sram4k_3"] = 0x00004000
333 # SoCCore -------------------------------------------------------------
334 SoCCore
.__init
__(self
, platform
, clk_freq
=sys_clk_freq
,
335 cpu_type
= "microwatt",
336 cpu_cls
= LibreSoC
if cpu
== "libresoc" \
339 csr_address_width
= 14, # limit to 0x8000
340 cpu_variant
= variant
,
345 with_sdram
= with_sdram
,
346 sdram_module
= sdram_module
,
347 sdram_data_width
= sdram_data_width
,
348 integrated_rom_size
= 0, # if ram_fname else 0x10000,
349 #integrated_sram_size = 0x1000, - problem with yosys ABC
350 integrated_sram_size
= 0x200,
351 #integrated_main_ram_init = ram_init,
352 integrated_main_ram_size
= 0x00000000 if with_sdram \
353 else 0x10000000 , # 256MB
355 self
.platform
.name
= "ls180"
357 # add 4 more 4k integrated SRAMs
358 self
.add_ram("sram1", self
.mem_map
["sram1"], 0x200)
359 self
.add_ram("sram2", self
.mem_map
["sram2"], 0x200)
360 self
.add_ram("sram3", self
.mem_map
["sram3"], 0x200)
361 self
.add_ram("sram4", self
.mem_map
["sram4"], 0x200)
363 # SDR SDRAM ----------------------------------------------
364 if False: # not self.integrated_main_ram_size:
365 self
.submodules
.sdrphy
= sdrphy_cls(platform
.request("sdram"))
367 if cpu
== "libresoc":
368 # XICS interrupt devices
369 icp_addr
= self
.mem_map
['icp']
370 icp_wb
= self
.cpu
.xics_icp
371 icp_region
= SoCRegion(origin
=icp_addr
, size
=0x20, cached
=False)
372 self
.bus
.add_slave(name
='icp', slave
=icp_wb
, region
=icp_region
)
374 ics_addr
= self
.mem_map
['ics']
375 ics_wb
= self
.cpu
.xics_ics
376 ics_region
= SoCRegion(origin
=ics_addr
, size
=0x1000, cached
=False)
377 self
.bus
.add_slave(name
='ics', slave
=ics_wb
, region
=ics_region
)
380 for i
, sram_wb
in enumerate(self
.cpu
.srams
):
381 name
= 'sram4k_%d' % i
382 sram_adr
= self
.mem_map
[name
]
383 ics_region
= SoCRegion(origin
=sram_adr
, size
=0x1000)
384 self
.bus
.add_slave(name
=name
, slave
=sram_wb
, region
=ics_region
)
386 # CRG -----------------------------------------------------------------
387 self
.submodules
.crg
= CRG(platform
.request("sys_clk"),
388 platform
.request("sys_rst"))
391 clksel_i
= platform
.request("sys_clksel_i")
392 pll18_o
= platform
.request("sys_pll_18_o")
393 pll_lck_o
= platform
.request("sys_pll_lck_o")
395 self
.comb
+= self
.cpu
.clk_sel
.eq(clksel_i
) # allow clock src select
396 self
.comb
+= pll18_o
.eq(self
.cpu
.pll_18_o
) # "test feed" from the PLL
397 self
.comb
+= pll_lck_o
.eq(self
.cpu
.pll_lck_o
) # PLL lock flag
401 # SDRAM ----------------------------------------------------
403 sdram_clk_freq
= int(100e6
) # FIXME: use 100MHz timings
404 sdram_module_cls
= getattr(litedram_modules
, sdram_module
)
405 sdram_rate
= "1:{}".format(
406 sdram_module_nphases
[sdram_module_cls
.memtype
])
407 sdram_module
= sdram_module_cls(sdram_clk_freq
, sdram_rate
)
408 phy_settings
= get_sdram_phy_settings(
409 memtype
= sdram_module
.memtype
,
410 data_width
= sdram_data_width
,
411 clk_freq
= sdram_clk_freq
)
412 #sdrphy_cls = HalfRateGENSDRPHY
413 sdrphy_cls
= GENSDRPHY
414 sdram_pads
= self
.cpu
.cpupads
['sdr']
415 self
.submodules
.sdrphy
= sdrphy_cls(sdram_pads
)
416 #self.submodules.sdrphy = sdrphy_cls(sdram_module,
420 self
.add_sdram("sdram",
422 module
= sdram_module
,
423 origin
= self
.mem_map
["main_ram"],
425 l2_cache_size
= 0, # 8192
426 l2_cache_min_data_width
= 128,
427 l2_cache_reverse
= True
429 # FIXME: skip memtest to avoid corrupting memory
430 self
.add_constant("MEMTEST_BUS_SIZE", 128//16)
431 self
.add_constant("MEMTEST_DATA_SIZE", 128//16)
432 self
.add_constant("MEMTEST_ADDR_SIZE", 128//16)
433 self
.add_constant("MEMTEST_BUS_DEBUG", 1)
434 self
.add_constant("MEMTEST_ADDR_DEBUG", 1)
435 self
.add_constant("MEMTEST_DATA_DEBUG", 1)
438 sys_clk
= ClockSignal()
439 sdr_clk
= self
.cpu
.cpupads
['sdram_clock']
440 #self.specials += DDROutput(1, 0, , sdram_clk)
441 self
.specials
+= SDROutput(clk
=sys_clk
, i
=sys_clk
, o
=sdr_clk
)
444 uart_core_pads
= self
.cpu
.cpupads
['uart']
445 self
.submodules
.uart_phy
= uart
.UARTPHY(
446 pads
= uart_core_pads
,
447 clk_freq
= self
.sys_clk_freq
,
449 self
.submodules
.uart
= ResetInserter()(uart
.UART(self
.uart_phy
,
453 self
.csr
.add("uart_phy", use_loc_if_exists
=True)
454 self
.csr
.add("uart", use_loc_if_exists
=True)
455 self
.irq
.add("uart", use_loc_if_exists
=True)
457 # GPIOs (bi-directional)
458 gpio_core_pads
= self
.cpu
.cpupads
['gpio']
459 self
.submodules
.gpio
= GPIOTristateASIC(gpio_core_pads
, range(8))
462 self
.submodules
.gpio
= GPIOTristateASIC(gpio_core_pads
, range(8,16))
463 self
.add_csr("gpio1")
466 print ("cpupadkeys", self
.cpu
.cpupads
.keys())
467 self
.submodules
.spimaster
= SPIMaster(
468 pads
= self
.cpu
.cpupads
['mspi1'],
470 sys_clk_freq
= sys_clk_freq
,
473 self
.add_csr("spimaster")
475 # SPI SDCard (1 wide)
477 pads
= self
.cpu
.cpupads
['mspi0']
478 spisdcard
= SPIMaster(pads
, 8, self
.sys_clk_freq
, spi_clk_freq
)
479 spisdcard
.add_clk_divider()
480 setattr(self
.submodules
, 'spisdcard', spisdcard
)
481 self
.add_csr('spisdcard')
483 # EINTs - very simple, wire up top 3 bits to ls180 "eint" pins
484 eintpads
= self
.cpu
.cpupads
['eint']
485 print ("eintpads", eintpads
)
486 self
.comb
+= self
.cpu
.interrupt
[12:16].eq(eintpads
)
489 jtagpads
= platform
.request("jtag")
490 self
.comb
+= self
.cpu
.jtag_tck
.eq(jtagpads
.tck
)
491 self
.comb
+= self
.cpu
.jtag_tms
.eq(jtagpads
.tms
)
492 self
.comb
+= self
.cpu
.jtag_tdi
.eq(jtagpads
.tdi
)
493 self
.comb
+= jtagpads
.tdo
.eq(self
.cpu
.jtag_tdo
)
495 # NC - allows some iopads to be connected up
496 # sigh, just do something, anything, to stop yosys optimising these out
497 nc_pads
= platform
.request("nc")
498 num_nc
= len(nc_pads
)
499 self
.nc
= Signal(num_nc
)
500 self
.comb
+= self
.nc
.eq(nc_pads
)
501 self
.dummy
= Signal(num_nc
)
502 for i
in range(num_nc
):
503 self
.sync
+= self
.dummy
[i
].eq(self
.nc
[i
] | self
.cpu
.interrupt
[0])
506 pwmpads
= self
.cpu
.cpupads
['pwm']
509 setattr(self
.submodules
, name
, PWM(pwmpads
[i
]))
513 i2c_core_pads
= self
.cpu
.cpupads
['mtwi']
514 self
.submodules
.i2c
= I2CMaster(i2c_core_pads
)
517 # SDCard -----------------------------------------------------
520 sdcard_pads
= self
.cpu
.cpupads
['sd0']
523 self
.submodules
.sdphy
= SDPHY(sdcard_pads
,
524 self
.platform
.device
, self
.clk_freq
)
525 self
.submodules
.sdcore
= SDCore(self
.sdphy
)
526 self
.add_csr("sdphy")
527 self
.add_csr("sdcore")
530 bus
= wishbone
.Interface(data_width
=self
.bus
.data_width
,
531 adr_width
=self
.bus
.address_width
)
532 self
.submodules
.sdblock2mem
= SDBlock2MemDMA(bus
=bus
,
533 endianness
=self
.cpu
.endianness
)
534 self
.comb
+= self
.sdcore
.source
.connect(self
.sdblock2mem
.sink
)
535 dma_bus
= self
.bus
if not hasattr(self
, "dma_bus") else self
.dma_bus
536 dma_bus
.add_master("sdblock2mem", master
=bus
)
537 self
.add_csr("sdblock2mem")
540 bus
= wishbone
.Interface(data_width
=self
.bus
.data_width
,
541 adr_width
=self
.bus
.address_width
)
542 self
.submodules
.sdmem2block
= SDMem2BlockDMA(bus
=bus
,
543 endianness
=self
.cpu
.endianness
)
544 self
.comb
+= self
.sdmem2block
.source
.connect(self
.sdcore
.sink
)
545 dma_bus
= self
.bus
if not hasattr(self
, "dma_bus") else self
.dma_bus
546 dma_bus
.add_master("sdmem2block", master
=bus
)
547 self
.add_csr("sdmem2block")
549 # Debug ---------------------------------------------------------------
553 jtag_en
= ('jtag' in variant
) or variant
== 'ls180'
555 # setup running of DMI FSM
558 dmi_dout
= Signal(64)
564 dbg_dout
= Signal(64)
567 # capture pc from dmi
569 active_dbg
= Signal()
570 active_dbg_cr
= Signal()
571 active_dbg_xer
= Signal()
580 # increment counter, Stop after 100000 cycles
582 self
.sync
+= uptime
.eq(uptime
+ 1)
583 #self.sync += If(uptime == 1000000000000, Finish())
585 # DMI FSM counter and FSM itself
586 dmicount
= Signal(10)
587 dmirunning
= Signal(1)
588 dmi_monitor
= Signal(1)
590 self
.submodules
+= dmifsm
594 If(dmi_req
& dmi_wen
,
595 (self
.cpu
.dmi_addr
.eq(dmi_addr
), # DMI Addr
596 self
.cpu
.dmi_din
.eq(dmi_din
), # DMI in
597 self
.cpu
.dmi_req
.eq(1), # DMI request
598 self
.cpu
.dmi_wr
.eq(1), # DMI write
605 If(dmi_req
& ~dmi_wen
,
606 (self
.cpu
.dmi_addr
.eq(dmi_addr
), # DMI Addr
607 self
.cpu
.dmi_req
.eq(1), # DMI request
608 self
.cpu
.dmi_wr
.eq(0), # DMI read
610 # acknowledge received: capture data.
612 NextValue(dbg_addr
, dmi_addr
),
613 NextValue(dbg_dout
, self
.cpu
.dmi_dout
),
614 NextValue(dbg_msg
, 1),
621 # DMI response received: reset the dmi request and check if
625 NextState("FIRE_MONITOR"), # fire "monitor" on next cycle
627 NextState("START"), # back to start on next cycle
629 NextValue(dmi_req
, 0),
630 NextValue(dmi_addr
, 0),
631 NextValue(dmi_din
, 0),
632 NextValue(dmi_wen
, 0),
635 # "monitor" mode fires off a STAT request
636 dmifsm
.act("FIRE_MONITOR",
637 (NextValue(dmi_req
, 1),
638 NextValue(dmi_addr
, 1), # DMI STAT address
639 NextValue(dmi_din
, 0),
640 NextValue(dmi_wen
, 0), # read STAT
641 NextState("START"), # back to start on next cycle
645 self
.comb
+= xer_so
.eq((dbg_dout
& 1) == 1)
646 self
.comb
+= xer_ca
.eq((dbg_dout
& 4) == 4)
647 self
.comb
+= xer_ca32
.eq((dbg_dout
& 8) == 8)
648 self
.comb
+= xer_ov
.eq((dbg_dout
& 16) == 16)
649 self
.comb
+= xer_ov32
.eq((dbg_dout
& 32) == 32)
652 self
.sync
+= If(dbg_msg
,
653 (If(active_dbg
& (dbg_addr
== 0b10), # PC
654 Display("pc : %016x", dbg_dout
),
656 If(dbg_addr
== 0b10, # PC
657 pc
.eq(dbg_dout
), # capture PC
659 #If(dbg_addr == 0b11, # MSR
660 # Display(" msr: %016x", dbg_dout),
662 If(dbg_addr
== 0b1000, # CR
663 Display(" cr : %016x", dbg_dout
),
665 If(dbg_addr
== 0b1001, # XER
666 Display(" xer: so %d ca %d 32 %d ov %d 32 %d",
667 xer_so
, xer_ca
, xer_ca32
, xer_ov
, xer_ov32
),
669 If(dbg_addr
== 0b101, # GPR
670 Display(" gpr: %016x", dbg_dout
),
672 # also check if this is a "stat"
673 If(dbg_addr
== 1, # requested a STAT
674 #Display(" stat: %x", dbg_dout),
675 If(dbg_dout
& 2, # bit 2 of STAT is "stopped" mode
676 dmirunning
.eq(1), # continue running
677 dmi_monitor
.eq(0), # and stop monitor mode
685 self
.sync
+= If(uptime
== 0,
686 (dmi_addr
.eq(0), # CTRL
687 dmi_din
.eq(1<<0), # STOP
693 self
.sync
+= If(uptime
== 4,
697 self
.sync
+= If(dmirunning
,
698 dmicount
.eq(dmicount
+ 1),
701 # loop every 1<<N cycles
705 self
.sync
+= If(dmicount
== 4,
706 (dmi_addr
.eq(0b10), # NIA
713 self
.sync
+= If(dmicount
== 8,
714 (dmi_addr
.eq(0), # CTRL
715 dmi_din
.eq(1<<3), # STEP
718 dmirunning
.eq(0), # stop counter, need to fire "monitor"
719 dmi_monitor
.eq(1), # start "monitor" instead
723 # limit range of pc for debug reporting
724 #self.comb += active_dbg.eq((0x378c <= pc) & (pc <= 0x38d8))
725 #self.comb += active_dbg.eq((0x0 < pc) & (pc < 0x58))
726 self
.comb
+= active_dbg
.eq(1)
730 self
.sync
+= If(active_dbg
& (dmicount
== 12),
731 (dmi_addr
.eq(0b11), # MSR
737 if cpu
== "libresoc":
738 #self.comb += active_dbg_cr.eq((0x10300 <= pc) & (pc <= 0x12600))
739 self
.comb
+= active_dbg_cr
.eq(0)
742 self
.sync
+= If(active_dbg_cr
& (dmicount
== 16),
743 (dmi_addr
.eq(0b1000), # CR
749 #self.comb += active_dbg_xer.eq((0x10300 <= pc) & (pc <= 0x1094c))
750 self
.comb
+= active_dbg_xer
.eq(active_dbg_cr
)
753 self
.sync
+= If(active_dbg_xer
& (dmicount
== 20),
754 (dmi_addr
.eq(0b1001), # XER
762 self
.sync
+= If(active_dbg
& (dmicount
== 24+(i
*8)),
763 (dmi_addr
.eq(0b100), # GSPR addr
770 self
.sync
+= If(active_dbg
& (dmicount
== 28+(i
*8)),
771 (dmi_addr
.eq(0b101), # GSPR data
777 # monitor bbus read/write
778 self
.sync
+= If(active_dbg
& self
.cpu
.dbus
.stb
& self
.cpu
.dbus
.ack
,
779 Display(" [%06x] dadr: %8x, we %d s %01x w %016x r: %016x",
793 self
.sync
+= If(active_dbg
& self
.cpu
.ibus
.stb
& self
.cpu
.ibus
.ack
&
795 Display(" [%06x] iadr: %8x, s %01x w %016x",
804 self
.sync
+= If(active_dbg
& self
.cpu
.ibus
.stb
& self
.cpu
.ibus
.ack
&
806 Display(" [%06x] iadr: %8x, s %01x r %016x",
815 # Build -----------------------------------------------------------------------
818 parser
= argparse
.ArgumentParser(description
="LiteX LibreSoC CPU Sim")
819 parser
.add_argument("--cpu", default
="libresoc",
820 help="CPU to use: libresoc (default) or microwatt")
821 parser
.add_argument("--platform", default
="sim",
822 help="platform (sim or ls180)")
823 parser
.add_argument("--debug", action
="store_true",
824 help="Enable debug traces")
825 parser
.add_argument("--trace", action
="store_true",
826 help="Enable tracing")
827 parser
.add_argument("--trace-start", default
=0,
828 help="Cycle to start FST tracing")
829 parser
.add_argument("--trace-end", default
=-1,
830 help="Cycle to end FST tracing")
831 parser
.add_argument("--build", action
="store_true", help="Build bitstream")
832 args
= parser
.parse_args()
835 if args
.platform
== 'ls180':
836 soc
= LibreSoCSim(cpu
=args
.cpu
, debug
=args
.debug
,
837 platform
=args
.platform
)
838 builder
= Builder(soc
, compile_gateware
= True)
839 builder
.build(run
= True)
843 sim_config
= SimConfig(default_clk
="sys_clk")
844 sim_config
.add_module("serial2console", "serial")
847 soc
= LibreSoCSim(cpu
=args
.cpu
, debug
=args
.debug
,
848 platform
=args
.platform
)
849 builder
= Builder(soc
, compile_gateware
= i
!=0)
850 builder
.build(sim_config
=sim_config
,
853 trace_start
= int(args
.trace_start
),
854 trace_end
= int(args
.trace_end
),
858 if __name__
== "__main__":