From 4af2c8a776baba1a14fe3be996908010668482a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Mon, 30 Sep 2024 11:52:12 +0200 Subject: [PATCH 1/4] build: io: allow optional arguments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit allow optional arguments for io. Signed-off-by: Fin Maaß --- litex/build/io.py | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/litex/build/io.py b/litex/build/io.py index b83cac4780..a038f0c559 100644 --- a/litex/build/io.py +++ b/litex/build/io.py @@ -11,11 +11,12 @@ # Differential Input/Output ------------------------------------------------------------------------ class DifferentialInput(Special): - def __init__(self, i_p, i_n, o): + def __init__(self, i_p, i_n, o, **kwargs): Special.__init__(self) self.i_p = wrap(i_p) self.i_n = wrap(i_n) self.o = wrap(o) + self.kwargs = kwargs def iter_expressions(self): yield self, "i_p", SPECIAL_INPUT @@ -28,11 +29,12 @@ def lower(dr): class DifferentialOutput(Special): - def __init__(self, i, o_p, o_n): + def __init__(self, i, o_p, o_n, **kwargs): Special.__init__(self) self.i = wrap(i) self.o_p = wrap(o_p) self.o_n = wrap(o_n) + self.kwargs = kwargs def iter_expressions(self): yield self, "i" , SPECIAL_INPUT @@ -46,10 +48,11 @@ def lower(dr): # Clk Input/Output --------------------------------------------------------------------------------- class ClkInput(Special): - def __init__(self, i, o): + def __init__(self, i, o, **kwargs): Special.__init__(self) self.i = wrap(i) self.o = o if isinstance(o, str) else wrap(o) + self.kwargs = kwargs def iter_expressions(self): yield self, "i", SPECIAL_INPUT @@ -61,10 +64,11 @@ def lower(dr): class ClkOutput(Special): - def __init__(self, i, o): + def __init__(self, i, o, **kwargs): Special.__init__(self) self.i = i if isinstance(i, str) else wrap(i) self.o = wrap(o) + self.kwargs = kwargs def iter_expressions(self): yield self, "i", SPECIAL_INPUT @@ -83,7 +87,7 @@ def __init__(self, i, o, clk): self.sync.sdrio += o.eq(i) class SDRIO(Special): - def __init__(self, i, o, clk=None): + def __init__(self, i, o, clk=None, **kwargs): assert len(i) == len(o) == 1 Special.__init__(self) self.i = wrap(i) @@ -92,6 +96,7 @@ def __init__(self, i, o, clk=None): clk = ClockSignal() self.clk = wrap(clk) self.clk_domain = None if not hasattr(clk, "cd") else clk.cd + self.kwargs = kwargs def iter_expressions(self): yield self, "i" , SPECIAL_INPUT @@ -119,7 +124,7 @@ def __init__(self, io, o, oe, i, clk): self.specials += Tristate(io, _o, _oe, _i) class SDRTristate(Special): - def __init__(self, io, o, oe, i, clk=None): + def __init__(self, io, o, oe, i, clk=None, **kwargs): assert len(i) == len(o) == len(oe) Special.__init__(self) self.io = wrap(io) @@ -127,6 +132,7 @@ def __init__(self, io, o, oe, i, clk=None): self.oe = wrap(oe) self.i = wrap(i) self.clk = wrap(clk) if clk is not None else ClockSignal() + self.kwargs = kwargs def iter_expressions(self): yield self, "io" , SPECIAL_INOUT @@ -142,7 +148,7 @@ def lower(dr): # DDR Input/Output --------------------------------------------------------------------------------- class DDRInput(Special): - def __init__(self, i, o1, o2, clk=None): + def __init__(self, i, o1, o2, clk=None, **kwargs): Special.__init__(self) self.i = wrap(i) self.o1 = wrap(o1) @@ -150,6 +156,7 @@ def __init__(self, i, o1, o2, clk=None): if clk is None: clk = ClockSignal() self.clk = clk if isinstance(clk, str) else wrap(clk) + self.kwargs = kwargs def iter_expressions(self): yield self, "i" , SPECIAL_INPUT @@ -163,7 +170,7 @@ def lower(dr): class DDROutput(Special): - def __init__(self, i1, i2, o, clk=None): + def __init__(self, i1, i2, o, clk=None, **kwargs): Special.__init__(self) self.i1 = wrap(i1) self.i2 = wrap(i2) @@ -171,6 +178,7 @@ def __init__(self, i1, i2, o, clk=None): if clk is None: clk = ClockSignal() self.clk = clk if isinstance(clk, str) else wrap(clk) + self.kwargs = kwargs def iter_expressions(self): yield self, "i1" , SPECIAL_INPUT @@ -195,7 +203,7 @@ def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk): self.specials += Tristate(io, _o, _oe, _i) class DDRTristate(Special): - def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk=None): + def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk=None, **kwargs): Special.__init__(self) self.io = io self.o1 = o1 @@ -205,6 +213,7 @@ def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk=None): self.i1 = i1 self.i2 = i2 self.clk = clk if clk is not None else ClockSignal() + self.kwargs = kwargs def iter_expressions(self): yield self, "io" , SPECIAL_INOUT From 557448269ef8a2d0bbfd3bb3a8615b859b0d813d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Mon, 30 Sep 2024 12:38:28 +0200 Subject: [PATCH 2/4] build: efinix: EfinixClkOutput: allow inverting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit allow inverting of EfinixClkOutput. Signed-off-by: Fin Maaß --- litex/build/efinix/common.py | 5 +++-- litex/build/efinix/ifacewriter.py | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/litex/build/efinix/common.py b/litex/build/efinix/common.py index 50d78a8d98..c2f05401f7 100644 --- a/litex/build/efinix/common.py +++ b/litex/build/efinix/common.py @@ -109,7 +109,7 @@ def lower(dr): # Efinix Clk Output -------------------------------------------------------------------------------- class EfinixClkOutputImpl(LiteXModule): - def __init__(self, i, o): + def __init__(self, i, o, out_clk_inv=False): assert_is_signal_or_clocksignal(i) platform = LiteXContext.platform block = { @@ -119,6 +119,7 @@ def __init__(self, i, o): "properties" : platform.get_pin_properties(o), "name" : i, "mode" : "OUTPUT_CLK", + "out_clk_inv": 1 if out_clk_inv else 0, } platform.toolchain.ifacewriter.blocks.append(block) platform.toolchain.excluded_ios.append(o) @@ -126,7 +127,7 @@ def __init__(self, i, o): class EfinixClkOutput(LiteXModule): @staticmethod def lower(dr): - return EfinixClkOutputImpl(dr.i, dr.o) + return EfinixClkOutputImpl(dr.i, dr.o, **dr.kwargs) # Efinix Tristate ---------------------------------------------------------------------------------- diff --git a/litex/build/efinix/ifacewriter.py b/litex/build/efinix/ifacewriter.py index ffae3b2d94..df8a7362fd 100644 --- a/litex/build/efinix/ifacewriter.py +++ b/litex/build/efinix/ifacewriter.py @@ -275,6 +275,8 @@ def generate_gpio(self, block, verbose=True): cmd += 'design.create_clockout_gpio("{}")\n'.format(name) cmd += 'design.set_property("{}","OUT_CLK_PIN","{}")\n'.format(name, name) cmd += 'design.assign_pkg_pin("{}","{}")\n\n'.format(name, block["location"]) + if "out_clk_inv" in block: + cmd += f'design.set_property("{name}","IS_OUTCLK_INVERTED","{block["out_clk_inv"]}")\n' if prop: for p, val in prop: cmd += 'design.set_property("{}","{}","{}")\n'.format(name, p, val) From 0313c07a4ee4a02495bf476e47ea311afc68b1a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Mon, 30 Sep 2024 12:45:13 +0200 Subject: [PATCH 3/4] build efinix: common: allow clk inverting on registered gpio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit allow clk inverting on registered gpio. Signed-off-by: Fin Maaß --- litex/build/efinix/common.py | 40 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/litex/build/efinix/common.py b/litex/build/efinix/common.py index c2f05401f7..34e7ef7982 100644 --- a/litex/build/efinix/common.py +++ b/litex/build/efinix/common.py @@ -275,7 +275,7 @@ def lower(dr): # Efinix DDRTristate ------------------------------------------------------------------------------- class EfinixDDRTristateImpl(LiteXModule): - def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk): + def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk, out_clk_inv=False, in_clk_inv=False): assert oe1 == oe2 assert_is_signal_or_clocksignal(clk) platform = LiteXContext.platform @@ -305,8 +305,8 @@ def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk): "out_reg" : "DDIO_RESYNC", "out_clk_pin" : clk, "oe_reg" : "REG", - "in_clk_inv" : 0, - "out_clk_inv" : 0, + "in_clk_inv" : 1 if in_clk_inv else 0, + "out_clk_inv" : 1 if out_clk_inv else 0, "drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4") } platform.toolchain.ifacewriter.blocks.append(block) @@ -315,12 +315,12 @@ def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk): class EfinixDDRTristate: @staticmethod def lower(dr): - return EfinixDDRTristateImpl(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, **dr.kwargs) # Efinix SDRTristate ------------------------------------------------------------------------------- class EfinixSDRTristateImpl(LiteXModule): - def __init__(self, io, o, oe, i, clk): + def __init__(self, io, o, oe, i, clk, out_clk_inv=False, in_clk_inv=False): assert_is_signal_or_clocksignal(clk) platform = LiteXContext.platform io_name = platform.get_pin_name(io) @@ -345,8 +345,8 @@ def __init__(self, io, o, oe, i, clk): "out_reg" : "REG", "out_clk_pin" : clk, "oe_reg" : "REG", - "in_clk_inv" : 0, - "out_clk_inv" : 0, + "in_clk_inv" : 1 if in_clk_inv else 0, + "out_clk_inv" : 1 if out_clk_inv else 0, "drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4") } platform.toolchain.ifacewriter.blocks.append(block) @@ -356,12 +356,12 @@ def __init__(self, io, o, oe, i, clk): class EfinixSDRTristate(LiteXModule): @staticmethod def lower(dr): - return EfinixSDRTristateImpl(dr.io, dr.o, dr.oe, dr.i, dr.clk) + return EfinixSDRTristateImpl(dr.io, dr.o, dr.oe, dr.i, dr.clk, **dr.kwargs) # Efinix SDROutput --------------------------------------------------------------------------------- class EfinixSDROutputImpl(LiteXModule): - def __init__(self, i, o, clk): + def __init__(self, i, o, clk, out_clk_inv=False): assert_is_signal_or_clocksignal(clk) platform = LiteXContext.platform io_name = platform.get_pin_name(o) @@ -379,7 +379,7 @@ def __init__(self, i, o, clk): "size" : 1, "out_reg" : "REG", "out_clk_pin" : clk, - "out_clk_inv" : 0, + "out_clk_inv" : 1 if out_clk_inv else 0, "drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4") } platform.toolchain.ifacewriter.blocks.append(block) @@ -389,12 +389,12 @@ def __init__(self, i, o, clk): class EfinixSDROutput(LiteXModule): @staticmethod def lower(dr): - return EfinixSDROutputImpl(dr.i, dr.o, dr.clk) + return EfinixSDROutputImpl(dr.i, dr.o, dr.clk, **dr.kwargs) # Efinix DDROutput --------------------------------------------------------------------------------- class EfinixDDROutputImpl(LiteXModule): - def __init__(self, i1, i2, o, clk): + def __init__(self, i1, i2, o, clk, out_clk_inv=False): assert_is_signal_or_clocksignal(clk) platform = LiteXContext.platform io_name = platform.get_pin_name(o) @@ -414,7 +414,7 @@ def __init__(self, i1, i2, o, clk): "size" : 1, "out_reg" : "DDIO_RESYNC", "out_clk_pin" : clk, - "out_clk_inv" : 0, + "out_clk_inv" : 1 if out_clk_inv else 0, "drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4") } platform.toolchain.ifacewriter.blocks.append(block) @@ -423,12 +423,12 @@ def __init__(self, i1, i2, o, clk): class EfinixDDROutput: @staticmethod def lower(dr): - return EfinixDDROutputImpl(dr.i1, dr.i2, dr.o, dr.clk) + return EfinixDDROutputImpl(dr.i1, dr.i2, dr.o, dr.clk, **dr.kwargs) # Efinix SDRInput ---------------------------------------------------------------------------------- class EfinixSDRInputImpl(LiteXModule): - def __init__(self, i, o, clk): + def __init__(self, i, o, clk, in_clk_inv=False): assert_is_signal_or_clocksignal(clk) platform = LiteXContext.platform io_name = platform.get_pin_name(i) @@ -445,7 +445,7 @@ def __init__(self, i, o, clk): "size" : 1, "in_reg" : "REG", "in_clk_pin" : clk, - "in_clk_inv" : 0 + "in_clk_inv" : 1 if in_clk_inv else 0, } platform.toolchain.ifacewriter.blocks.append(block) platform.toolchain.excluded_ios.append(platform.get_pin(i)) @@ -453,12 +453,12 @@ def __init__(self, i, o, clk): class EfinixSDRInput: @staticmethod def lower(dr): - return EfinixSDRInputImpl(dr.i, dr.o, dr.clk) + return EfinixSDRInputImpl(dr.i, dr.o, dr.clk, **dr.kwargs) # Efinix DDRInput ---------------------------------------------------------------------------------- class EfinixDDRInputImpl(LiteXModule): - def __init__(self, i, o1, o2, clk): + def __init__(self, i, o1, o2, clk, in_clk_inv=False): assert_is_signal_or_clocksignal(clk) platform = LiteXContext.platform io_name = platform.get_pin_name(i) @@ -477,7 +477,7 @@ def __init__(self, i, o1, o2, clk): "size" : 1, "in_reg" : "DDIO_RESYNC", "in_clk_pin" : clk, - "in_clk_inv" : 0 + "in_clk_inv" : 1 if in_clk_inv else 0, } platform.toolchain.ifacewriter.blocks.append(block) platform.toolchain.excluded_ios.append(platform.get_pin(i)) @@ -485,7 +485,7 @@ def __init__(self, i, o1, o2, clk): class EfinixDDRInput: @staticmethod def lower(dr): - return EfinixDDRInputImpl(dr.i, dr.o1, dr.o2, dr.clk) + return EfinixDDRInputImpl(dr.i, dr.o1, dr.o2, dr.clk, **dr.kwargs) # Efinix Special Overrides ------------------------------------------------------------------------- From 66e17bedc632993b65cc9edd5c65846639eba8aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Mon, 30 Sep 2024 12:49:04 +0200 Subject: [PATCH 4/4] build: efinix: common: allow different in clk on reg Tristates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit allow a different clk for input on registered Tristates. Signed-off-by: Fin Maaß --- litex/build/efinix/common.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/litex/build/efinix/common.py b/litex/build/efinix/common.py index 34e7ef7982..0e1b23d6f4 100644 --- a/litex/build/efinix/common.py +++ b/litex/build/efinix/common.py @@ -275,7 +275,7 @@ def lower(dr): # Efinix DDRTristate ------------------------------------------------------------------------------- class EfinixDDRTristateImpl(LiteXModule): - def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk, out_clk_inv=False, in_clk_inv=False): + def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk, out_clk_inv=False, in_clk_inv=False, in_clk=None): assert oe1 == oe2 assert_is_signal_or_clocksignal(clk) platform = LiteXContext.platform @@ -301,7 +301,7 @@ def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk, out_clk_inv=False, in_clk_ "properties" : io_prop, "size" : 1, "in_reg" : "DDIO_RESYNC", - "in_clk_pin" : clk, + "in_clk_pin" : clk if in_clk is None else in_clk, "out_reg" : "DDIO_RESYNC", "out_clk_pin" : clk, "oe_reg" : "REG", @@ -320,7 +320,7 @@ def lower(dr): # Efinix SDRTristate ------------------------------------------------------------------------------- class EfinixSDRTristateImpl(LiteXModule): - def __init__(self, io, o, oe, i, clk, out_clk_inv=False, in_clk_inv=False): + def __init__(self, io, o, oe, i, clk, out_clk_inv=False, in_clk_inv=False, in_clk=None): assert_is_signal_or_clocksignal(clk) platform = LiteXContext.platform io_name = platform.get_pin_name(io) @@ -341,7 +341,7 @@ def __init__(self, io, o, oe, i, clk, out_clk_inv=False, in_clk_inv=False): "properties" : io_prop, "size" : 1, "in_reg" : "REG", - "in_clk_pin" : clk, + "in_clk_pin" : clk if in_clk is None else in_clk, "out_reg" : "REG", "out_clk_pin" : clk, "oe_reg" : "REG",