From 223a69cf91d0fdc74a51ac3b96836a1ed2c4d248 Mon Sep 17 00:00:00 2001 From: Tomasz Michalak Date: Mon, 23 Jan 2023 12:13:33 +0100 Subject: [PATCH 1/6] Add platform and target files for Antmicro's sdi mipi video converter board Signed-off-by: Tomasz Michalak --- .../antmicro_sdi_mipi_video_converter.py | 228 ++++++++++++++++++ .../antmicro_sdi_mipi_video_converter.py | 141 +++++++++++ 2 files changed, 369 insertions(+) create mode 100644 litex_boards/platforms/antmicro_sdi_mipi_video_converter.py create mode 100755 litex_boards/targets/antmicro_sdi_mipi_video_converter.py diff --git a/litex_boards/platforms/antmicro_sdi_mipi_video_converter.py b/litex_boards/platforms/antmicro_sdi_mipi_video_converter.py new file mode 100644 index 0000000..b85ddc6 --- /dev/null +++ b/litex_boards/platforms/antmicro_sdi_mipi_video_converter.py @@ -0,0 +1,228 @@ +from litex.build.generic_platform import * +from litex.build.lattice import LatticePlatform +from litex.build.lattice.programmer import LatticeProgrammer +from litex.build.lattice.programmer import EcpprogProgrammer + +# IOs ---------------------------------------------------------------------------------------------- + +_io = [ + ("serial", 0, + Subsignal("tx", Pins("J12"), IOStandard("LVCMOS33")), + Subsignal("rx", Pins("J11"), IOStandard("LVCMOS33")), + ), + + # Section 7.3 General Purpose LEDs + ("user_led", 0, Pins("E15"), IOStandard("LVCMOS33")), + ("user_led", 1, Pins("E16"), IOStandard("LVCMOS33")), + + # Section 7.1 DIP Switch + ("user_dip_btn", 0, Pins("F15"), IOStandard("LVCMOS33")), + ("user_dip_btn", 1, Pins("H10"), IOStandard("LVCMOS33")), + + + # Section 6.3.1. SPI Configuration + ("spiflash", 0, + Subsignal("cs_n", Pins("C15")), + Subsignal("clk", Pins("C16")), + Subsignal("mosi", Pins("C14")), + Subsignal("miso", Pins("D16")), + IOStandard("LVCMOS33") + ) +] + + +# Connectors --------------------------------------------------------------------------------------- + +_connectors = [] + +# Test and Demo ------------------------------------------------------------------------------------ + + +# Platform ----------------------------------------------------------------------------------------- + +class Platform(LatticePlatform): + default_clk_name = "clk12" + default_clk_period = 1e9/12e6 + + def __init__(self, device="LIFCL-40-9BG400C", toolchain="radiant", **kwargs): + # Accept "LIFCL" for backwards compatibility. + # LIFCL just means Crosslink-NX so we can expect every + # Crosslink-NX Evaluation Board to have a LIFCL part. + if device == "LIFCL": + device == "LIFCL-40-9BG400C" + assert device in ["LIFCL-40-9BG256C", "LIFCL-40-9BG400C", "LIFCL-40-8BG400CES", "LIFCL-40-8BG400CES2", "LIFCL-40-8BG400C"] + LatticePlatform.__init__(self, device, _io, _connectors, toolchain=toolchain, **kwargs) + + def create_programmer(self, mode = "direct", prog="radiant"): + assert mode in ["direct","flash"] + assert prog in ["radiant","ecpprog"] + + if prog == "ecpprog": + return EcpprogProgrammer() + + + xcf_template_direct = """ + + + + + JTAG + + + 1 + Lattice + LIFCL + LIFCL-40 + 0x010f1043 + All + LIFCL-40 + + 8 + 11111111 + 1 + 0 + + {bitstream_file} + N/A + Static Random Access Memory (SRAM) + Fast Configuration + + + + + SEQUENTIAL + ENTIRED CHAIN + No Override + TLR + TLR + + 3 + + + USB2 + FTUSB-0 + + +""" + + xcf_template_flash = """ + + + + + JTAG2SPI + + + 1 + Lattice + LIFCL + LIFCL-40 + All + + 8 + 11111111 + 1 + 0 + + {bitstream_file} + External SPI Flash Memory (SPI FLASH) + Erase,Program,Verify + + + + + 1 + Lattice + LIFCL + LIFCL-40 + 0x010f1043 + All + LIFCL-40 + + 8 + 11111111 + 1 + 0 + + Static Random Access Memory (SRAM) + Refresh Verify ID + + + + + + 1 + Macronix + SPI Serial Flash + MX25L12833F + 0x18 + 8-pin SOP + Erase,Program,Verify + {bitstream_file} + 0x00000000 + 0x000F0000 + 128 + 1016029 + 1 + + + + + + 1 + + {bitstream_file} + + + + + + + + + + + SEQUENTIAL + ENTIRED CHAIN + No Override + TLR + TLR + + + 3 + + + USB2 + FTUSB-0 + Lattice CrossLink-NX Eval Board A Location 0000 Serial FT4J4IK9A + + +""" + + if mode == "direct": + xcf_template = xcf_template_direct + if mode == "flash": + xcf_template = xcf_template_flash + + return LatticeProgrammer(xcf_template) diff --git a/litex_boards/targets/antmicro_sdi_mipi_video_converter.py b/litex_boards/targets/antmicro_sdi_mipi_video_converter.py new file mode 100755 index 0000000..7534e24 --- /dev/null +++ b/litex_boards/targets/antmicro_sdi_mipi_video_converter.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python3 + +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: BSD-2-Clause + +import os + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + +import platforms.antmicro_sdi_mipi_video_converter + +from litex.soc.cores.ram import NXLRAM +from litex.soc.cores.clock import NXPLL +from litex.build.io import CRG +from litex.build.generic_platform import * + +from litex.soc.cores.clock import * +from litex.soc.integration.soc_core import * +from litex.soc.integration.builder import * +from litex.soc.cores.led import LedChaser + +from litex.build.lattice.oxide import oxide_args, oxide_argdict +from litex.build.lattice.radiant import radiant_build_argdict, radiant_build_args + +kB = 1024 +mB = 1024*kB + + +# CRG ---------------------------------------------------------------------------------------------- + +class _CRG(Module): + def __init__(self, platform, sys_clk_freq): + self.clock_domains.cd_por = ClockDomain() + self.clock_domains.cd_sys = ClockDomain() + + # Built in OSC + self.submodules.hf_clk = NXOSCA() + hf_clk_freq = 25e6 + self.hf_clk.create_hf_clk(self.cd_por, hf_clk_freq) + + # Power on reset + por_count = Signal(16, reset=2**16-1) + por_done = Signal() + self.comb += por_done.eq(por_count == 0) + self.sync.por += If(~por_done, por_count.eq(por_count - 1)) + + # PLL + self.submodules.sys_pll = sys_pll = NXPLL(platform=platform, create_output_port_clocks=True) + sys_pll.register_clkin(self.cd_por.clk, hf_clk_freq) + sys_pll.create_clkout(self.cd_sys, sys_clk_freq) + self.specials += AsyncResetSynchronizer(self.cd_sys, ~self.sys_pll.locked | ~por_done ) + + +# BaseSoC ------------------------------------------------------------------------------------------ + +class BaseSoC(SoCCore): + mem_map = { + "rom" : 0x00000000, + "sram" : 0x40000000, + "main_ram": 0x60000000, + "csr" : 0xf0000000, + } + + def __init__(self, sys_clk_freq=int(75e6), device="LIFCL-40-9BG256C", toolchain="radiant", with_led_chaser=True, **kwargs): + platform = antmicro_sdi_mipi_video_converter.Platform(device=device, toolchain=toolchain) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + + # SoCCore -----------------------------------------_---------------------------------------- + + # Disable Integrated SRAM since we want to instantiate LRAM specifically for it + kwargs["integrated_sram_size"] = 0 + SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Crosslink-NX Evaluation Board", **kwargs) + + # 128KB LRAM (used as SRAM) --------------------------------------------------------------- + + self.submodules.spram = NXLRAM(32, 64*kB) + self.register_mem("sram", self.mem_map["sram"], self.spram.bus, 16*kB) + + self.submodules.main_ram = NXLRAM(32, 64*kB) + self.register_mem("main_ram", self.mem_map["main_ram"], self.main_ram.bus, 64*kB) + + # Leds ------------------------------------------------------------------------------------- + if with_led_chaser: + self.submodules.leds = LedChaser( + pads = Cat(*[platform.request("user_led", i) for i in range(2)]), + sys_clk_freq = sys_clk_freq) + +# Build -------------------------------------------------------------------------------------------- + +def main(): + from litex.soc.integration.soc import LiteXSoCArgumentParser + parser = LiteXSoCArgumentParser(description="LiteX SoC on Crosslink-NX Eval Board") + target_group = parser.add_argument_group(title="Target options") + target_group.add_argument("--build", action="store_true", help="Build design.") + target_group.add_argument("--load", action="store_true", help="Load bitstream.") + target_group.add_argument("--toolchain", default="radiant", help="FPGA toolchain (radiant or prjoxide).") + target_group.add_argument("--device", default="LIFCL-40-9BG256C", help="FPGA device (LIFCL-40-9BG400C, LIFCL-40-8BG400CES, or LIFCL-40-8BG400CES2).") + target_group.add_argument("--sys-clk-freq", default=75e6, help="System clock frequency.") + target_group.add_argument("--programmer", default="radiant", help="Programmer (radiant or ecpprog).") + target_group.add_argument("--prog-target", default="direct", help="Programming Target (direct or flash).") + + builder_args(parser) + soc_core_args(parser) + oxide_args(parser) + radiant_build_args(parser) + args = parser.parse_args() + + soc = BaseSoC( + sys_clk_freq = int(float(args.sys_clk_freq)), + device = args.device, + toolchain = args.toolchain, + **soc_core_argdict(args) + ) + + builder = Builder(soc, **builder_argdict(args)) + builder_kargs = oxide_argdict(args) if args.toolchain == "oxide" else radiant_build_argdict(args) + if args.build: + builder.build(**builder_kargs) + + if args.load: + prog = soc.platform.create_programmer(args.prog_target, args.programmer) + if args.programmer == "ecpprog" and args.prog_target == "flash": + prog.flash(address=args.address, bitstream=builder.get_bitstream_filename(mode="sram")) + else: + if args.programmer == "radiant": + os.system("sudo modprobe -rf ftdi_sio") + + prog.load_bitstream(builder.get_bitstream_filename(mode="sram")) + + if args.programmer == "radiant": + os.system("sudo modprobe ftdi_sio") + +if __name__ == "__main__": + main() + From 934e031dca8424040122f2570d10cecfa7db693e Mon Sep 17 00:00:00 2001 From: Antoni Pokusinski Date: Mon, 6 Feb 2023 11:05:30 +0100 Subject: [PATCH 2/6] Fix imports --- litex_boards/targets/antmicro_sdi_mipi_video_converter.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/litex_boards/targets/antmicro_sdi_mipi_video_converter.py b/litex_boards/targets/antmicro_sdi_mipi_video_converter.py index 7534e24..9e3b0e4 100755 --- a/litex_boards/targets/antmicro_sdi_mipi_video_converter.py +++ b/litex_boards/targets/antmicro_sdi_mipi_video_converter.py @@ -11,7 +11,7 @@ import os from migen import * from migen.genlib.resetsync import AsyncResetSynchronizer -import platforms.antmicro_sdi_mipi_video_converter +import litex_boards.platforms.antmicro_sdi_mipi_video_converter from litex.soc.cores.ram import NXLRAM from litex.soc.cores.clock import NXPLL @@ -66,7 +66,7 @@ class BaseSoC(SoCCore): } def __init__(self, sys_clk_freq=int(75e6), device="LIFCL-40-9BG256C", toolchain="radiant", with_led_chaser=True, **kwargs): - platform = antmicro_sdi_mipi_video_converter.Platform(device=device, toolchain=toolchain) + platform = litex_boards.platforms.antmicro_sdi_mipi_video_converter.Platform(device=device, toolchain=toolchain) # CRG -------------------------------------------------------------------------------------- self.submodules.crg = _CRG(platform, sys_clk_freq) @@ -138,4 +138,4 @@ def main(): if __name__ == "__main__": main() - + From 01abbc0d50cb0297aef5ef70e2c1c3ca985681b3 Mon Sep 17 00:00:00 2001 From: Antoni Pokusinski Date: Wed, 8 Feb 2023 14:06:25 +0100 Subject: [PATCH 3/6] Replace deprecated register_mem with add_slave --- litex_boards/targets/antmicro_sdi_mipi_video_converter.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/litex_boards/targets/antmicro_sdi_mipi_video_converter.py b/litex_boards/targets/antmicro_sdi_mipi_video_converter.py index 9e3b0e4..badd918 100755 --- a/litex_boards/targets/antmicro_sdi_mipi_video_converter.py +++ b/litex_boards/targets/antmicro_sdi_mipi_video_converter.py @@ -20,6 +20,7 @@ from litex.build.generic_platform import * from litex.soc.cores.clock import * from litex.soc.integration.soc_core import * +from litex.soc.integration.soc import SoCRegion from litex.soc.integration.builder import * from litex.soc.cores.led import LedChaser @@ -80,10 +81,10 @@ class BaseSoC(SoCCore): # 128KB LRAM (used as SRAM) --------------------------------------------------------------- self.submodules.spram = NXLRAM(32, 64*kB) - self.register_mem("sram", self.mem_map["sram"], self.spram.bus, 16*kB) + self.bus.add_slave("sram", self.spram.bus, SoCRegion(origin=self.mem_map["sram"], size=16*kB)) self.submodules.main_ram = NXLRAM(32, 64*kB) - self.register_mem("main_ram", self.mem_map["main_ram"], self.main_ram.bus, 64*kB) + self.bus.add_slave("main_ram", self.main_ram.bus, SoCRegion(origin=self.mem_map["main_ram"], size=64*kB)) # Leds ------------------------------------------------------------------------------------- if with_led_chaser: From 0c774a906d60f8bb54429900cda000337b676c3e Mon Sep 17 00:00:00 2001 From: Antoni Pokusinski Date: Wed, 8 Feb 2023 15:11:32 +0100 Subject: [PATCH 4/6] Add clk12 to platform --- litex_boards/platforms/antmicro_sdi_mipi_video_converter.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/litex_boards/platforms/antmicro_sdi_mipi_video_converter.py b/litex_boards/platforms/antmicro_sdi_mipi_video_converter.py index b85ddc6..676dad7 100644 --- a/litex_boards/platforms/antmicro_sdi_mipi_video_converter.py +++ b/litex_boards/platforms/antmicro_sdi_mipi_video_converter.py @@ -6,6 +6,8 @@ from litex.build.lattice.programmer import EcpprogProgrammer # IOs ---------------------------------------------------------------------------------------------- _io = [ + ("clk12", 0, Pins("G15"), IOStandard("LVCMOS33")), + ("serial", 0, Subsignal("tx", Pins("J12"), IOStandard("LVCMOS33")), Subsignal("rx", Pins("J11"), IOStandard("LVCMOS33")), From 70f2fd636822132e20edf7b32d5a5de7be1af7e3 Mon Sep 17 00:00:00 2001 From: Antoni Pokusinski Date: Wed, 15 Feb 2023 11:45:42 +0100 Subject: [PATCH 5/6] Fix format --- .../antmicro_sdi_mipi_video_converter.py | 15 ++++---- .../antmicro_sdi_mipi_video_converter.py | 35 ++++++++++--------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/litex_boards/platforms/antmicro_sdi_mipi_video_converter.py b/litex_boards/platforms/antmicro_sdi_mipi_video_converter.py index 676dad7..8f7e902 100644 --- a/litex_boards/platforms/antmicro_sdi_mipi_video_converter.py +++ b/litex_boards/platforms/antmicro_sdi_mipi_video_converter.py @@ -6,12 +6,12 @@ from litex.build.lattice.programmer import EcpprogProgrammer # IOs ---------------------------------------------------------------------------------------------- _io = [ - ("clk12", 0, Pins("G15"), IOStandard("LVCMOS33")), + ("clk12", 0, Pins("G15"), IOStandard("LVCMOS33")), ("serial", 0, Subsignal("tx", Pins("J12"), IOStandard("LVCMOS33")), Subsignal("rx", Pins("J11"), IOStandard("LVCMOS33")), - ), + ), # Section 7.3 General Purpose LEDs ("user_led", 0, Pins("E15"), IOStandard("LVCMOS33")), @@ -29,7 +29,7 @@ _io = [ Subsignal("mosi", Pins("C14")), Subsignal("miso", Pins("D16")), IOStandard("LVCMOS33") - ) + ) ] @@ -43,7 +43,7 @@ _connectors = [] # Platform ----------------------------------------------------------------------------------------- class Platform(LatticePlatform): - default_clk_name = "clk12" + default_clk_name = "clk12" default_clk_period = 1e9/12e6 def __init__(self, device="LIFCL-40-9BG400C", toolchain="radiant", **kwargs): @@ -55,14 +55,13 @@ class Platform(LatticePlatform): assert device in ["LIFCL-40-9BG256C", "LIFCL-40-9BG400C", "LIFCL-40-8BG400CES", "LIFCL-40-8BG400CES2", "LIFCL-40-8BG400C"] LatticePlatform.__init__(self, device, _io, _connectors, toolchain=toolchain, **kwargs) - def create_programmer(self, mode = "direct", prog="radiant"): - assert mode in ["direct","flash"] - assert prog in ["radiant","ecpprog"] + def create_programmer(self, mode="direct", prog="radiant"): + assert mode in ["direct", "flash"] + assert prog in ["radiant", "ecpprog"] if prog == "ecpprog": return EcpprogProgrammer() - xcf_template_direct = """ diff --git a/litex_boards/targets/antmicro_sdi_mipi_video_converter.py b/litex_boards/targets/antmicro_sdi_mipi_video_converter.py index badd918..f2d9b7e 100755 --- a/litex_boards/targets/antmicro_sdi_mipi_video_converter.py +++ b/litex_boards/targets/antmicro_sdi_mipi_video_converter.py @@ -15,7 +15,6 @@ import litex_boards.platforms.antmicro_sdi_mipi_video_converter from litex.soc.cores.ram import NXLRAM from litex.soc.cores.clock import NXPLL -from litex.build.io import CRG from litex.build.generic_platform import * from litex.soc.cores.clock import * @@ -45,7 +44,7 @@ class _CRG(Module): # Power on reset por_count = Signal(16, reset=2**16-1) - por_done = Signal() + por_done = Signal() self.comb += por_done.eq(por_count == 0) self.sync.por += If(~por_done, por_count.eq(por_count - 1)) @@ -53,21 +52,22 @@ class _CRG(Module): self.submodules.sys_pll = sys_pll = NXPLL(platform=platform, create_output_port_clocks=True) sys_pll.register_clkin(self.cd_por.clk, hf_clk_freq) sys_pll.create_clkout(self.cd_sys, sys_clk_freq) - self.specials += AsyncResetSynchronizer(self.cd_sys, ~self.sys_pll.locked | ~por_done ) + self.specials += AsyncResetSynchronizer(self.cd_sys, ~self.sys_pll.locked | ~por_done) # BaseSoC ------------------------------------------------------------------------------------------ class BaseSoC(SoCCore): mem_map = { - "rom" : 0x00000000, - "sram" : 0x40000000, + "rom": 0x00000000, + "sram": 0x40000000, "main_ram": 0x60000000, - "csr" : 0xf0000000, + "csr": 0xf0000000, } def __init__(self, sys_clk_freq=int(75e6), device="LIFCL-40-9BG256C", toolchain="radiant", with_led_chaser=True, **kwargs): - platform = litex_boards.platforms.antmicro_sdi_mipi_video_converter.Platform(device=device, toolchain=toolchain) + platform = litex_boards.platforms.antmicro_sdi_mipi_video_converter.Platform( + device=device, toolchain=toolchain) # CRG -------------------------------------------------------------------------------------- self.submodules.crg = _CRG(platform, sys_clk_freq) @@ -76,10 +76,11 @@ class BaseSoC(SoCCore): # Disable Integrated SRAM since we want to instantiate LRAM specifically for it kwargs["integrated_sram_size"] = 0 - SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Crosslink-NX Evaluation Board", **kwargs) + SoCCore.__init__(self, platform, sys_clk_freq, + ident="LiteX SoC on Crosslink-NX Evaluation Board", **kwargs) # 128KB LRAM (used as SRAM) --------------------------------------------------------------- - + self.submodules.spram = NXLRAM(32, 64*kB) self.bus.add_slave("sram", self.spram.bus, SoCRegion(origin=self.mem_map["sram"], size=16*kB)) @@ -89,11 +90,12 @@ class BaseSoC(SoCCore): # Leds ------------------------------------------------------------------------------------- if with_led_chaser: self.submodules.leds = LedChaser( - pads = Cat(*[platform.request("user_led", i) for i in range(2)]), - sys_clk_freq = sys_clk_freq) + pads=Cat(*[platform.request("user_led", i) for i in range(2)]), + sys_clk_freq=sys_clk_freq) # Build -------------------------------------------------------------------------------------------- + def main(): from litex.soc.integration.soc import LiteXSoCArgumentParser parser = LiteXSoCArgumentParser(description="LiteX SoC on Crosslink-NX Eval Board") @@ -113,9 +115,9 @@ def main(): args = parser.parse_args() soc = BaseSoC( - sys_clk_freq = int(float(args.sys_clk_freq)), - device = args.device, - toolchain = args.toolchain, + sys_clk_freq=int(float(args.sys_clk_freq)), + device=args.device, + toolchain=args.toolchain, **soc_core_argdict(args) ) @@ -127,7 +129,8 @@ def main(): if args.load: prog = soc.platform.create_programmer(args.prog_target, args.programmer) if args.programmer == "ecpprog" and args.prog_target == "flash": - prog.flash(address=args.address, bitstream=builder.get_bitstream_filename(mode="sram")) + prog.flash(address=args.address, + bitstream=builder.get_bitstream_filename(mode="sram")) else: if args.programmer == "radiant": os.system("sudo modprobe -rf ftdi_sio") @@ -137,6 +140,6 @@ def main(): if args.programmer == "radiant": os.system("sudo modprobe ftdi_sio") + if __name__ == "__main__": main() - From 31d718749a9d4646bf01ce2c57e45c888b6ff5c6 Mon Sep 17 00:00:00 2001 From: Antoni Pokusinski Date: Wed, 15 Feb 2023 11:53:50 +0100 Subject: [PATCH 6/6] Add copyrights --- litex_boards/platforms/antmicro_sdi_mipi_video_converter.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/litex_boards/platforms/antmicro_sdi_mipi_video_converter.py b/litex_boards/platforms/antmicro_sdi_mipi_video_converter.py index 8f7e902..05c3f06 100644 --- a/litex_boards/platforms/antmicro_sdi_mipi_video_converter.py +++ b/litex_boards/platforms/antmicro_sdi_mipi_video_converter.py @@ -1,3 +1,9 @@ +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: BSD-2-Clause + from litex.build.generic_platform import * from litex.build.lattice import LatticePlatform from litex.build.lattice.programmer import LatticeProgrammer