41979267086168976132457e1423f239a625d4a6
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"] = 0x00001000
325 self
.mem_map
["sram2"] = 0x00002000
326 self
.mem_map
["sram3"] = 0x00003000
328 # SoCCore -------------------------------------------------------------
329 SoCCore
.__init
__(self
, platform
, clk_freq
=sys_clk_freq
,
330 cpu_type
= "microwatt",
331 cpu_cls
= LibreSoC
if cpu
== "libresoc" \
334 csr_address_width
= 14, # limit to 0x8000
335 cpu_variant
= variant
,
340 with_sdram
= with_sdram
,
341 sdram_module
= sdram_module
,
342 sdram_data_width
= sdram_data_width
,
343 integrated_rom_size
= 0, # if ram_fname else 0x10000,
344 #integrated_sram_size = 0x1000, - problem with yosys ABC
345 integrated_sram_size
= 0x200,
346 #integrated_main_ram_init = ram_init,
347 integrated_main_ram_size
= 0x00000000 if with_sdram \
348 else 0x10000000 , # 256MB
350 self
.platform
.name
= "ls180"
352 # add 3 more 4k integrated SRAMs
353 self
.add_ram("sram1", self
.mem_map
["sram1"], 0x200)
354 self
.add_ram("sram2", self
.mem_map
["sram2"], 0x200)
355 self
.add_ram("sram3", self
.mem_map
["sram3"], 0x200)
357 # SDR SDRAM ----------------------------------------------
358 if False: # not self.integrated_main_ram_size:
359 self
.submodules
.sdrphy
= sdrphy_cls(platform
.request("sdram"))
361 if cpu
== "libresoc":
362 # XICS interrupt devices
363 icp_addr
= self
.mem_map
['icp']
364 icp_wb
= self
.cpu
.xics_icp
365 icp_region
= SoCRegion(origin
=icp_addr
, size
=0x20, cached
=False)
366 self
.bus
.add_slave(name
='icp', slave
=icp_wb
, region
=icp_region
)
368 ics_addr
= self
.mem_map
['ics']
369 ics_wb
= self
.cpu
.xics_ics
370 ics_region
= SoCRegion(origin
=ics_addr
, size
=0x1000, cached
=False)
371 self
.bus
.add_slave(name
='ics', slave
=ics_wb
, region
=ics_region
)
373 # CRG -----------------------------------------------------------------
374 self
.submodules
.crg
= CRG(platform
.request("sys_clk"),
375 platform
.request("sys_rst"))
378 clksel_i
= platform
.request("sys_clksel_i")
379 pll18_o
= platform
.request("sys_pll_18_o")
380 pll_lck_o
= platform
.request("sys_pll_lck_o")
382 self
.comb
+= self
.cpu
.clk_sel
.eq(clksel_i
) # allow clock src select
383 self
.comb
+= pll18_o
.eq(self
.cpu
.pll_18_o
) # "test feed" from the PLL
384 self
.comb
+= pll_lck_o
.eq(self
.cpu
.pll_lck_o
) # PLL lock flag
388 # SDRAM ----------------------------------------------------
390 sdram_clk_freq
= int(100e6
) # FIXME: use 100MHz timings
391 sdram_module_cls
= getattr(litedram_modules
, sdram_module
)
392 sdram_rate
= "1:{}".format(
393 sdram_module_nphases
[sdram_module_cls
.memtype
])
394 sdram_module
= sdram_module_cls(sdram_clk_freq
, sdram_rate
)
395 phy_settings
= get_sdram_phy_settings(
396 memtype
= sdram_module
.memtype
,
397 data_width
= sdram_data_width
,
398 clk_freq
= sdram_clk_freq
)
399 #sdrphy_cls = HalfRateGENSDRPHY
400 sdrphy_cls
= GENSDRPHY
401 sdram_pads
= self
.cpu
.cpupads
['sdr']
402 self
.submodules
.sdrphy
= sdrphy_cls(sdram_pads
)
403 #self.submodules.sdrphy = sdrphy_cls(sdram_module,
407 self
.add_sdram("sdram",
409 module
= sdram_module
,
410 origin
= self
.mem_map
["main_ram"],
412 l2_cache_size
= 0, # 8192
413 l2_cache_min_data_width
= 128,
414 l2_cache_reverse
= True
416 # FIXME: skip memtest to avoid corrupting memory
417 self
.add_constant("MEMTEST_BUS_SIZE", 128//16)
418 self
.add_constant("MEMTEST_DATA_SIZE", 128//16)
419 self
.add_constant("MEMTEST_ADDR_SIZE", 128//16)
420 self
.add_constant("MEMTEST_BUS_DEBUG", 1)
421 self
.add_constant("MEMTEST_ADDR_DEBUG", 1)
422 self
.add_constant("MEMTEST_DATA_DEBUG", 1)
425 sys_clk
= ClockSignal()
426 sdr_clk
= self
.cpu
.cpupads
['sdram_clock']
427 #self.specials += DDROutput(1, 0, , sdram_clk)
428 self
.specials
+= SDROutput(clk
=sys_clk
, i
=sys_clk
, o
=sdr_clk
)
431 uart_core_pads
= self
.cpu
.cpupads
['uart']
432 self
.submodules
.uart_phy
= uart
.UARTPHY(
433 pads
= uart_core_pads
,
434 clk_freq
= self
.sys_clk_freq
,
436 self
.submodules
.uart
= ResetInserter()(uart
.UART(self
.uart_phy
,
440 self
.csr
.add("uart_phy", use_loc_if_exists
=True)
441 self
.csr
.add("uart", use_loc_if_exists
=True)
442 self
.irq
.add("uart", use_loc_if_exists
=True)
444 # GPIOs (bi-directional)
445 gpio_core_pads
= self
.cpu
.cpupads
['gpio']
446 self
.submodules
.gpio
= GPIOTristateASIC(gpio_core_pads
, range(8))
449 self
.submodules
.gpio
= GPIOTristateASIC(gpio_core_pads
, range(8,16))
450 self
.add_csr("gpio1")
453 print ("cpupadkeys", self
.cpu
.cpupads
.keys())
454 self
.submodules
.spimaster
= SPIMaster(
455 pads
= self
.cpu
.cpupads
['mspi1'],
457 sys_clk_freq
= sys_clk_freq
,
460 self
.add_csr("spimaster")
462 # SPI SDCard (1 wide)
464 pads
= self
.cpu
.cpupads
['mspi0']
465 spisdcard
= SPIMaster(pads
, 8, self
.sys_clk_freq
, spi_clk_freq
)
466 spisdcard
.add_clk_divider()
467 setattr(self
.submodules
, 'spisdcard', spisdcard
)
468 self
.add_csr('spisdcard')
470 # EINTs - very simple, wire up top 3 bits to ls180 "eint" pins
471 eintpads
= self
.cpu
.cpupads
['eint']
472 print ("eintpads", eintpads
)
473 self
.comb
+= self
.cpu
.interrupt
[12:16].eq(eintpads
)
476 jtagpads
= platform
.request("jtag")
477 self
.comb
+= self
.cpu
.jtag_tck
.eq(jtagpads
.tck
)
478 self
.comb
+= self
.cpu
.jtag_tms
.eq(jtagpads
.tms
)
479 self
.comb
+= self
.cpu
.jtag_tdi
.eq(jtagpads
.tdi
)
480 self
.comb
+= jtagpads
.tdo
.eq(self
.cpu
.jtag_tdo
)
482 # NC - allows some iopads to be connected up
483 # sigh, just do something, anything, to stop yosys optimising these out
484 nc_pads
= platform
.request("nc")
485 num_nc
= len(nc_pads
)
486 self
.nc
= Signal(num_nc
)
487 self
.comb
+= self
.nc
.eq(nc_pads
)
488 self
.dummy
= Signal(num_nc
)
489 for i
in range(num_nc
):
490 self
.sync
+= self
.dummy
[i
].eq(self
.nc
[i
] | self
.cpu
.interrupt
[0])
493 pwmpads
= self
.cpu
.cpupads
['pwm']
496 setattr(self
.submodules
, name
, PWM(pwmpads
[i
]))
500 i2c_core_pads
= self
.cpu
.cpupads
['mtwi']
501 self
.submodules
.i2c
= I2CMaster(i2c_core_pads
)
504 # SDCard -----------------------------------------------------
507 sdcard_pads
= self
.cpu
.cpupads
['sd0']
510 self
.submodules
.sdphy
= SDPHY(sdcard_pads
,
511 self
.platform
.device
, self
.clk_freq
)
512 self
.submodules
.sdcore
= SDCore(self
.sdphy
)
513 self
.add_csr("sdphy")
514 self
.add_csr("sdcore")
517 bus
= wishbone
.Interface(data_width
=self
.bus
.data_width
,
518 adr_width
=self
.bus
.address_width
)
519 self
.submodules
.sdblock2mem
= SDBlock2MemDMA(bus
=bus
,
520 endianness
=self
.cpu
.endianness
)
521 self
.comb
+= self
.sdcore
.source
.connect(self
.sdblock2mem
.sink
)
522 dma_bus
= self
.bus
if not hasattr(self
, "dma_bus") else self
.dma_bus
523 dma_bus
.add_master("sdblock2mem", master
=bus
)
524 self
.add_csr("sdblock2mem")
527 bus
= wishbone
.Interface(data_width
=self
.bus
.data_width
,
528 adr_width
=self
.bus
.address_width
)
529 self
.submodules
.sdmem2block
= SDMem2BlockDMA(bus
=bus
,
530 endianness
=self
.cpu
.endianness
)
531 self
.comb
+= self
.sdmem2block
.source
.connect(self
.sdcore
.sink
)
532 dma_bus
= self
.bus
if not hasattr(self
, "dma_bus") else self
.dma_bus
533 dma_bus
.add_master("sdmem2block", master
=bus
)
534 self
.add_csr("sdmem2block")
536 # Debug ---------------------------------------------------------------
540 jtag_en
= ('jtag' in variant
) or variant
== 'ls180'
542 # setup running of DMI FSM
545 dmi_dout
= Signal(64)
551 dbg_dout
= Signal(64)
554 # capture pc from dmi
556 active_dbg
= Signal()
557 active_dbg_cr
= Signal()
558 active_dbg_xer
= Signal()
567 # increment counter, Stop after 100000 cycles
569 self
.sync
+= uptime
.eq(uptime
+ 1)
570 #self.sync += If(uptime == 1000000000000, Finish())
572 # DMI FSM counter and FSM itself
573 dmicount
= Signal(10)
574 dmirunning
= Signal(1)
575 dmi_monitor
= Signal(1)
577 self
.submodules
+= dmifsm
581 If(dmi_req
& dmi_wen
,
582 (self
.cpu
.dmi_addr
.eq(dmi_addr
), # DMI Addr
583 self
.cpu
.dmi_din
.eq(dmi_din
), # DMI in
584 self
.cpu
.dmi_req
.eq(1), # DMI request
585 self
.cpu
.dmi_wr
.eq(1), # DMI write
592 If(dmi_req
& ~dmi_wen
,
593 (self
.cpu
.dmi_addr
.eq(dmi_addr
), # DMI Addr
594 self
.cpu
.dmi_req
.eq(1), # DMI request
595 self
.cpu
.dmi_wr
.eq(0), # DMI read
597 # acknowledge received: capture data.
599 NextValue(dbg_addr
, dmi_addr
),
600 NextValue(dbg_dout
, self
.cpu
.dmi_dout
),
601 NextValue(dbg_msg
, 1),
608 # DMI response received: reset the dmi request and check if
612 NextState("FIRE_MONITOR"), # fire "monitor" on next cycle
614 NextState("START"), # back to start on next cycle
616 NextValue(dmi_req
, 0),
617 NextValue(dmi_addr
, 0),
618 NextValue(dmi_din
, 0),
619 NextValue(dmi_wen
, 0),
622 # "monitor" mode fires off a STAT request
623 dmifsm
.act("FIRE_MONITOR",
624 (NextValue(dmi_req
, 1),
625 NextValue(dmi_addr
, 1), # DMI STAT address
626 NextValue(dmi_din
, 0),
627 NextValue(dmi_wen
, 0), # read STAT
628 NextState("START"), # back to start on next cycle
632 self
.comb
+= xer_so
.eq((dbg_dout
& 1) == 1)
633 self
.comb
+= xer_ca
.eq((dbg_dout
& 4) == 4)
634 self
.comb
+= xer_ca32
.eq((dbg_dout
& 8) == 8)
635 self
.comb
+= xer_ov
.eq((dbg_dout
& 16) == 16)
636 self
.comb
+= xer_ov32
.eq((dbg_dout
& 32) == 32)
639 self
.sync
+= If(dbg_msg
,
640 (If(active_dbg
& (dbg_addr
== 0b10), # PC
641 Display("pc : %016x", dbg_dout
),
643 If(dbg_addr
== 0b10, # PC
644 pc
.eq(dbg_dout
), # capture PC
646 #If(dbg_addr == 0b11, # MSR
647 # Display(" msr: %016x", dbg_dout),
649 If(dbg_addr
== 0b1000, # CR
650 Display(" cr : %016x", dbg_dout
),
652 If(dbg_addr
== 0b1001, # XER
653 Display(" xer: so %d ca %d 32 %d ov %d 32 %d",
654 xer_so
, xer_ca
, xer_ca32
, xer_ov
, xer_ov32
),
656 If(dbg_addr
== 0b101, # GPR
657 Display(" gpr: %016x", dbg_dout
),
659 # also check if this is a "stat"
660 If(dbg_addr
== 1, # requested a STAT
661 #Display(" stat: %x", dbg_dout),
662 If(dbg_dout
& 2, # bit 2 of STAT is "stopped" mode
663 dmirunning
.eq(1), # continue running
664 dmi_monitor
.eq(0), # and stop monitor mode
672 self
.sync
+= If(uptime
== 0,
673 (dmi_addr
.eq(0), # CTRL
674 dmi_din
.eq(1<<0), # STOP
680 self
.sync
+= If(uptime
== 4,
684 self
.sync
+= If(dmirunning
,
685 dmicount
.eq(dmicount
+ 1),
688 # loop every 1<<N cycles
692 self
.sync
+= If(dmicount
== 4,
693 (dmi_addr
.eq(0b10), # NIA
700 self
.sync
+= If(dmicount
== 8,
701 (dmi_addr
.eq(0), # CTRL
702 dmi_din
.eq(1<<3), # STEP
705 dmirunning
.eq(0), # stop counter, need to fire "monitor"
706 dmi_monitor
.eq(1), # start "monitor" instead
710 # limit range of pc for debug reporting
711 #self.comb += active_dbg.eq((0x378c <= pc) & (pc <= 0x38d8))
712 #self.comb += active_dbg.eq((0x0 < pc) & (pc < 0x58))
713 self
.comb
+= active_dbg
.eq(1)
717 self
.sync
+= If(active_dbg
& (dmicount
== 12),
718 (dmi_addr
.eq(0b11), # MSR
724 if cpu
== "libresoc":
725 #self.comb += active_dbg_cr.eq((0x10300 <= pc) & (pc <= 0x12600))
726 self
.comb
+= active_dbg_cr
.eq(0)
729 self
.sync
+= If(active_dbg_cr
& (dmicount
== 16),
730 (dmi_addr
.eq(0b1000), # CR
736 #self.comb += active_dbg_xer.eq((0x10300 <= pc) & (pc <= 0x1094c))
737 self
.comb
+= active_dbg_xer
.eq(active_dbg_cr
)
740 self
.sync
+= If(active_dbg_xer
& (dmicount
== 20),
741 (dmi_addr
.eq(0b1001), # XER
749 self
.sync
+= If(active_dbg
& (dmicount
== 24+(i
*8)),
750 (dmi_addr
.eq(0b100), # GSPR addr
757 self
.sync
+= If(active_dbg
& (dmicount
== 28+(i
*8)),
758 (dmi_addr
.eq(0b101), # GSPR data
764 # monitor bbus read/write
765 self
.sync
+= If(active_dbg
& self
.cpu
.dbus
.stb
& self
.cpu
.dbus
.ack
,
766 Display(" [%06x] dadr: %8x, we %d s %01x w %016x r: %016x",
780 self
.sync
+= If(active_dbg
& self
.cpu
.ibus
.stb
& self
.cpu
.ibus
.ack
&
782 Display(" [%06x] iadr: %8x, s %01x w %016x",
791 self
.sync
+= If(active_dbg
& self
.cpu
.ibus
.stb
& self
.cpu
.ibus
.ack
&
793 Display(" [%06x] iadr: %8x, s %01x r %016x",
802 # Build -----------------------------------------------------------------------
805 parser
= argparse
.ArgumentParser(description
="LiteX LibreSoC CPU Sim")
806 parser
.add_argument("--cpu", default
="libresoc",
807 help="CPU to use: libresoc (default) or microwatt")
808 parser
.add_argument("--platform", default
="sim",
809 help="platform (sim or ls180)")
810 parser
.add_argument("--debug", action
="store_true",
811 help="Enable debug traces")
812 parser
.add_argument("--trace", action
="store_true",
813 help="Enable tracing")
814 parser
.add_argument("--trace-start", default
=0,
815 help="Cycle to start FST tracing")
816 parser
.add_argument("--trace-end", default
=-1,
817 help="Cycle to end FST tracing")
818 parser
.add_argument("--build", action
="store_true", help="Build bitstream")
819 args
= parser
.parse_args()
822 if args
.platform
== 'ls180':
823 soc
= LibreSoCSim(cpu
=args
.cpu
, debug
=args
.debug
,
824 platform
=args
.platform
)
825 builder
= Builder(soc
, compile_gateware
= True)
826 builder
.build(run
= True)
830 sim_config
= SimConfig(default_clk
="sys_clk")
831 sim_config
.add_module("serial2console", "serial")
834 soc
= LibreSoCSim(cpu
=args
.cpu
, debug
=args
.debug
,
835 platform
=args
.platform
)
836 builder
= Builder(soc
, compile_gateware
= i
!=0)
837 builder
.build(sim_config
=sim_config
,
840 trace_start
= int(args
.trace_start
),
841 trace_end
= int(args
.trace_end
),
845 if __name__
== "__main__":