From 675616493c12c3a28693f009e1aa249188b5ad8b Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Sun, 20 Jun 2021 22:25:49 +0200 Subject: [PATCH 1/4] platform/1bitsquare_icebreaker: Add possible USB pinouts The pin outs come from LUNA : https://github.com/greatscottgadgets/luna/blob/main/luna/gateware/platform/icebreaker.py#L94 and are some commonly used ones from other projects / pmods. Signed-off-by: Sylvain Munaut --- .../platforms/1bitsquared_icebreaker.py | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/litex_boards/platforms/1bitsquared_icebreaker.py b/litex_boards/platforms/1bitsquared_icebreaker.py index 4f62709..176fe72 100644 --- a/litex_boards/platforms/1bitsquared_icebreaker.py +++ b/litex_boards/platforms/1bitsquared_icebreaker.py @@ -96,6 +96,42 @@ dvi_pmod = [ ) ] +usb_pmod_1a = [ + ("usb", 0, + Subsignal("d_p", Pins("PMOD1A:2")), + Subsignal("d_n", Pins("PMOD1A:3")), + Subsignal("pullup", Pins("PMOD1A:0")), + IOStandard("LVCMOS33"), + ) +] + +usb_pmod_1b = [ + ("usb", 0, + Subsignal("d_p", Pins("PMOD1B:2")), + Subsignal("d_n", Pins("PMOD1B:3")), + Subsignal("pullup", Pins("PMOD1B:0")), + IOStandard("LVCMOS33"), + ) +] + +usb_tnt = [ + ("usb", 0, + Subsignal("d_p", Pins("PMOD1B:3")), + Subsignal("d_n", Pins("PMOD1B:2")), + Subsignal("pullup", Pins("PMOD1B:1")), + IOStandard("LVCMOS33"), + ) +] + +usb_keckmann = [ + ("usb", 0, + Subsignal("d_p", Pins("PMOD1B:0")), + Subsignal("d_n", Pins("PMOD1B:1")), + Subsignal("pullup", Pins("PMOD1B:2")), + IOStandard("LVCMOS33"), + ) +] + # Platform ----------------------------------------------------------------------------------------- class Platform(LatticePlatform): From 4c758dc0e3a0d4ace47ff870f205324c3ab3b9aa Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Mon, 21 Jun 2021 16:16:47 +0200 Subject: [PATCH 2/4] platforms/1bitsquared_icebreaker: Fix wrong URL in header Signed-off-by: Sylvain Munaut --- litex_boards/platforms/1bitsquared_icebreaker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/litex_boards/platforms/1bitsquared_icebreaker.py b/litex_boards/platforms/1bitsquared_icebreaker.py index 176fe72..1122cd0 100644 --- a/litex_boards/platforms/1bitsquared_icebreaker.py +++ b/litex_boards/platforms/1bitsquared_icebreaker.py @@ -7,7 +7,7 @@ # iCEBreaker FPGA: # - Crowd Supply campaign: https://www.crowdsupply.com/1bitsquared/icebreaker # - 1BitSquared Store: https://1bitsquared.com/products/icebreaker -# - Design files: https://github.com/icebreaker/icebreaker +# - Design files: https://github.com/icebreaker-fpga/icebreaker from litex.build.generic_platform import * from litex.build.lattice import LatticePlatform From 2ebcb4a726e7e3fd5236537a8e5d7b649b412419 Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Mon, 21 Jun 2021 16:17:54 +0200 Subject: [PATCH 3/4] platforms: Add new 1bitsquared_icebreaker_bitsy platform Signed-off-by: Sylvain Munaut --- .../platforms/1bitsquared_icebreaker_bitsy.py | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 litex_boards/platforms/1bitsquared_icebreaker_bitsy.py diff --git a/litex_boards/platforms/1bitsquared_icebreaker_bitsy.py b/litex_boards/platforms/1bitsquared_icebreaker_bitsy.py new file mode 100644 index 0000000..647bf02 --- /dev/null +++ b/litex_boards/platforms/1bitsquared_icebreaker_bitsy.py @@ -0,0 +1,140 @@ +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2020 Piotr Esden-Tempski +# Copyright (c) 2021 Sylvain Munaut +# SPDX-License-Identifier: BSD-2-Clause + +# iCEBreaker Bitsy FPGA: +# - 1BitSquared Store: https://1bitsquared.com/collections/fpga/products/icebreaker-bitsy +# - Design files: https://github.com/icebreaker-fpga/icebreaker + +from litex.build.dfu import DFUProg +from litex.build.generic_platform import * +from litex.build.lattice import LatticePlatform + +# IOs ---------------------------------------------------------------------------------------------- + +_io_v0 = [ + # Clk / Rst + ("clk12", 0, Pins("35"), IOStandard("LVCMOS33")), + + # Leds + ("user_led_n", 0, Pins("11"), IOStandard("LVCMOS33")), + ("user_led_n", 1, Pins("37"), IOStandard("LVCMOS33")), + + ("user_ledr_n", 0, Pins("11"), IOStandard("LVCMOS33")), # Color-specific alias + ("user_ledg_n", 0, Pins("37"), IOStandard("LVCMOS33")), # Color-specific alias + + # Button + ("user_btn_n", 0, Pins("10"), IOStandard("LVCMOS33")), + + # USB + ("usb", 0, + Subsignal("d_p", Pins("43")), + Subsignal("d_n", Pins("42")), + Subsignal("pullup", Pins("38")), + IOStandard("LVCMOS33") + ), + + # Serial + ("serial", 0, + Subsignal("rx", Pins("18")), + Subsignal("tx", Pins("19"), Misc("PULLUP")), + IOStandard("LVCMOS33") + ), + + # SPIFlash + ("spiflash", 0, + Subsignal("cs_n", Pins("16"), IOStandard("LVCMOS33")), + Subsignal("clk", Pins("15"), IOStandard("LVCMOS33")), + Subsignal("miso", Pins("17"), IOStandard("LVCMOS33")), + Subsignal("mosi", Pins("14"), IOStandard("LVCMOS33")), + Subsignal("wp", Pins("12"), IOStandard("LVCMOS33")), + Subsignal("hold", Pins("13"), IOStandard("LVCMOS33")), + ), + ("spiflash4x", 0, + Subsignal("cs_n", Pins("16"), IOStandard("LVCMOS33")), + Subsignal("clk", Pins("15"), IOStandard("LVCMOS33")), + Subsignal("dq", Pins("14 17 12 13"), IOStandard("LVCMOS33")), + ), +] + +_io_v1 = [ + # Clk / Rst + ("clk12", 0, Pins("35"), IOStandard("LVCMOS33")), + + # Leds + ("user_led_n", 0, Pins("25"), IOStandard("LVCMOS33")), + ("user_led_n", 1, Pins( "6"), IOStandard("LVCMOS33")), + + ("user_ledr_n", 0, Pins("25"), IOStandard("LVCMOS33")), # Color-specific alias + ("user_ledg_n", 0, Pins( "6"), IOStandard("LVCMOS33")), # Color-specific alias + + # Button + ("user_btn_n", 0, Pins( "2"), IOStandard("LVCMOS33")), + + # USB + ("usb", 0, + Subsignal("d_p", Pins("42")), + Subsignal("d_n", Pins("38")), + Subsignal("pullup", Pins("37")), + IOStandard("LVCMOS33") + ), + + # Serial + ("serial", 0, + Subsignal("rx", Pins("47")), + Subsignal("tx", Pins("44"), Misc("PULLUP")), + IOStandard("LVCMOS33") + ), + + # SPIFlash + ("spiflash", 0, + Subsignal("cs_n", Pins("16"), IOStandard("LVCMOS33")), + Subsignal("clk", Pins("15"), IOStandard("LVCMOS33")), + Subsignal("miso", Pins("17"), IOStandard("LVCMOS33")), + Subsignal("mosi", Pins("14"), IOStandard("LVCMOS33")), + Subsignal("wp", Pins("18"), IOStandard("LVCMOS33")), + Subsignal("hold", Pins("19"), IOStandard("LVCMOS33")), + ), + ("spiflash4x", 0, + Subsignal("cs_n", Pins("16"), IOStandard("LVCMOS33")), + Subsignal("clk", Pins("15"), IOStandard("LVCMOS33")), + Subsignal("dq", Pins("14 17 18 19"), IOStandard("LVCMOS33")), + ), +] + +# Connectors --------------------------------------------------------------------------------------- + +_connectors_v0 = [ +] + +_connectors_v1 = [ + ("PIN", "47 44 48 45 4 3 9 10 11 12 21 13 20 25 23 27 26 28 31 32 34 36 43 46"), + ("PMOD1", "47 48 4 9 44 45 3 10"), + ("PMOD2", "43 32 26 28 36 31 27 34"), + ("PMOD3", "23 12 13 11 25 21 20 46") +] + + +# Platform ----------------------------------------------------------------------------------------- + +class Platform(LatticePlatform): + default_clk_name = "clk12" + default_clk_period = 1e9/12e6 + + def __init__(self, revision="v1", toolchain="icestorm"): + assert revision in ["v0", "v1"] + io, connectors = { + "v0": (_io_v0, _connectors_v0), + "v1": (_io_v1, _connectors_v1), + }[revision] + LatticePlatform.__init__(self, "ice40-up5k-sg48", io, connectors, toolchain=toolchain) + + def create_programmer(self): + return DFUProg(vid="1d50", pid="6146") + + def do_finalize(self, fragment): + LatticePlatform.do_finalize(self, fragment) + self.add_period_constraint(self.lookup_request("clk12", loose=True), 1e9/12e6) From 87cd56d1879185ec763ef7dc8c07fd4d0bf0b465 Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Mon, 21 Jun 2021 22:11:53 +0200 Subject: [PATCH 4/4] targets: Add new 1bitsquared_icebreaker_bitsy target Most basic SoC ever but ... it runs Signed-off-by: Sylvain Munaut --- .../targets/1bitsquared_icebreaker_bitsy.py | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100755 litex_boards/targets/1bitsquared_icebreaker_bitsy.py diff --git a/litex_boards/targets/1bitsquared_icebreaker_bitsy.py b/litex_boards/targets/1bitsquared_icebreaker_bitsy.py new file mode 100755 index 0000000..bf46cf3 --- /dev/null +++ b/litex_boards/targets/1bitsquared_icebreaker_bitsy.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python3 + +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2019 Sean Cross +# Copyright (c) 2018 David Shah +# Copyright (c) 2020 Piotr Esden-Tempski +# Copyright (c) 2020 Florent Kermarrec +# Copyright (c) 2021 Sylvain Munaut +# SPDX-License-Identifier: BSD-2-Clause + +# This target file provides a minimal LiteX SoC for the iCEBreaker-bitsy with a CPU, +# its ROM (in SPI Flash), its SRAM, close to the others LiteX targets. +# For more complete example of LiteX SoC for the iCEBreaker-bitsy with more features and +# documentation can be found, refer to : +# https://github.com/icebreaker-fpga/icebreaker-litex-examples + +import os +import argparse + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + +from litex_boards.platforms import icebreaker_bitsy + +from litex.soc.cores.ram import Up5kSPRAM +from litex.soc.cores.spi_flash import SpiFlash +from litex.soc.cores.clock import iCE40PLL +from litex.soc.integration.soc_core import * +from litex.soc.integration.soc import SoCRegion +from litex.soc.integration.builder import * + +kB = 1024 +mB = 1024*kB + +# CRG ---------------------------------------------------------------------------------------------- + +class _CRG(Module): + def __init__(self, platform, sys_clk_freq): + self.rst = Signal() + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_por = ClockDomain(reset_less=True) + + # # # + + # Clk/Rst + clk12 = platform.request("clk12") + rst_n = platform.request("user_btn_n") + + # Power On Reset + por_count = Signal(16, reset=2**16-1) + por_done = Signal() + self.comb += self.cd_por.clk.eq(ClockSignal()) + self.comb += por_done.eq(por_count == 0) + self.sync.por += If(~por_done, por_count.eq(por_count - 1)) + + # PLL + self.submodules.pll = pll = iCE40PLL(primitive="SB_PLL40_PAD") + self.comb += pll.reset.eq(~rst_n) # FIXME: Add proper iCE40PLL reset support and add back | self.rst. + pll.register_clkin(clk12, 12e6) + pll.create_clkout(self.cd_sys, sys_clk_freq, with_reset=False) + self.specials += AsyncResetSynchronizer(self.cd_sys, ~por_done | ~pll.locked) + platform.add_period_constraint(self.cd_sys.clk, 1e9/sys_clk_freq) + +# BaseSoC ------------------------------------------------------------------------------------------ + +class BaseSoC(SoCCore): + mem_map = {**SoCCore.mem_map, **{"spiflash": 0x80000000}} + def __init__(self, bios_flash_offset, sys_clk_freq=int(24e6), revision="v1", **kwargs): + platform = icebreaker_bitsy.Platform(revision=revision) + + # Disable Integrated ROM/SRAM since too large for iCE40 and UP5K has specific SPRAM. + kwargs["integrated_sram_size"] = 0 + kwargs["integrated_rom_size"] = 0 + + # Set CPU variant / reset address + kwargs["cpu_reset_address"] = self.mem_map["spiflash"] + bios_flash_offset + + # SoCCore ---------------------------------------------------------------------------------- + SoCCore.__init__(self, platform, sys_clk_freq, + ident = "LiteX SoC on iCEBreaker-bitsy", + ident_version = True, + **kwargs) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + + # 128KB SPRAM (used as SRAM) --------------------------------------------------------------- + self.submodules.spram = Up5kSPRAM(size=128*kB) + self.bus.add_slave("sram", self.spram.bus, SoCRegion(size=128*kB)) + + # SPI Flash -------------------------------------------------------------------------------- + self.add_spi_flash(mode="1x", dummy_cycles=8) + + # Add ROM linker region -------------------------------------------------------------------- + self.bus.add_region("rom", SoCRegion( + origin = self.mem_map["spiflash"] + bios_flash_offset, + size = 32*kB, + linker = True) + ) + +# Build -------------------------------------------------------------------------------------------- + +def main(): + parser = argparse.ArgumentParser(description="LiteX SoC on iCEBreaker") + parser.add_argument("--build", action="store_true", help="Build bitstream") + parser.add_argument("--flash", action="store_true", help="Flash bitstream and bios") + parser.add_argument("--sys-clk-freq", default=24e6, help="System clock frequency (default: 24MHz)") + parser.add_argument("--bios-flash-offset", default=0xa0000, help="BIOS offset in SPI Flash (default: 0xa0000)") + parser.add_argument("--revision", default="v1", help="Board revision 'v0' or 'v1'") + builder_args(parser) + soc_core_args(parser) + args = parser.parse_args() + + soc = BaseSoC( + bios_flash_offset = args.bios_flash_offset, + sys_clk_freq = int(float(args.sys_clk_freq)), + revision = args.revision, + **soc_core_argdict(args) + ) + builder = Builder(soc, **builder_argdict(args)) + builder.build(run=args.build) + + if args.flash: + from litex.build.dfu import DFUProg + prog_gw = DFUProg(vid="1d50", pid="0x6146", alt=0) + prog_sw = DFUProg(vid="1d50", pid="0x6146", alt=1) + + prog_gw.load_bitstream(os.path.join(builder.gateware_dir, soc.build_name + ".bin"), reset=False) + prog_sw.load_bitstream(os.path.join(builder.software_dir, 'bios/bios.bin')) + +if __name__ == "__main__": + main()