diff --git a/litex/build/efinix/common.py b/litex/build/efinix/common.py index 0c62ac34e..2ee986884 100644 --- a/litex/build/efinix/common.py +++ b/litex/build/efinix/common.py @@ -69,6 +69,7 @@ class EfinixTristateImpl(Module): 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") @@ -81,6 +82,7 @@ class EfinixTristateImpl(Module): "mode" : "INOUT", "name" : io_name, "location" : [io_loc[0]], + "properties" : io_prop } platform.toolchain.ifacewriter.blocks.append(block) diff --git a/litex/build/efinix/ifacewriter.py b/litex/build/efinix/ifacewriter.py index 4fed01f40..5957d138f 100644 --- a/litex/build/efinix/ifacewriter.py +++ b/litex/build/efinix/ifacewriter.py @@ -108,6 +108,7 @@ design.create("{2}", "{3}", "./../gateware", overwrite=True) def generate_gpio(self, block, verbose=True): name = block["name"] mode = block["mode"] + prop = block["properties"] cmd = "" if mode == "INOUT": @@ -118,6 +119,9 @@ design.create("{2}", "{3}", "./../gateware", overwrite=True) cmd += f'design.create_inout_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 prop: + for p, val in prop: + cmd += 'design.set_property("{}","{}","{}")\n'.format(name, p, val) cmd += "\n" return cmd @@ -132,6 +136,10 @@ design.create("{2}", "{3}", "./../gateware", overwrite=True) 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 prop: + for p, val in prop: + cmd += 'design.set_property("{}","{}","{}")\n'.format(name, p, val) + cmd += "\n" return cmd if mode == "OUTPUT": @@ -150,6 +158,9 @@ design.create("{2}", "{3}", "./../gateware", overwrite=True) if "drive_strength" in block: cmd += 'design.set_property("{}","DRIVE_STRENGTH","4")\n'.format(name, block["drive_strength"]) + if prop: + for p, val in prop: + cmd += 'design.set_property("{}","{}","{}")\n'.format(name, p, val) cmd += "\n" return cmd @@ -157,12 +168,20 @@ design.create("{2}", "{3}", "./../gateware", overwrite=True) cmd += 'design.create_input_clock_gpio("{}")\n'.format(name) cmd += 'design.set_property("{}","IN_PIN","{}")\n'.format(name, name) cmd += 'design.assign_pkg_pin("{}","{}")\n\n'.format(name, block["location"]) + if prop: + for p, val in prop: + cmd += 'design.set_property("{}","{}","{}")\n'.format(name, p, val) + cmd += "\n" return cmd if mode == "OUTPUT_CLK": 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 prop: + for p, val in prop: + cmd += 'design.set_property("{}","{}","{}")\n'.format(name, p, val) + cmd += "\n" return cmd cmd = "# TODO: " + str(block) +"\n" diff --git a/litex/build/efinix/platform.py b/litex/build/efinix/platform.py index 81f36d6c7..67ed060cb 100644 --- a/litex/build/efinix/platform.py +++ b/litex/build/efinix/platform.py @@ -86,7 +86,36 @@ class EfinixPlatform(GenericPlatform): return [pins[idx]] return None - def get_pin_name(self, sig): + def get_pin_properties(self, sig): + ret = [] + if sig is None: + return None + assert len(sig) == 1 + + if isinstance(sig, _Slice): + sig = sig.value + sc = self.constraint_manager.get_sig_constraints() + for s, pins, others, resource in sc: + if (s == sig) and (pins[0] != 'X'): + for o in others: + if isinstance(o, IOStandard): + ret.append(('IO_STANDARD', o.name)) + if isinstance(o, Misc): + if o.misc in ["WEAK_PULLUP", "WEAK_PULLDOWN"]: + prop = "PULL_OPTION" + val = o.misc + if "DRIVE_STRENGTH" in o.misc: + prop = "DRIVE_STRENGTH" + val = o.misc.split("=")[1] + ret.append((prop, val)) + if "SLEWRATE" in o.misc: + prop = "SLEW_RATE" + val = "1" + ret.append((prop, val)) + return ret + return None + + def get_pin_name(self, sig, without_index=False): if sig is None: return None assert len(sig) == 1