From f8dc03810d185f57123a59e5cd3aa158efbf981d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Thu, 26 Sep 2024 15:48:31 +0200 Subject: [PATCH 1/3] build: efinix: use LiteXContext to get platform MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit use LiteXContext to get platform. Signed-off-by: Fin Maaß --- litex/build/efinix/common.py | 59 +++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/litex/build/efinix/common.py b/litex/build/efinix/common.py index f43afb0c6a..e1ca67f7f4 100644 --- a/litex/build/efinix/common.py +++ b/litex/build/efinix/common.py @@ -8,6 +8,7 @@ from migen.fhdl.module import Module from migen.genlib.resetsync import AsyncResetSynchronizer +from litex.gen import * from litex.build.io import * from litex.build.generic_platform import Pins @@ -72,7 +73,8 @@ def lower(dr): class EfinixClkInputImpl(Module): n = 0 - def __init__(self, platform, i, o): + def __init__(self, i, o): + platform = LiteXContext.platform self.name = f"clk_input{self.n}" if isinstance(o, Signal): clk_out_name = f"{o.name_override}{self.name}_clk" @@ -103,13 +105,14 @@ def __init__(self, platform, i, o): class EfinixClkInput(Module): @staticmethod def lower(dr): - return EfinixClkInputImpl(dr.platform, dr.i, dr.o) + return EfinixClkInputImpl(dr.i, dr.o) # Efinix Clk Output -------------------------------------------------------------------------------- class EfinixClkOutputImpl(Module): - def __init__(self, platform, i, o): + def __init__(self, i, o): assert_is_signal_or_clocksignal(i) + platform = LiteXContext.platform block = { "type" : "GPIO", "size" : 1, @@ -121,16 +124,16 @@ def __init__(self, platform, i, o): platform.toolchain.ifacewriter.blocks.append(block) platform.toolchain.excluded_ios.append(o) - class EfinixClkOutput(Module): @staticmethod def lower(dr): - return EfinixClkOutputImpl(dr.platform, dr.i, dr.o) + return EfinixClkOutputImpl(dr.i, dr.o) # Efinix Tristate ---------------------------------------------------------------------------------- class EfinixTristateImpl(Module): - def __init__(self, platform, io, o, oe, i=None): + def __init__(self, io, o, oe, i=None): + platform = LiteXContext.platform nbits, sign = value_bits_sign(io) for bit in range(nbits): @@ -158,12 +161,13 @@ def __init__(self, platform, io, o, oe, i=None): class EfinixTristate(Module): @staticmethod def lower(dr): - return EfinixTristateImpl(dr.platform, dr.target, dr.o, dr.oe, dr.i) + return EfinixTristateImpl(dr.target, dr.o, dr.oe, dr.i) # Efinix DifferentialOutput ------------------------------------------------------------------------ class EfinixDifferentialOutputImpl(Module): - def __init__(self, platform, i, o_p, o_n): + def __init__(self, i, o_p, o_n): + platform = LiteXContext.platform # only keep _p io_name = platform.get_pin_name(o_p) io_pad = platform.get_pad_name(o_p) # need real pad name @@ -202,12 +206,13 @@ def __init__(self, platform, i, o_p, o_n): class EfinixDifferentialOutput: @staticmethod def lower(dr): - return EfinixDifferentialOutputImpl(dr.platform, dr.i, dr.o_p, dr.o_n) + return EfinixDifferentialOutputImpl(dr.i, dr.o_p, dr.o_n) # Efinix DifferentialInput ------------------------------------------------------------------------- class EfinixDifferentialInputImpl(Module): - def __init__(self, platform, i_p, i_n, o): + def __init__(self, i_p, i_n, o): + platform = LiteXContext.platform # only keep _p io_name = platform.get_pin_name(i_p) io_pad = platform.get_pad_name(i_p) # need real pad name @@ -261,14 +266,15 @@ def __init__(self, platform, i_p, i_n, o): class EfinixDifferentialInput: @staticmethod def lower(dr): - return EfinixDifferentialInputImpl(dr.platform, dr.i_p, dr.i_n, dr.o) + return EfinixDifferentialInputImpl(dr.i_p, dr.i_n, dr.o) # Efinix DDRTristate ------------------------------------------------------------------------------- class EfinixDDRTristateImpl(Module): - def __init__(self, platform, io, o1, o2, oe1, oe2, i1, i2, clk): + def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk): assert oe1 == oe2 assert_is_signal_or_clocksignal(clk) + platform = LiteXContext.platform io_name = platform.get_pin_name(io) io_pad = platform.get_pin_location(io) io_prop = platform.get_pin_properties(io) @@ -304,13 +310,14 @@ def __init__(self, platform, io, o1, o2, oe1, oe2, i1, i2, clk): class EfinixDDRTristate: @staticmethod def lower(dr): - return EfinixDDRTristateImpl(dr.platform, dr.io, dr.o1, dr.o2, dr.oe1, dr.oe2, dr.i1, dr.i2, dr.clk) + return EfinixDDRTristateImpl(dr.io, dr.o1, dr.o2, dr.oe1, dr.oe2, dr.i1, dr.i2, dr.clk) # Efinix SDRTristate ------------------------------------------------------------------------------- -class EfinixSDRTristateImpl(EfinixDDRTristateImpl): - def __init__(self, platform, io, o, oe, i, clk): +class EfinixSDRTristateImpl(Module): + def __init__(self, io, o, oe, i, clk): assert_is_signal_or_clocksignal(clk) + platform = LiteXContext.platform io_name = platform.get_pin_name(io) io_pad = platform.get_pin_location(io) io_prop = platform.get_pin_properties(io) @@ -343,13 +350,14 @@ def __init__(self, platform, io, o, oe, i, clk): class EfinixSDRTristate(Module): @staticmethod def lower(dr): - return EfinixSDRTristateImpl(dr.platform, dr.io, dr.o, dr.oe, dr.i, dr.clk) + return EfinixSDRTristateImpl(dr.io, dr.o, dr.oe, dr.i, dr.clk) # Efinix SDROutput --------------------------------------------------------------------------------- class EfinixSDROutputImpl(Module): - def __init__(self, platform, i, o, clk): + def __init__(self, i, o, clk): assert_is_signal_or_clocksignal(clk) + platform = LiteXContext.platform io_name = platform.get_pin_name(o) io_pad = platform.get_pin_location(o) io_prop = platform.get_pin_properties(o) @@ -375,13 +383,14 @@ def __init__(self, platform, i, o, clk): class EfinixSDROutput(Module): @staticmethod def lower(dr): - return EfinixSDROutputImpl(dr.platform, dr.i, dr.o, dr.clk) + return EfinixSDROutputImpl(dr.i, dr.o, dr.clk) # Efinix DDROutput --------------------------------------------------------------------------------- class EfinixDDROutputImpl(Module): - def __init__(self, platform, i1, i2, o, clk): + def __init__(self, i1, i2, o, clk): assert_is_signal_or_clocksignal(clk) + platform = LiteXContext.platform io_name = platform.get_pin_name(o) io_pad = platform.get_pin_location(o) io_prop = platform.get_pin_properties(o) @@ -408,13 +417,14 @@ def __init__(self, platform, i1, i2, o, clk): class EfinixDDROutput: @staticmethod def lower(dr): - return EfinixDDROutputImpl(dr.platform, dr.i1, dr.i2, dr.o, dr.clk) + return EfinixDDROutputImpl(dr.i1, dr.i2, dr.o, dr.clk) # Efinix SDRInput ---------------------------------------------------------------------------------- class EfinixSDRInputImpl(Module): - def __init__(self, platform, i, o, clk): + def __init__(self, i, o, clk): assert_is_signal_or_clocksignal(clk) + platform = LiteXContext.platform io_name = platform.get_pin_name(i) io_pad = platform.get_pin_location(i) io_prop = platform.get_pin_properties(i) @@ -437,13 +447,14 @@ def __init__(self, platform, i, o, clk): class EfinixSDRInput: @staticmethod def lower(dr): - return EfinixSDRInputImpl(dr.platform, dr.i, dr.o, dr.clk) + return EfinixSDRInputImpl(dr.i, dr.o, dr.clk) # Efinix DDRInput ---------------------------------------------------------------------------------- class EfinixDDRInputImpl(Module): - def __init__(self, platform, i, o1, o2, clk): + def __init__(self, i, o1, o2, clk): assert_is_signal_or_clocksignal(clk) + platform = LiteXContext.platform io_name = platform.get_pin_name(i) io_pad = platform.get_pin_location(i) io_prop = platform.get_pin_properties(i) @@ -468,7 +479,7 @@ def __init__(self, platform, i, o1, o2, clk): class EfinixDDRInput: @staticmethod def lower(dr): - return EfinixDDRInputImpl(dr.platform, dr.i, dr.o1, dr.o2, dr.clk) + return EfinixDDRInputImpl(dr.i, dr.o1, dr.o2, dr.clk) # Efinix Special Overrides ------------------------------------------------------------------------- From e9a4b178ce65df3520462dcbf10c0520bc02f630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Thu, 26 Sep 2024 15:53:56 +0200 Subject: [PATCH 2/3] build: efinix: platform.py: add `get_pins_location` and `get_pins_name` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add `get_pins_location` and `get_pins_name`. Signed-off-by: Fin Maaß --- litex/build/efinix/platform.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/litex/build/efinix/platform.py b/litex/build/efinix/platform.py index 4505c4caed..1ac92658da 100644 --- a/litex/build/efinix/platform.py +++ b/litex/build/efinix/platform.py @@ -91,6 +91,15 @@ def get_pin_location(self, sig): return [pins[idx]] return None + def get_pins_location(self, sig): + if sig is None: + return None + sc = self.constraint_manager.get_sig_constraints() + for s, pins, others, resource in sc: + if (s == sig) and (pins[0] != 'X'): + return pins + return None + def get_pin_properties(self, sig): ret = [] if sig is None: @@ -150,6 +159,18 @@ def get_pin_name(self, sig): return name return None + def get_pins_name(self, sig): + if sig is None: + return None + sc = self.constraint_manager.get_sig_constraints() + for s, pins, others, resource in sc: + if s == sig: + name = resource[0] + (f"{resource[1]}" if resource[1] is not None else "") + if resource[2]: + name = name + "_" + resource[2] + return name + return None + def get_pad_name(self, sig): """ Return pin name (GPIOX_Y_ZZZ). From a825c61385eb4ab4462a6d55660756da6467873f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Thu, 26 Sep 2024 15:58:29 +0200 Subject: [PATCH 3/3] build: efinix: EfinixTristateImpl: use GPIO Bus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit use the gpio bus for Efinix Tristate implemenation. Signed-off-by: Fin Maaß --- litex/build/efinix/common.py | 48 +++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/litex/build/efinix/common.py b/litex/build/efinix/common.py index e1ca67f7f4..8638659073 100644 --- a/litex/build/efinix/common.py +++ b/litex/build/efinix/common.py @@ -134,28 +134,32 @@ def lower(dr): class EfinixTristateImpl(Module): def __init__(self, io, o, oe, i=None): platform = LiteXContext.platform - nbits, sign = value_bits_sign(io) - - for bit in range(nbits): - io_name = platform.get_pin_name(io[bit]) - io_loc = platform.get_pin_location(io[bit]) - io_prop = platform.get_pin_properties(io[bit]) - io_o = platform.add_iface_io(io_name + "_OUT") - io_oe = platform.add_iface_io(io_name + "_OE") - io_i = platform.add_iface_io(io_name + "_IN") - self.comb += io_o.eq(o >> bit) - self.comb += io_oe.eq(oe) - if i is not None: - self.comb += i[bit].eq(io_i) - block = { - "type" : "GPIO", - "mode" : "INOUT", - "name" : io_name, - "location" : [io_loc[0]], - "properties" : io_prop - } - - platform.toolchain.ifacewriter.blocks.append(block) + if len(io) == 1: + io_name = platform.get_pin_name(io) + io_pad = platform.get_pin_location(io) + io_prop = platform.get_pin_properties(io) + else: + io_name = platform.get_pins_name(io) + io_pad = platform.get_pins_location(io) + io_prop = platform.get_pin_properties(io[0]) + io_prop_dict = dict(io_prop) + io_data_i = platform.add_iface_io(io_name + "_OUT") + io_data_o = platform.add_iface_io(io_name + "_IN") + io_data_e = platform.add_iface_io(io_name + "_OE") + self.comb += io_data_i.eq(o) + self.comb += io_data_e.eq(oe) + if i is not None: + self.comb += i.eq(io_data_o) + block = { + "type" : "GPIO", + "mode" : "INOUT", + "name" : io_name, + "location" : io_pad, + "properties" : io_prop, + "size" : len(io), + "drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4") + } + platform.toolchain.ifacewriter.blocks.append(block) platform.toolchain.excluded_ios.append(platform.get_pin(io)) class EfinixTristate(Module):