X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=ls180soc.py;h=a24083977bc4123de781c606d90f9740d340ccc9;hb=dbc42a5cf0453f5e9f7f0ec2a042f785c48e2a4a;hp=3224f6d1b1ceb3a441561f726352d44c9f8395c2;hpb=c2808c908523d44211057913b68c3e24b8bf74bf;p=libresoc-litex.git diff --git a/ls180soc.py b/ls180soc.py index 3224f6d..a240839 100755 --- a/ls180soc.py +++ b/ls180soc.py @@ -43,6 +43,7 @@ from microwatt import Microwatt # 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. @@ -99,27 +100,40 @@ class I2CMaster(Module, AutoCSR): 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 ------------------------------------------------------- @@ -129,8 +143,8 @@ class SDRPad(Module): _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]) @@ -263,8 +277,10 @@ class GENSDRPHY(Module): 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) @@ -282,25 +298,34 @@ class LibreSoCSim(SoCCore): 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 @@ -320,11 +345,19 @@ class LibreSoCSim(SoCCore): 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 @@ -335,8 +368,8 @@ class LibreSoCSim(SoCCore): 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, @@ -347,18 +380,22 @@ class LibreSoCSim(SoCCore): 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: @@ -366,12 +403,12 @@ class LibreSoCSim(SoCCore): 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) @@ -387,14 +424,16 @@ class LibreSoCSim(SoCCore): 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 = [] @@ -436,7 +475,8 @@ class LibreSoCSim(SoCCore): # 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) @@ -456,34 +496,40 @@ class LibreSoCSim(SoCCore): # 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") @@ -503,11 +549,12 @@ class LibreSoCSim(SoCCore): 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'] @@ -516,41 +563,42 @@ class LibreSoCSim(SoCCore): # 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) @@ -828,13 +876,21 @@ def main(): 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("../") @@ -845,7 +901,8 @@ def main(): 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,