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)
46 SoCCSRHandler
.supported_address_width
.append(13)
48 # GPIO Tristate -------------------------------------------------------
49 # doesn't work properly.
50 #from litex.soc.cores.gpio import GPIOTristate
51 from litex
.soc
.interconnect
.csr
import CSRStorage
, CSRStatus
, CSRField
52 from migen
.genlib
.cdc
import MultiReg
55 from litex
.soc
.interconnect
import wishbone
56 from litesdcard
.phy
import (SDPHY
, SDPHYClocker
,
57 SDPHYInit
, SDPHYCMDW
, SDPHYCMDR
,
58 SDPHYDATAW
, SDPHYDATAR
,
60 from litesdcard
.core
import SDCore
61 from litesdcard
.frontend
.dma
import SDBlock2MemDMA
, SDMem2BlockDMA
62 from litex
.build
.io
import SDROutput
, SDRInput
65 # I2C Master Bit-Banging --------------------------------------------------
67 class I2CMaster(Module
, AutoCSR
):
68 """I2C Master Bit-Banging
70 Provides the minimal hardware to do software I2C Master bit banging.
72 On the same write CSRStorage (_w), software can control SCL (I2C_SCL),
73 SDA direction and value (I2C_OE, I2C_W). Software get back SDA value
74 with the read CSRStatus (_r).
76 pads_layout
= [("scl", 1), ("sda", 1)]
77 def __init__(self
, pads
):
79 self
._w
= CSRStorage(fields
=[
80 CSRField("scl", size
=1, offset
=0),
81 CSRField("oe", size
=1, offset
=1),
82 CSRField("sda", size
=1, offset
=2)],
84 self
._r
= CSRStatus(fields
=[
85 CSRField("sda", size
=1, offset
=0)],
90 def connect(self
, pads
):
95 pads
.scl
.eq(self
._w
.fields
.scl
),
96 pads
.sda_oe
.eq( self
._w
.fields
.oe
),
97 pads
.sda_o
.eq( self
._w
.fields
.sda
),
98 self
._r
.fields
.sda
.eq(pads
.sda_i
),
102 class GPIOTristateASIC(Module
, AutoCSR
):
103 def __init__(self
, name
, pads
, prange
=None):
105 prange
= range(nbits
)
108 self
._oe
= CSRStorage(nbits
, description
="GPIO Tristate(s) Control.")
109 self
._in
= CSRStatus(nbits
, description
="GPIO Input(s) Status.")
110 self
._out
= CSRStorage(nbits
, description
="GPIO Ouptut(s) Control.")
114 _pads
= Record( ((name
+"i", nbits
),
117 _o
= getattr(_pads
, name
+"o")
118 _oe
= getattr(_pads
, name
+"oe")
119 _i
= getattr(_pads
, name
+"i")
120 for j
, i
in enumerate(prange
):
121 self
.comb
+= _i
[j
].eq(pads
.i
[i
])
122 self
.comb
+= pads
.o
[i
].eq(_o
[j
])
123 self
.comb
+= pads
.oe
[i
].eq(_oe
[j
])
126 o
= self
._out
.storage
127 oe
= self
._oe
.storage
129 for j
in range(nbits
):
130 self
.specials
+= SDROutput(clk
=clk
, i
=oe
[j
], o
=_oe
[j
])
131 self
.specials
+= SDROutput(clk
=clk
, i
=o
[j
], o
=_o
[j
])
132 self
.specials
+= SDRInput(clk
=clk
, i
=_i
[j
], o
=i
[j
])
133 #for i in range(nbits):
134 #self.comb += _pads.oe[i].eq(self._oe.storage[i])
135 #self.comb += _pads.o[i].eq(self._out.storage[i])
136 #self.specials += MultiReg(_pads.i[i], self._in.status[i])
138 # SDCard PHY IO -------------------------------------------------------
140 class SDRPad(Module
):
141 def __init__(self
, pad
, name
, o
, oe
, i
):
143 _o
= getattr(pad
, "%s_o" % name
)
144 _oe
= getattr(pad
, "%s_oe" % name
)
145 _i
= getattr(pad
, "%s_i" % name
)
146 for j
in range(len(_o
)):
147 self
.specials
+= SDROutput(clk
=clk
, i
=oe
, o
=_oe
[j
])
148 self
.specials
+= SDROutput(clk
=clk
, i
=o
[j
], o
=_o
[j
])
149 self
.specials
+= SDRInput(clk
=clk
, i
=_i
[j
], o
=i
[j
])
152 class SDPHYIOGen(Module
):
153 def __init__(self
, clocker
, sdpads
, pads
):
155 if hasattr(pads
, "rst"):
156 self
.comb
+= pads
.rst
.eq(0)
159 self
.specials
+= SDROutput(
161 i
= ~clocker
.clk
& sdpads
.clk
,
167 self
.submodules
.sd_cmd
= SDRPad(pads
, "cmd", c
.o
, c
.oe
, c
.i
)
171 self
.submodules
.sd_data
= SDRPad(pads
, "data", d
.o
, d
.oe
, d
.i
)
174 class SDPHY(Module
, AutoCSR
):
175 def __init__(self
, pads
, device
, sys_clk_freq
,
176 cmd_timeout
=10e-3, data_timeout
=10e-3):
177 self
.card_detect
= CSRStatus() # Assume SDCard is present if no cd pin.
178 self
.comb
+= self
.card_detect
.status
.eq(getattr(pads
, "cd", 0))
180 self
.submodules
.clocker
= clocker
= SDPHYClocker()
181 self
.submodules
.init
= init
= SDPHYInit()
182 self
.submodules
.cmdw
= cmdw
= SDPHYCMDW()
183 self
.submodules
.cmdr
= cmdr
= SDPHYCMDR(sys_clk_freq
,
185 self
.submodules
.dataw
= dataw
= SDPHYDATAW()
186 self
.submodules
.datar
= datar
= SDPHYDATAR(sys_clk_freq
,
191 self
.sdpads
= sdpads
= Record(_sdpads_layout
)
194 sdphy_cls
= SDPHYIOGen
195 self
.submodules
.io
= sdphy_cls(clocker
, sdpads
, pads
)
197 # Connect pads_out of submodules to physical pads --------------
198 pl
= [init
, cmdw
, cmdr
, dataw
, datar
]
200 sdpads
.clk
.eq( reduce(or_
, [m
.pads_out
.clk
for m
in pl
])),
201 sdpads
.cmd
.oe
.eq( reduce(or_
, [m
.pads_out
.cmd
.oe
for m
in pl
])),
202 sdpads
.cmd
.o
.eq( reduce(or_
, [m
.pads_out
.cmd
.o
for m
in pl
])),
203 sdpads
.data
.oe
.eq(reduce(or_
, [m
.pads_out
.data
.oe
for m
in pl
])),
204 sdpads
.data
.o
.eq( reduce(or_
, [m
.pads_out
.data
.o
for m
in pl
])),
207 self
.comb
+= m
.pads_out
.ready
.eq(self
.clocker
.ce
)
209 # Connect physical pads to pads_in of submodules ---------------
211 self
.comb
+= m
.pads_in
.valid
.eq(self
.clocker
.ce
)
212 self
.comb
+= m
.pads_in
.cmd
.i
.eq(sdpads
.cmd
.i
)
213 self
.comb
+= m
.pads_in
.data
.i
.eq(sdpads
.data
.i
)
215 # Speed Throttling -------------------------------------------
216 self
.comb
+= clocker
.stop
.eq(dataw
.stop | datar
.stop
)
219 # Generic SDR PHY ---------------------------------------------------------
221 class GENSDRPHY(Module
):
222 def __init__(self
, pads
, cl
=2, cmd_latency
=1):
223 pads
= PHYPadsCombiner(pads
)
224 addressbits
= len(pads
.a
)
225 bankbits
= len(pads
.ba
)
226 nranks
= 1 if not hasattr(pads
, "cs_n") else len(pads
.cs_n
)
227 databits
= len(pads
.dq_i
)
229 assert databits
%8 == 0
231 # PHY settings ----------------------------------------------------
232 self
.settings
= PhySettings(
233 phytype
= "GENSDRPHY",
236 dfi_databits
= databits
,
244 read_latency
= cl
+ cmd_latency
,
248 # DFI Interface ---------------------------------------------------
249 self
.dfi
= dfi
= DFIInterface(addressbits
, bankbits
, nranks
, databits
)
253 # Iterate on pads groups ------------------------------------------
254 for pads_group
in range(len(pads
.groups
)):
255 pads
.sel_group(pads_group
)
257 # Addresses and Commands --------------------------------------
259 self
.specials
+= [SDROutput(i
=p0
.address
[i
], o
=pads
.a
[i
])
260 for i
in range(len(pads
.a
))]
261 self
.specials
+= [SDROutput(i
=p0
.bank
[i
], o
=pads
.ba
[i
])
262 for i
in range(len(pads
.ba
))]
263 self
.specials
+= SDROutput(i
=p0
.cas_n
, o
=pads
.cas_n
)
264 self
.specials
+= SDROutput(i
=p0
.ras_n
, o
=pads
.ras_n
)
265 self
.specials
+= SDROutput(i
=p0
.we_n
, o
=pads
.we_n
)
266 if hasattr(pads
, "cke"):
267 for i
in range(len(pads
.cke
)):
268 self
.specials
+= SDROutput(i
=p0
.cke
[i
], o
=pads
.cke
[i
])
269 if hasattr(pads
, "cs_n"):
270 for i
in range(len(pads
.cs_n
)):
271 self
.specials
+= SDROutput(i
=p0
.cs_n
[i
], o
=pads
.cs_n
[i
])
273 # DQ/DM Data Path -------------------------------------------------
277 self
.submodules
.dq
= SDRPad(pads
, "dq", d
.wrdata
, d
.wrdata_en
, d
.rddata
)
279 if hasattr(pads
, "dm"):
280 print ("sdr pads dm len", pads
.dm
, len(pads
.dm
))
281 for i
in range(len(pads
.dm
)):
282 self
.specials
+= SDROutput(i
=d
.wrdata_en
&d
.wrdata_mask
[i
],
285 # DQ/DM Control Path ----------------------------------------------
286 rddata_en
= Signal(cl
+ cmd_latency
)
287 self
.sync
+= rddata_en
.eq(Cat(dfi
.p0
.rddata_en
, rddata_en
))
288 self
.sync
+= dfi
.p0
.rddata_valid
.eq(rddata_en
[-1])
291 # LibreSoC 180nm ASIC -------------------------------------------------------
293 class LibreSoCSim(SoCCore
):
294 def __init__(self
, cpu
="libresoc", debug
=False, with_sdram
=True,
295 sdram_module
= "AS4C16M16",
296 #sdram_data_width = 16,
297 #sdram_module = "MT48LC16M16",
298 sdram_data_width
= 16,
299 irq_reserved_irqs
= {'uart': 0},
304 assert cpu
in ["libresoc", "microwatt"]
305 sys_clk_freq
= int(50e6
)
307 platform_name
= platform
308 if platform
== 'sim':
309 platform
= Platform()
310 self
.platform
.name
= 'ls180'
312 elif 'ls180' in platform
:
313 platform
= LS180Platform()
320 variant
= "ls180sram4k"
322 variant
= "ls180nopll"
324 print ("CPU, variant", platform_name
, variant
)
326 # reserve XICS ICP and XICS memory addresses.
327 self
.mem_map
['xics_icp'] = 0xc0010000
328 self
.mem_map
['xics_ics'] = 0xc0011000
329 #self.csr_map["icp"] = 8 # 8 x 0x800 == 0x4000
330 #self.csr_map["ics"] = 10 # 10 x 0x800 == 0x5000
334 #ram_init = get_mem_data({
335 # ram_fname: "0x00000000",
337 ram_init
= get_mem_data(ram_fname
, "little")
339 # remap the main RAM to reset-start-address
341 # without sram nothing works, therefore move it to higher up
342 self
.mem_map
["sram"] = 0x90000000
344 # put UART at 0xc000200 (w00t! this works!)
345 self
.csr_map
["uart"] = 4
347 self
.mem_map
["main_ram"] = 0x90000000
349 self
.mem_map
["sram"] = 0x00000000
350 self
.mem_map
["sram1"] = 0x00000200
351 self
.mem_map
["sram2"] = 0x00000400
352 self
.mem_map
["sram3"] = 0x00000600
353 self
.mem_map
["sram4"] = 0x00000800
356 sram_size
= 0x80 # ridiculously small
357 if "sram4k" not in variant
:
358 sram_size
= 0x200 # no 4k SRAMs, make slightly bigger
359 self
.mem_map
["sram"] = 0x00000000
360 self
.mem_map
["sram1"] = 0x00000700
361 self
.mem_map
["sram4k_0"] = 0x00001000
362 self
.mem_map
["sram4k_1"] = 0x00002000
363 self
.mem_map
["sram4k_2"] = 0x00003000
364 self
.mem_map
["sram4k_3"] = 0x00004000
366 # SoCCore -------------------------------------------------------------
367 SoCCore
.__init
__(self
, platform
, clk_freq
=sys_clk_freq
,
368 cpu_type
= "microwatt",
369 cpu_cls
= LibreSoC
if cpu
== "libresoc" \
371 #bus_data_width = 64, # don't add this! stops conversion
372 csr_address_width
= 13, # limit to 0x8000
373 cpu_variant
= variant
,
378 with_sdram
= with_sdram
,
379 sdram_module
= sdram_module
,
380 sdram_data_width
= sdram_data_width
,
381 integrated_rom_size
= 0, # if ram_fname else 0x10000,
382 #integrated_sram_size = 0x1000, - problem with yosys ABC
383 integrated_sram_size
= sram_size
,
384 #integrated_main_ram_init = ram_init,
385 integrated_main_ram_size
= 0x00000000 if with_sdram \
386 else 0x10000000 , # 256MB
389 self
.platform
.name
= platform_name
392 # add 4 more 4k integrated SRAMs
393 self
.add_ram("sram1", self
.mem_map
["sram1"], 0x200)
394 self
.add_ram("sram2", self
.mem_map
["sram2"], 0x200)
395 self
.add_ram("sram3", self
.mem_map
["sram3"], 0x200)
396 self
.add_ram("sram4", self
.mem_map
["sram4"], 0x200)
398 self
.add_ram("sram1", self
.mem_map
["sram1"], 0x80) # tiny!
400 # SDR SDRAM ----------------------------------------------
401 if False: # not self.integrated_main_ram_size:
402 self
.submodules
.sdrphy
= sdrphy_cls(platform
.request("sdram"))
404 if cpu
== "libresoc":
405 # XICS interrupt devices
406 icp_addr
= self
.mem_map
['xics_icp']
407 icp_wb
= self
.cpu
.xics_icp
408 icp_region
= SoCRegion(origin
=icp_addr
, size
=0x20, cached
=False)
409 self
.bus
.add_slave(name
='icp', slave
=icp_wb
, region
=icp_region
)
411 ics_addr
= self
.mem_map
['xics_ics']
412 ics_wb
= self
.cpu
.xics_ics
413 ics_region
= SoCRegion(origin
=ics_addr
, size
=0x1000, cached
=False)
414 self
.bus
.add_slave(name
='ics', slave
=ics_wb
, region
=ics_region
)
417 for i
, sram_wb
in enumerate(self
.cpu
.srams
):
418 name
= 'sram4k_%d' % i
419 sram_adr
= self
.mem_map
[name
]
420 ics_region
= SoCRegion(origin
=sram_adr
, size
=0x1000)
421 self
.bus
.add_slave(name
=name
, slave
=sram_wb
, region
=ics_region
)
423 # CRG -----------------------------------------------------------------
424 self
.submodules
.crg
= CRG(platform
.request("sys_clk"),
425 platform
.request("sys_rst"))
427 if hasattr(self
.cpu
, "clk_sel"):
429 clksel_i
= platform
.request("sys_clksel_i")
430 pll_test_o
= platform
.request("sys_pll_testout_o")
431 pll_vco_o
= platform
.request("sys_pll_vco_o")
433 self
.comb
+= self
.cpu
.clk_sel
.eq(clksel_i
) # allow clock src select
434 self
.comb
+= pll_test_o
.eq(self
.cpu
.pll_test_o
) # "test" from PLL
435 self
.comb
+= pll_vco_o
.eq(self
.cpu
.pll_vco_o
) # PLL lock flag
436 self
.comb
+= self
.cpu
.clk
.eq(self
.cpu
.pllclk_o
) # PLL out into cpu
440 # SDRAM ----------------------------------------------------
442 sdram_clk_freq
= int(100e6
) # FIXME: use 100MHz timings
443 sdram_module_cls
= getattr(litedram_modules
, sdram_module
)
444 sdram_rate
= "1:{}".format(
445 sdram_module_nphases
[sdram_module_cls
.memtype
])
446 sdram_module
= sdram_module_cls(sdram_clk_freq
, sdram_rate
)
447 phy_settings
= get_sdram_phy_settings(
448 memtype
= sdram_module
.memtype
,
449 data_width
= sdram_data_width
,
450 clk_freq
= sdram_clk_freq
)
451 #sdrphy_cls = HalfRateGENSDRPHY
452 sdrphy_cls
= GENSDRPHY
453 sdram_pads
= self
.cpu
.cpupads
['sdr']
454 self
.submodules
.sdrphy
= sdrphy_cls(sdram_pads
)
455 #self.submodules.sdrphy = sdrphy_cls(sdram_module,
459 self
.add_sdram("sdram",
461 module
= sdram_module
,
462 origin
= self
.mem_map
["main_ram"],
464 l2_cache_size
= 0, # 8192
465 l2_cache_min_data_width
= 128,
466 l2_cache_reverse
= True
468 # FIXME: skip memtest to avoid corrupting memory
469 self
.add_constant("MEMTEST_BUS_SIZE", 128//16)
470 self
.add_constant("MEMTEST_DATA_SIZE", 128//16)
471 self
.add_constant("MEMTEST_ADDR_SIZE", 128//16)
472 self
.add_constant("MEMTEST_BUS_DEBUG", 1)
473 self
.add_constant("MEMTEST_ADDR_DEBUG", 1)
474 self
.add_constant("MEMTEST_DATA_DEBUG", 1)
477 sys_clk
= ClockSignal()
478 #sdr_clk = self.cpu.cpupads['sdram_clock']
479 sdr_clk
= sdram_pads
.clock
480 #self.specials += DDROutput(1, 0, , sdram_clk)
481 self
.specials
+= SDROutput(clk
=sys_clk
, i
=sys_clk
, o
=sdr_clk
)
484 uart_core_pads
= self
.cpu
.cpupads
['uart']
485 self
.submodules
.uart_phy
= uart
.UARTPHY(
486 pads
= uart_core_pads
,
487 clk_freq
= self
.sys_clk_freq
,
489 self
.submodules
.uart
= ResetInserter()(uart
.UART(self
.uart_phy
,
493 self
.csr
.add("uart_phy", use_loc_if_exists
=True)
494 self
.csr
.add("uart", use_loc_if_exists
=True)
495 self
.irq
.add("uart", use_loc_if_exists
=True)
497 # GPIOs (bi-directional)
498 gpio_core_pads
= self
.cpu
.cpupads
['gpio']
499 self
.submodules
.gpio0
= GPIOTristateASIC("gpio0", gpio_core_pads
,
501 self
.add_csr("gpio0")
503 self
.submodules
.gpio1
= GPIOTristateASIC("gpio1", gpio_core_pads
,
505 self
.add_csr("gpio1")
508 print ("cpupadkeys", self
.cpu
.cpupads
.keys())
509 if hasattr(self
.cpu
.cpupads
, 'mspi0'):
511 pads
= self
.cpu
.cpupads
['mspi0']
512 spimaster
= SPIMaster(pads
, 8, self
.sys_clk_freq
, sd_clk_freq
)
513 spimaster
.add_clk_divider()
514 setattr(self
.submodules
, 'spimaster', spimaster
)
515 self
.add_csr('spimaster')
517 if hasattr(self
.cpu
.cpupads
, 'mspi1'):
518 # SPI SDCard (1 wide)
520 pads
= self
.cpu
.cpupads
['mspi1']
521 spisdcard
= SPIMaster(pads
, 8, self
.sys_clk_freq
, spi_clk_freq
)
522 spisdcard
.add_clk_divider()
523 setattr(self
.submodules
, 'spisdcard', spisdcard
)
524 self
.add_csr('spisdcard')
526 # EINTs - very simple, wire up top 3 bits to ls180 "eint" pins
527 eintpads
= self
.cpu
.cpupads
['eint']
528 print ("eintpads", eintpads
)
529 self
.eint_tmp
= Signal(len(eintpads
))
530 for i
in range(len(eintpads
)):
531 self
.comb
+= self
.cpu
.interrupt
[13+i
].eq(self
.eint_tmp
[i
])
532 self
.comb
+= self
.eint_tmp
[i
].eq(getattr(eintpads
, "%d" % i
))
535 jtagpads
= platform
.request("jtag")
536 self
.comb
+= self
.cpu
.jtag_tck
.eq(jtagpads
.tck
)
537 self
.comb
+= self
.cpu
.jtag_tms
.eq(jtagpads
.tms
)
538 self
.comb
+= self
.cpu
.jtag_tdi
.eq(jtagpads
.tdi
)
539 self
.comb
+= jtagpads
.tdo
.eq(self
.cpu
.jtag_tdo
)
541 # NC - allows some iopads to be connected up
542 # sigh, just do something, anything, to stop yosys optimising these out
543 nc_pads
= platform
.request("nc")
544 num_nc
= len(nc_pads
)
545 self
.nc
= Signal(num_nc
)
546 self
.comb
+= self
.nc
.eq(nc_pads
)
547 self
.dummy
= Signal(num_nc
)
548 for i
in range(num_nc
):
549 self
.sync
+= self
.dummy
[i
].eq(self
.nc
[i
] | self
.cpu
.interrupt
[0])
552 if hasattr(self
.cpu
.cpupads
, 'pwm'):
553 pwmpads
= self
.cpu
.cpupads
['pwm']
556 setattr(self
.submodules
, name
, PWM(pwmpads
[i
]))
560 i2c_core_pads
= self
.cpu
.cpupads
['mtwi']
561 self
.submodules
.i2c
= I2CMaster(i2c_core_pads
)
564 # SDCard -----------------------------------------------------
566 if hasattr(self
.cpu
.cpupads
, 'sd0'):
568 sdcard_pads
= self
.cpu
.cpupads
['sd0']
571 self
.submodules
.sdphy
= SDPHY(sdcard_pads
,
572 self
.platform
.device
, self
.clk_freq
)
573 self
.submodules
.sdcore
= SDCore(self
.sdphy
)
574 self
.add_csr("sdphy")
575 self
.add_csr("sdcore")
578 bus
= wishbone
.Interface(data_width
=self
.bus
.data_width
,
579 adr_width
=self
.bus
.address_width
)
580 self
.submodules
.sdblock2mem
= SDBlock2MemDMA(bus
=bus
,
581 endianness
=self
.cpu
.endianness
)
582 self
.comb
+= self
.sdcore
.source
.connect(self
.sdblock2mem
.sink
)
583 dma_bus
= self
.bus
if not hasattr(self
, "dma_bus") else self
.dma_bus
584 dma_bus
.add_master("sdblock2mem", master
=bus
)
585 self
.add_csr("sdblock2mem")
588 bus
= wishbone
.Interface(data_width
=self
.bus
.data_width
,
589 adr_width
=self
.bus
.address_width
)
590 self
.submodules
.sdmem2block
= SDMem2BlockDMA(bus
=bus
,
591 endianness
=self
.cpu
.endianness
)
592 self
.comb
+= self
.sdmem2block
.source
.connect(self
.sdcore
.sink
)
593 dma_bus
= self
.bus
if not hasattr(self
, "dma_bus") else self
.dma_bus
594 dma_bus
.add_master("sdmem2block", master
=bus
)
595 self
.add_csr("sdmem2block")
597 # Debug ---------------------------------------------------------------
601 jtag_en
= ('jtag' in variant
) or ('ls180' in variant
)
603 # setup running of DMI FSM
606 dmi_dout
= Signal(64)
612 dbg_dout
= Signal(64)
615 # capture pc from dmi
617 active_dbg
= Signal()
618 active_dbg_cr
= Signal()
619 active_dbg_xer
= Signal()
628 # increment counter, Stop after 100000 cycles
630 self
.sync
+= uptime
.eq(uptime
+ 1)
631 #self.sync += If(uptime == 1000000000000, Finish())
633 # DMI FSM counter and FSM itself
634 dmicount
= Signal(10)
635 dmirunning
= Signal(1)
636 dmi_monitor
= Signal(1)
638 self
.submodules
+= dmifsm
642 If(dmi_req
& dmi_wen
,
643 (self
.cpu
.dmi_addr
.eq(dmi_addr
), # DMI Addr
644 self
.cpu
.dmi_din
.eq(dmi_din
), # DMI in
645 self
.cpu
.dmi_req
.eq(1), # DMI request
646 self
.cpu
.dmi_wr
.eq(1), # DMI write
653 If(dmi_req
& ~dmi_wen
,
654 (self
.cpu
.dmi_addr
.eq(dmi_addr
), # DMI Addr
655 self
.cpu
.dmi_req
.eq(1), # DMI request
656 self
.cpu
.dmi_wr
.eq(0), # DMI read
658 # acknowledge received: capture data.
660 NextValue(dbg_addr
, dmi_addr
),
661 NextValue(dbg_dout
, self
.cpu
.dmi_dout
),
662 NextValue(dbg_msg
, 1),
669 # DMI response received: reset the dmi request and check if
673 NextState("FIRE_MONITOR"), # fire "monitor" on next cycle
675 NextState("START"), # back to start on next cycle
677 NextValue(dmi_req
, 0),
678 NextValue(dmi_addr
, 0),
679 NextValue(dmi_din
, 0),
680 NextValue(dmi_wen
, 0),
683 # "monitor" mode fires off a STAT request
684 dmifsm
.act("FIRE_MONITOR",
685 (NextValue(dmi_req
, 1),
686 NextValue(dmi_addr
, 1), # DMI STAT address
687 NextValue(dmi_din
, 0),
688 NextValue(dmi_wen
, 0), # read STAT
689 NextState("START"), # back to start on next cycle
693 self
.comb
+= xer_so
.eq((dbg_dout
& 1) == 1)
694 self
.comb
+= xer_ca
.eq((dbg_dout
& 4) == 4)
695 self
.comb
+= xer_ca32
.eq((dbg_dout
& 8) == 8)
696 self
.comb
+= xer_ov
.eq((dbg_dout
& 16) == 16)
697 self
.comb
+= xer_ov32
.eq((dbg_dout
& 32) == 32)
700 self
.sync
+= If(dbg_msg
,
701 (If(active_dbg
& (dbg_addr
== 0b10), # PC
702 Display("pc : %016x", dbg_dout
),
704 If(dbg_addr
== 0b10, # PC
705 pc
.eq(dbg_dout
), # capture PC
707 #If(dbg_addr == 0b11, # MSR
708 # Display(" msr: %016x", dbg_dout),
710 If(dbg_addr
== 0b1000, # CR
711 Display(" cr : %016x", dbg_dout
),
713 If(dbg_addr
== 0b1001, # XER
714 Display(" xer: so %d ca %d 32 %d ov %d 32 %d",
715 xer_so
, xer_ca
, xer_ca32
, xer_ov
, xer_ov32
),
717 If(dbg_addr
== 0b101, # GPR
718 Display(" gpr: %016x", dbg_dout
),
720 # also check if this is a "stat"
721 If(dbg_addr
== 1, # requested a STAT
722 #Display(" stat: %x", dbg_dout),
723 If(dbg_dout
& 2, # bit 2 of STAT is "stopped" mode
724 dmirunning
.eq(1), # continue running
725 dmi_monitor
.eq(0), # and stop monitor mode
733 self
.sync
+= If(uptime
== 0,
734 (dmi_addr
.eq(0), # CTRL
735 dmi_din
.eq(1<<0), # STOP
741 self
.sync
+= If(uptime
== 4,
745 self
.sync
+= If(dmirunning
,
746 dmicount
.eq(dmicount
+ 1),
749 # loop every 1<<N cycles
753 self
.sync
+= If(dmicount
== 4,
754 (dmi_addr
.eq(0b10), # NIA
761 self
.sync
+= If(dmicount
== 8,
762 (dmi_addr
.eq(0), # CTRL
763 dmi_din
.eq(1<<3), # STEP
766 dmirunning
.eq(0), # stop counter, need to fire "monitor"
767 dmi_monitor
.eq(1), # start "monitor" instead
771 # limit range of pc for debug reporting
772 #self.comb += active_dbg.eq((0x378c <= pc) & (pc <= 0x38d8))
773 #self.comb += active_dbg.eq((0x0 < pc) & (pc < 0x58))
774 self
.comb
+= active_dbg
.eq(1)
778 self
.sync
+= If(active_dbg
& (dmicount
== 12),
779 (dmi_addr
.eq(0b11), # MSR
785 if cpu
== "libresoc":
786 #self.comb += active_dbg_cr.eq((0x10300 <= pc) & (pc <= 0x12600))
787 self
.comb
+= active_dbg_cr
.eq(0)
790 self
.sync
+= If(active_dbg_cr
& (dmicount
== 16),
791 (dmi_addr
.eq(0b1000), # CR
797 #self.comb += active_dbg_xer.eq((0x10300 <= pc) & (pc <= 0x1094c))
798 self
.comb
+= active_dbg_xer
.eq(active_dbg_cr
)
801 self
.sync
+= If(active_dbg_xer
& (dmicount
== 20),
802 (dmi_addr
.eq(0b1001), # XER
810 self
.sync
+= If(active_dbg
& (dmicount
== 24+(i
*8)),
811 (dmi_addr
.eq(0b100), # GSPR addr
818 self
.sync
+= If(active_dbg
& (dmicount
== 28+(i
*8)),
819 (dmi_addr
.eq(0b101), # GSPR data
825 # monitor bbus read/write
826 self
.sync
+= If(active_dbg
& self
.cpu
.dbus
.stb
& self
.cpu
.dbus
.ack
,
827 Display(" [%06x] dadr: %8x, we %d s %01x w %016x r: %016x",
841 self
.sync
+= If(active_dbg
& self
.cpu
.ibus
.stb
& self
.cpu
.ibus
.ack
&
843 Display(" [%06x] iadr: %8x, s %01x w %016x",
852 self
.sync
+= If(active_dbg
& self
.cpu
.ibus
.stb
& self
.cpu
.ibus
.ack
&
854 Display(" [%06x] iadr: %8x, s %01x r %016x",
863 # Build -----------------------------------------------------------------------
866 parser
= argparse
.ArgumentParser(description
="LiteX LibreSoC CPU Sim")
867 parser
.add_argument("--cpu", default
="libresoc",
868 help="CPU to use: libresoc (default) or microwatt")
869 parser
.add_argument("--platform", default
="sim",
870 help="platform (sim or ls180)")
871 parser
.add_argument("--debug", action
="store_true",
872 help="Enable debug traces")
873 parser
.add_argument("--trace", action
="store_true",
874 help="Enable tracing")
875 parser
.add_argument("--trace-start", default
=0,
876 help="Cycle to start FST tracing")
877 parser
.add_argument("--trace-end", default
=-1,
878 help="Cycle to end FST tracing")
879 parser
.add_argument("--num-srams", default
=5,
880 help="number of srams")
881 parser
.add_argument("--srams4k", action
="store_true",
882 help="enable 4k srams")
883 parser
.add_argument("--build", action
="store_true", help="Build bitstream")
884 args
= parser
.parse_args()
886 print ("number of SRAMs", args
.num_srams
)
887 print ("enable 4K SRAMs variant", args
.srams4k
)
889 if 'ls180' in args
.platform
:
890 soc
= LibreSoCSim(cpu
=args
.cpu
, debug
=args
.debug
,
891 platform
=args
.platform
,
892 srams_4k
=args
.srams4k
,
893 dff_srams
=args
.num_srams
)
894 builder
= Builder(soc
, compile_gateware
= True)
895 builder
.build(run
= True)
899 sim_config
= SimConfig(default_clk
="sys_clk")
900 sim_config
.add_module("serial2console", "serial")
903 soc
= LibreSoCSim(cpu
=args
.cpu
, debug
=args
.debug
,
904 platform
=args
.platform
,
905 dff_srams
=args
.num_srams
)
906 builder
= Builder(soc
, compile_gateware
= i
!=0)
907 builder
.build(sim_config
=sim_config
,
910 trace_start
= int(args
.trace_start
),
911 trace_end
= int(args
.trace_end
),
915 if __name__
== "__main__":