# HACK!
from litex.soc.integration.soc import SoCCSRHandler
SoCCSRHandler.supported_address_width.append(12)
+SoCCSRHandler.supported_address_width.append(13)
# GPIO Tristate -------------------------------------------------------
# doesn't work properly.
class GPIOTristateASIC(Module, AutoCSR):
- def __init__(self, pads, prange=None):
- nbits = len(pads.oe) # hack
+ def __init__(self, name, pads, prange=None):
+ if prange is None:
+ prange = range(nbits)
+ nbits = len(prange)
+
self._oe = CSRStorage(nbits, description="GPIO Tristate(s) Control.")
self._in = CSRStatus(nbits, description="GPIO Input(s) Status.")
self._out = CSRStorage(nbits, description="GPIO Ouptut(s) Control.")
# # #
- _pads = Record( (("i", nbits),
- ("o", nbits),
- ("oe", nbits)))
- self.comb += _pads.i.eq(pads.i)
- self.comb += pads.o.eq(_pads.o)
- self.comb += pads.oe.eq(_pads.oe)
+ _pads = Record( ((name+"i", nbits),
+ (name+"o", nbits),
+ (name+"oe", nbits)))
+ _o = getattr(_pads, name+"o")
+ _oe = getattr(_pads, name+"oe")
+ _i = getattr(_pads, name+"i")
+ for j, i in enumerate(prange):
+ self.comb += _i[j].eq(pads.i[i])
+ self.comb += pads.o[i].eq(_o[j])
+ self.comb += pads.oe[i].eq(_oe[j])
- self.comb += _pads.oe.eq(self._oe.storage)
- self.comb += _pads.o.eq(self._out.storage)
- if prange is None:
- prange = range(nbits)
- for i in prange:
- self.specials += MultiReg(_pads.i[i], self._in.status[i])
+ clk = ClockSignal()
+ o = self._out.storage
+ oe = self._oe.storage
+ i = self._in.status
+ for j in range(nbits):
+ self.specials += SDROutput(clk=clk, i=oe[j], o=_oe[j])
+ self.specials += SDROutput(clk=clk, i=o[j], o=_o[j])
+ self.specials += SDRInput(clk=clk, i=_i[j], o=i[j])
+ #for i in range(nbits):
+ #self.comb += _pads.oe[i].eq(self._oe.storage[i])
+ #self.comb += _pads.o[i].eq(self._out.storage[i])
+ #self.specials += MultiReg(_pads.i[i], self._in.status[i])
# SDCard PHY IO -------------------------------------------------------
_o = getattr(pad, "%s_o" % name)
_oe = getattr(pad, "%s_oe" % name)
_i = getattr(pad, "%s_i" % name)
- self.specials += SDROutput(clk=clk, i=oe, o=_oe)
for j in range(len(_o)):
+ self.specials += SDROutput(clk=clk, i=oe, o=_oe[j])
self.specials += SDROutput(clk=clk, i=o[j], o=_o[j])
self.specials += SDRInput(clk=clk, i=_i[j], o=i[j])
self.submodules.dq = SDRPad(pads, "dq", d.wrdata, d.wrdata_en, d.rddata)
if hasattr(pads, "dm"):
+ print ("sdr pads dm len", pads.dm, len(pads.dm))
for i in range(len(pads.dm)):
- self.specials += SDROutput(i=d.wrdata_mask[i], o=pads.dm[i])
+ self.specials += SDROutput(i=d.wrdata_en&d.wrdata_mask[i],
+ o=pads.dm[i])
# DQ/DM Control Path ----------------------------------------------
rddata_en = Signal(cl + cmd_latency)
sdram_data_width = 16,
irq_reserved_irqs = {'uart': 0},
platform='sim',
+ dff_srams=5,
+ srams_4k=False,
):
assert cpu in ["libresoc", "microwatt"]
sys_clk_freq = int(50e6)
+ platform_name = platform
if platform == 'sim':
platform = Platform()
+ self.platform.name = 'ls180'
uart_name = "sim"
- elif platform == 'ls180':
+ elif 'ls180' in platform:
platform = LS180Platform()
uart_name = "uart"
#cpu_data_width = 32
cpu_data_width = 64
- variant = "ls180"
+ if srams_4k:
+ variant = "ls180sram4k"
+ else:
+ variant = "ls180nopll"
+
+ print ("CPU, variant", platform_name, variant)
# reserve XICS ICP and XICS memory addresses.
- self.mem_map['icp'] = 0xc0010000
- self.mem_map['ics'] = 0xc0011000
+ self.mem_map['xics_icp'] = 0xc0010000
+ self.mem_map['xics_ics'] = 0xc0011000
#self.csr_map["icp"] = 8 # 8 x 0x800 == 0x4000
#self.csr_map["ics"] = 10 # 10 x 0x800 == 0x5000
self.csr_map["uart"] = 4
self.mem_map["main_ram"] = 0x90000000
- self.mem_map["sram"] = 0x00000000
- self.mem_map["sram1"] = 0x00000200
- self.mem_map["sram2"] = 0x00000400
- self.mem_map["sram3"] = 0x00000600
- self.mem_map["sram4"] = 0x00000800
+ if dff_srams == 5:
+ self.mem_map["sram"] = 0x00000000
+ self.mem_map["sram1"] = 0x00000200
+ self.mem_map["sram2"] = 0x00000400
+ self.mem_map["sram3"] = 0x00000600
+ self.mem_map["sram4"] = 0x00000800
+ sram_size = 0x200
+ else:
+ sram_size = 0x80 # ridiculously small
+ if "sram4k" not in variant:
+ sram_size = 0x200 # no 4k SRAMs, make slightly bigger
+ self.mem_map["sram"] = 0x00000000
+ self.mem_map["sram1"] = 0x00000700
self.mem_map["sram4k_0"] = 0x00001000
self.mem_map["sram4k_1"] = 0x00002000
self.mem_map["sram4k_2"] = 0x00003000
cpu_type = "microwatt",
cpu_cls = LibreSoC if cpu == "libresoc" \
else Microwatt,
- bus_data_width = 64,
- csr_address_width = 14, # limit to 0x8000
+ #bus_data_width = 64, # don't add this! stops conversion
+ csr_address_width = 13, # limit to 0x8000
cpu_variant = variant,
csr_data_width = 8,
l2_size = 0,
sdram_data_width = sdram_data_width,
integrated_rom_size = 0, # if ram_fname else 0x10000,
#integrated_sram_size = 0x1000, - problem with yosys ABC
- integrated_sram_size = 0x200,
+ integrated_sram_size = sram_size,
#integrated_main_ram_init = ram_init,
integrated_main_ram_size = 0x00000000 if with_sdram \
else 0x10000000 , # 256MB
)
- self.platform.name = "ls180"
- # add 4 more 4k integrated SRAMs
- self.add_ram("sram1", self.mem_map["sram1"], 0x200)
- self.add_ram("sram2", self.mem_map["sram2"], 0x200)
- self.add_ram("sram3", self.mem_map["sram3"], 0x200)
- self.add_ram("sram4", self.mem_map["sram4"], 0x200)
+ self.platform.name = platform_name
+
+ if dff_srams == 5:
+ # add 4 more 4k integrated SRAMs
+ self.add_ram("sram1", self.mem_map["sram1"], 0x200)
+ self.add_ram("sram2", self.mem_map["sram2"], 0x200)
+ self.add_ram("sram3", self.mem_map["sram3"], 0x200)
+ self.add_ram("sram4", self.mem_map["sram4"], 0x200)
+ else:
+ self.add_ram("sram1", self.mem_map["sram1"], 0x80) # tiny!
# SDR SDRAM ----------------------------------------------
if False: # not self.integrated_main_ram_size:
if cpu == "libresoc":
# XICS interrupt devices
- icp_addr = self.mem_map['icp']
+ icp_addr = self.mem_map['xics_icp']
icp_wb = self.cpu.xics_icp
icp_region = SoCRegion(origin=icp_addr, size=0x20, cached=False)
self.bus.add_slave(name='icp', slave=icp_wb, region=icp_region)
- ics_addr = self.mem_map['ics']
+ ics_addr = self.mem_map['xics_ics']
ics_wb = self.cpu.xics_ics
ics_region = SoCRegion(origin=ics_addr, size=0x1000, cached=False)
self.bus.add_slave(name='ics', slave=ics_wb, region=ics_region)
self.submodules.crg = CRG(platform.request("sys_clk"),
platform.request("sys_rst"))
- # PLL/Clock Select
- clksel_i = platform.request("sys_clksel_i")
- pll18_o = platform.request("sys_pll_18_o")
- pll_lck_o = platform.request("sys_pll_lck_o")
+ if hasattr(self.cpu, "clk_sel"):
+ # PLL/Clock Select
+ clksel_i = platform.request("sys_clksel_i")
+ pll_test_o = platform.request("sys_pll_testout_o")
+ pll_vco_o = platform.request("sys_pll_vco_o")
- self.comb += self.cpu.clk_sel.eq(clksel_i) # allow clock src select
- self.comb += pll18_o.eq(self.cpu.pll_18_o) # "test feed" from the PLL
- self.comb += pll_lck_o.eq(self.cpu.pll_lck_o) # PLL lock flag
+ self.comb += self.cpu.clk_sel.eq(clksel_i) # allow clock src select
+ self.comb += pll_test_o.eq(self.cpu.pll_test_o) # "test" from PLL
+ self.comb += pll_vco_o.eq(self.cpu.pll_vco_o) # PLL lock flag
+ self.comb += self.cpu.clk.eq(self.cpu.pllclk_o) # PLL out into cpu
#ram_init = []
# SDRAM clock
sys_clk = ClockSignal()
- sdr_clk = self.cpu.cpupads['sdram_clock']
+ #sdr_clk = self.cpu.cpupads['sdram_clock']
+ sdr_clk = sdram_pads.clock
#self.specials += DDROutput(1, 0, , sdram_clk)
self.specials += SDROutput(clk=sys_clk, i=sys_clk, o=sdr_clk)
# GPIOs (bi-directional)
gpio_core_pads = self.cpu.cpupads['gpio']
- self.submodules.gpio = GPIOTristateASIC(gpio_core_pads, range(8))
- self.add_csr("gpio")
+ self.submodules.gpio0 = GPIOTristateASIC("gpio0", gpio_core_pads,
+ range(8))
+ self.add_csr("gpio0")
- self.submodules.gpio = GPIOTristateASIC(gpio_core_pads, range(8,16))
+ self.submodules.gpio1 = GPIOTristateASIC("gpio1", gpio_core_pads,
+ range(8, 16))
self.add_csr("gpio1")
# SPI Master
print ("cpupadkeys", self.cpu.cpupads.keys())
- self.submodules.spimaster = SPIMaster(
- pads = self.cpu.cpupads['mspi1'],
- data_width = 8,
- sys_clk_freq = sys_clk_freq,
- spi_clk_freq = 8e6,
- )
- self.add_csr("spimaster")
-
- # SPI SDCard (1 wide)
- spi_clk_freq = 400e3
- pads = self.cpu.cpupads['mspi0']
- spisdcard = SPIMaster(pads, 8, self.sys_clk_freq, spi_clk_freq)
- spisdcard.add_clk_divider()
- setattr(self.submodules, 'spisdcard', spisdcard)
- self.add_csr('spisdcard')
+ if hasattr(self.cpu.cpupads, 'mspi0'):
+ sd_clk_freq = 8e6
+ pads = self.cpu.cpupads['mspi0']
+ spimaster = SPIMaster(pads, 8, self.sys_clk_freq, sd_clk_freq)
+ spimaster.add_clk_divider()
+ setattr(self.submodules, 'spimaster', spimaster)
+ self.add_csr('spimaster')
+
+ if hasattr(self.cpu.cpupads, 'mspi1'):
+ # SPI SDCard (1 wide)
+ spi_clk_freq = 400e3
+ pads = self.cpu.cpupads['mspi1']
+ spisdcard = SPIMaster(pads, 8, self.sys_clk_freq, spi_clk_freq)
+ spisdcard.add_clk_divider()
+ setattr(self.submodules, 'spisdcard', spisdcard)
+ self.add_csr('spisdcard')
# EINTs - very simple, wire up top 3 bits to ls180 "eint" pins
eintpads = self.cpu.cpupads['eint']
print ("eintpads", eintpads)
- self.comb += self.cpu.interrupt[12:16].eq(eintpads)
+ self.eint_tmp = Signal(len(eintpads))
+ for i in range(len(eintpads)):
+ self.comb += self.cpu.interrupt[13+i].eq(self.eint_tmp[i])
+ self.comb += self.eint_tmp[i].eq(getattr(eintpads, "%d" % i))
# JTAG
jtagpads = platform.request("jtag")
self.sync += self.dummy[i].eq(self.nc[i] | self.cpu.interrupt[0])
# PWM
- pwmpads = self.cpu.cpupads['pwm']
- for i in range(2):
- name = "pwm%d" % i
- setattr(self.submodules, name, PWM(pwmpads[i]))
- self.add_csr(name)
+ if hasattr(self.cpu.cpupads, 'pwm'):
+ pwmpads = self.cpu.cpupads['pwm']
+ for i in range(2):
+ name = "pwm%d" % i
+ setattr(self.submodules, name, PWM(pwmpads[i]))
+ self.add_csr(name)
# I2C Master
i2c_core_pads = self.cpu.cpupads['mtwi']
# SDCard -----------------------------------------------------
- # Emulator / Pads
- sdcard_pads = self.cpu.cpupads['sd0']
-
- # Core
- self.submodules.sdphy = SDPHY(sdcard_pads,
- self.platform.device, self.clk_freq)
- self.submodules.sdcore = SDCore(self.sdphy)
- self.add_csr("sdphy")
- self.add_csr("sdcore")
-
- # Block2Mem DMA
- bus = wishbone.Interface(data_width=self.bus.data_width,
- adr_width=self.bus.address_width)
- self.submodules.sdblock2mem = SDBlock2MemDMA(bus=bus,
- endianness=self.cpu.endianness)
- self.comb += self.sdcore.source.connect(self.sdblock2mem.sink)
- dma_bus = self.bus if not hasattr(self, "dma_bus") else self.dma_bus
- dma_bus.add_master("sdblock2mem", master=bus)
- self.add_csr("sdblock2mem")
-
- # Mem2Block DMA
- bus = wishbone.Interface(data_width=self.bus.data_width,
- adr_width=self.bus.address_width)
- self.submodules.sdmem2block = SDMem2BlockDMA(bus=bus,
- endianness=self.cpu.endianness)
- self.comb += self.sdmem2block.source.connect(self.sdcore.sink)
- dma_bus = self.bus if not hasattr(self, "dma_bus") else self.dma_bus
- dma_bus.add_master("sdmem2block", master=bus)
- self.add_csr("sdmem2block")
+ if hasattr(self.cpu.cpupads, 'sd0'):
+ # Emulator / Pads
+ sdcard_pads = self.cpu.cpupads['sd0']
+
+ # Core
+ self.submodules.sdphy = SDPHY(sdcard_pads,
+ self.platform.device, self.clk_freq)
+ self.submodules.sdcore = SDCore(self.sdphy)
+ self.add_csr("sdphy")
+ self.add_csr("sdcore")
+
+ # Block2Mem DMA
+ bus = wishbone.Interface(data_width=self.bus.data_width,
+ adr_width=self.bus.address_width)
+ self.submodules.sdblock2mem = SDBlock2MemDMA(bus=bus,
+ endianness=self.cpu.endianness)
+ self.comb += self.sdcore.source.connect(self.sdblock2mem.sink)
+ dma_bus = self.bus if not hasattr(self, "dma_bus") else self.dma_bus
+ dma_bus.add_master("sdblock2mem", master=bus)
+ self.add_csr("sdblock2mem")
+
+ # Mem2Block DMA
+ bus = wishbone.Interface(data_width=self.bus.data_width,
+ adr_width=self.bus.address_width)
+ self.submodules.sdmem2block = SDMem2BlockDMA(bus=bus,
+ endianness=self.cpu.endianness)
+ self.comb += self.sdmem2block.source.connect(self.sdcore.sink)
+ dma_bus = self.bus if not hasattr(self, "dma_bus") else self.dma_bus
+ dma_bus.add_master("sdmem2block", master=bus)
+ self.add_csr("sdmem2block")
# Debug ---------------------------------------------------------------
if not debug:
return
- jtag_en = ('jtag' in variant) or variant == 'ls180'
+ jtag_en = ('jtag' in variant) or ('ls180' in variant)
# setup running of DMI FSM
dmi_addr = Signal(4)
help="Cycle to start FST tracing")
parser.add_argument("--trace-end", default=-1,
help="Cycle to end FST tracing")
+ parser.add_argument("--num-srams", default=5,
+ help="number of srams")
+ parser.add_argument("--srams4k", action="store_true",
+ help="enable 4k srams")
parser.add_argument("--build", action="store_true", help="Build bitstream")
args = parser.parse_args()
+ print ("number of SRAMs", args.num_srams)
+ print ("enable 4K SRAMs variant", args.srams4k)
- if args.platform == 'ls180':
+ if 'ls180' in args.platform:
soc = LibreSoCSim(cpu=args.cpu, debug=args.debug,
- platform=args.platform)
+ platform=args.platform,
+ srams_4k=args.srams4k,
+ dff_srams=args.num_srams)
builder = Builder(soc, compile_gateware = True)
builder.build(run = True)
os.chdir("../")
for i in range(2):
soc = LibreSoCSim(cpu=args.cpu, debug=args.debug,
- platform=args.platform)
+ platform=args.platform,
+ dff_srams=args.num_srams)
builder = Builder(soc, compile_gateware = i!=0)
builder.build(sim_config=sim_config,
run = i!=0,