From d6eec8e76d136d36970db4eff9351886a08d65d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Wed, 23 Oct 2024 11:08:58 +0200 Subject: [PATCH 1/4] efinix: ifacewriter: gpio: share common code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit share common code for INPUT, INOUT and OUTPUT. Signed-off-by: Fin Maaß --- litex/build/efinix/ifacewriter.py | 38 ++++--------------------------- 1 file changed, 4 insertions(+), 34 deletions(-) diff --git a/litex/build/efinix/ifacewriter.py b/litex/build/efinix/ifacewriter.py index a8bf638993..e84f651ec1 100644 --- a/litex/build/efinix/ifacewriter.py +++ b/litex/build/efinix/ifacewriter.py @@ -169,38 +169,9 @@ def generate_gpio(self, block, verbose=True): for i, pad in enumerate(block["location"]): cmd += f'design.assign_pkg_pin("{name}[{i}]","{pad}")\n' - if "out_reg" in block: - cmd += f'design.set_property("{name}","OUT_REG","{block["out_reg"]}")\n' - cmd += f'design.set_property("{name}","OUT_CLK_PIN","{block["out_clk_pin"]}")\n' - if "out_delay" in block: - cmd += f'design.set_property("{name}","OUTDELAY","{block["out_delay"]}")\n' - - if "out_clk_inv" in block: - cmd += f'design.set_property("{name}","IS_OUTCLK_INVERTED","{block["out_clk_inv"]}")\n' - - if "in_reg" in block: - cmd += f'design.set_property("{name}","IN_REG","{block["in_reg"]}")\n' - cmd += f'design.set_property("{name}","IN_CLK_PIN","{block["in_clk_pin"]}")\n' - if "in_delay" in block: - cmd += f'design.set_property("{name}","INDELAY","{block["in_delay"]}")\n' - - if "in_clk_inv" in block: - cmd += f'design.set_property("{name}","IS_INCLK_INVERTED","{block["in_clk_inv"]}")\n' - if "oe_reg" in block: cmd += f'design.set_property("{name}","OE_REG","{block["oe_reg"]}")\n' - if "drive_strength" in block: - cmd += 'design.set_property("{}","DRIVE_STRENGTH","{}")\n'.format(name, block["drive_strength"]) - if "slewrate" in block: - cmd += 'design.set_property("{}","SLEWRATE","{}")\n'.format(name, block["slewrate"]) - - if prop: - for p, val in prop: - cmd += 'design.set_property("{}","{}","{}")\n'.format(name, p, val) - cmd += "\n" - return cmd - if mode == "INPUT": if len(block["location"]) == 1: cmd += f'design.create_input_gpio("{name}")\n' @@ -209,6 +180,8 @@ def generate_gpio(self, block, verbose=True): cmd += f'design.create_input_gpio("{name}",{block["size"]-1},0)\n' for i, pad in enumerate(block["location"]): cmd += f'design.assign_pkg_pin("{name}[{i}]","{pad}")\n' + + if mode == "INPUT" or mode == "INOUT": if "in_reg" in block: in_clk_pin = block["in_clk_pin"] if isinstance(in_clk_pin, ClockSignal): @@ -225,11 +198,6 @@ def generate_gpio(self, block, verbose=True): cmd += f'design.set_property("{name}","INDELAY","{block["in_delay"]}")\n' if "in_clk_inv" in block: cmd += f'design.set_property("{name}","IS_INCLK_INVERTED","{block["in_clk_inv"]}")\n' - if prop: - for p, val in prop: - cmd += 'design.set_property("{}","{}","{}")\n'.format(name, p, val) - cmd += "\n" - return cmd if mode == "OUTPUT": if len(block["location"]) == 1: @@ -240,6 +208,7 @@ def generate_gpio(self, block, verbose=True): for i, pad in enumerate(block["location"]): cmd += 'design.assign_pkg_pin("{}[{}]","{}")\n'.format(name, i, pad) + if mode == "OUTPUT" or mode == "INOUT": if "out_reg" in block: cmd += 'design.set_property("{}","OUT_REG","{}")\n'.format(name, block["out_reg"]) cmd += 'design.set_property("{}","OUT_CLK_PIN","{}")\n'.format(name, block["out_clk_pin"]) @@ -254,6 +223,7 @@ def generate_gpio(self, block, verbose=True): if "slewrate" in block: cmd += 'design.set_property("{}","SLEWRATE","{}")\n'.format(name, block["slewrate"]) + if mode == "INOUT" or mode == "INPUT" or mode == "OUTPUT": if prop: for p, val in prop: cmd += 'design.set_property("{}","{}","{}")\n'.format(name, p, val) From 70f4a349e5255e24570f33b9b5569348fdf9dfb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Wed, 23 Oct 2024 11:10:16 +0200 Subject: [PATCH 2/4] efinix: ifacewriter: fix in output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix in OUTPUT Signed-off-by: Fin Maaß --- litex/build/efinix/ifacewriter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/litex/build/efinix/ifacewriter.py b/litex/build/efinix/ifacewriter.py index e84f651ec1..9bf32376e0 100644 --- a/litex/build/efinix/ifacewriter.py +++ b/litex/build/efinix/ifacewriter.py @@ -204,7 +204,7 @@ def generate_gpio(self, block, verbose=True): cmd += 'design.create_output_gpio("{}")\n'.format(name) cmd += 'design.assign_pkg_pin("{}","{}")\n'.format(name, block["location"][0]) else: - cmd += 'design.create_input_gpio("{}",{},0)\n'.format(name, block["size"]-1) + cmd += 'design.create_output_gpio("{}",{},0)\n'.format(name, block["size"]-1) for i, pad in enumerate(block["location"]): cmd += 'design.assign_pkg_pin("{}[{}]","{}")\n'.format(name, i, pad) From 2d96e99494de422dae3c7f6b1e2b21d3692677c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Wed, 23 Oct 2024 11:18:57 +0200 Subject: [PATCH 3/4] build: io: SDRTristate: move check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit check wraped signals instead of before. Signed-off-by: Fin Maaß --- litex/build/io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/litex/build/io.py b/litex/build/io.py index b83cac4780..9ca21baeb7 100644 --- a/litex/build/io.py +++ b/litex/build/io.py @@ -120,13 +120,13 @@ def __init__(self, io, o, oe, i, clk): class SDRTristate(Special): def __init__(self, io, o, oe, i, clk=None): - assert len(i) == len(o) == len(oe) Special.__init__(self) self.io = wrap(io) self.o = wrap(o) self.oe = wrap(oe) self.i = wrap(i) self.clk = wrap(clk) if clk is not None else ClockSignal() + assert len(self.i) == len(self.o) == len(self.oe) def iter_expressions(self): yield self, "io" , SPECIAL_INOUT From 54973eb9cb2c7ed149ab33eb5aabd800a40cf433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Wed, 23 Oct 2024 11:55:22 +0200 Subject: [PATCH 4/4] build: efinix: use constant output option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit use constant output option, when the output is a `Constant` Signed-off-by: Fin Maaß --- litex/build/efinix/common.py | 43 ++++++++++++++++++++++++++----- litex/build/efinix/ifacewriter.py | 6 +++++ 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/litex/build/efinix/common.py b/litex/build/efinix/common.py index 0a3ef4bf91..8229d816b8 100644 --- a/litex/build/efinix/common.py +++ b/litex/build/efinix/common.py @@ -38,6 +38,20 @@ def assert_is_signal_or_clocksignal(obj): assert isinstance(obj, (ClockSignal, Signal)), f"Object {obj} is not a ClockSignal or Signal" +def const_output_calc(o, io): + if o.value == 0: + const_output = 0 + elif len(o) == 1: + const_output = 1 + else: + const_output = [] + for bit in range(len(io)): + if o.value & (1 << bit): + const_output.append(1) + else: + const_output.append(0) + return const_output + # Efinix AsyncResetSynchronizer -------------------------------------------------------------------- class EfinixAsyncResetSynchronizerImpl(LiteXModule): @@ -142,12 +156,16 @@ def __init__(self, io, o, oe, i=None): 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", len(io)) - io_data_o = platform.add_iface_io(io_name + "_IN", len(io)) + if isinstance(o, Constant): + const_output = const_output_calc(o, io) + else: + const_output = "NONE" + io_data_i = platform.add_iface_io(io_name + "_OUT", len(io)) + self.comb += io_data_i.eq(o) io_data_e = platform.add_iface_io(io_name + "_OE", len(io)) - self.comb += io_data_i.eq(o) self.comb += io_data_e.eq(oe) if i is not None: + io_data_o = platform.add_iface_io(io_name + "_IN", len(io)) self.comb += i.eq(io_data_o) block = { "type" : "GPIO", @@ -156,6 +174,7 @@ def __init__(self, io, o, oe, i=None): "location" : io_pad, "properties" : io_prop, "size" : len(io), + "const_output" : const_output, "drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4") } platform.toolchain.ifacewriter.blocks.append(block) @@ -326,10 +345,14 @@ def __init__(self, io, o, oe, i, clk): io_pad = platform.get_pin_location(io) io_prop = platform.get_pin_properties(io) io_prop_dict = dict(io_prop) - io_data_i = platform.add_iface_io(io_name + "_OUT") + if isinstance(o, Constant): + const_output = const_output_calc(o, io) + else: + const_output = "NONE" + io_data_i = platform.add_iface_io(io_name + "_OUT") + self.comb += io_data_i.eq(o) 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) self.comb += i.eq(io_data_o) block = { @@ -343,6 +366,7 @@ def __init__(self, io, o, oe, i, clk): "in_clk_pin" : clk, "out_reg" : "REG", "out_clk_pin" : clk, + "const_output" : const_output, "oe_reg" : "REG", "in_clk_inv" : 0, "out_clk_inv" : 0, @@ -367,8 +391,12 @@ def __init__(self, i, o, clk): io_pad = platform.get_pin_location(o) io_prop = platform.get_pin_properties(o) io_prop_dict = dict(io_prop) - io_data_i = platform.add_iface_io(io_name) - self.comb += io_data_i.eq(i) + if isinstance(i, Constant): + const_output = const_output_calc(i, o) + else: + const_output = "NONE" + io_data_i = platform.add_iface_io(io_name) + self.comb += io_data_i.eq(i) block = { "type" : "GPIO", "mode" : "OUTPUT", @@ -378,6 +406,7 @@ def __init__(self, i, o, clk): "size" : 1, "out_reg" : "REG", "out_clk_pin" : clk, + "const_output" : const_output, "out_clk_inv" : 0, "drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4") } diff --git a/litex/build/efinix/ifacewriter.py b/litex/build/efinix/ifacewriter.py index 9bf32376e0..ef65fc21b0 100644 --- a/litex/build/efinix/ifacewriter.py +++ b/litex/build/efinix/ifacewriter.py @@ -222,6 +222,12 @@ def generate_gpio(self, block, verbose=True): cmd += 'design.set_property("{}","DRIVE_STRENGTH","{}")\n'.format(name, block["drive_strength"]) if "slewrate" in block: cmd += 'design.set_property("{}","SLEWRATE","{}")\n'.format(name, block["slewrate"]) + if "const_output" in block: + if not isinstance(block["const_output"], list): + cmd += f'design.set_property("{name}","CONST_OUTPUT","{block["const_output"]}")\n' + else: + for i, val in enumerate(block["const_output"]): + cmd += f'design.set_property("{name}[{i}]","CONST_OUTPUT","{val}")\n' if mode == "INOUT" or mode == "INPUT" or mode == "OUTPUT": if prop: