From c77274c1ad96ca92b844dba76f4ed46266d5d017 Mon Sep 17 00:00:00 2001 From: whitequark Date: Thu, 22 Aug 2019 20:54:42 +0000 Subject: [PATCH] vendor: eliminate unnecessary LUT instantiation. Fixes #165. --- nmigen/vendor/lattice_ecp5.py | 72 +++++++++++------------------ nmigen/vendor/lattice_ice40.py | 56 ++++++++++++---------- nmigen/vendor/xilinx_7series.py | 70 ++++++++++++---------------- nmigen/vendor/xilinx_spartan_3_6.py | 66 +++++++++++--------------- 4 files changed, 115 insertions(+), 149 deletions(-) diff --git a/nmigen/vendor/lattice_ecp5.py b/nmigen/vendor/lattice_ecp5.py index 0a31919..833cd7b 100644 --- a/nmigen/vendor/lattice_ecp5.py +++ b/nmigen/vendor/lattice_ecp5.py @@ -148,7 +148,7 @@ class LatticeECP5Platform(TemplatedPlatform): return True return False - def _get_xdr_buffer(self, m, pin, i_invert=None, o_invert=None): + def _get_xdr_buffer(self, m, pin, *, i_invert=False, o_invert=False): def get_ireg(clk, d, q): for bit in range(len(q)): m.submodules += Instance("IFS1P3DX", @@ -187,50 +187,34 @@ class LatticeECP5Platform(TemplatedPlatform): o_Q=q[bit] ) - def get_ixor(z, invert): - if invert is None: - return z - else: - a = Signal.like(z, name_suffix="_x{}".format(1 if invert else 0)) - for bit in range(len(z)): - m.submodules += Instance("LUT4", - p_INIT=0x5555 if invert else 0xaaaa, - i_A=a[bit], - i_B=Const(0), - i_C=Const(0), - i_D=Const(0), - o_Z=z[bit] - ) + def get_ineg(y, invert): + if invert: + a = Signal.like(y, name_suffix="_n") + m.d.comb += y.eq(~a) return a + else: + return y - def get_oxor(a, invert): - if invert is None: - return a + def get_oneg(a, invert): + if invert: + y = Signal.like(a, name_suffix="_n") + m.d.comb += y.eq(~a) + return y else: - z = Signal.like(a, name_suffix="_x{}".format(1 if invert else 0)) - for bit in range(len(a)): - m.submodules += Instance("LUT4", - p_INIT=0x5555 if invert else 0xaaaa, - i_A=a[bit], - i_B=Const(0), - i_C=Const(0), - i_D=Const(0), - o_Z=z[bit] - ) - return z + return a if "i" in pin.dir: if pin.xdr < 2: - pin_i = get_ixor(pin.i, i_invert) + pin_i = get_ineg(pin.i, i_invert) elif pin.xdr == 2: - pin_i0 = get_ixor(pin.i0, i_invert) - pin_i1 = get_ixor(pin.i1, i_invert) + pin_i0 = get_ineg(pin.i0, i_invert) + pin_i1 = get_ineg(pin.i1, i_invert) if "o" in pin.dir: if pin.xdr < 2: - pin_o = get_oxor(pin.o, o_invert) + pin_o = get_oneg(pin.o, o_invert) elif pin.xdr == 2: - pin_o0 = get_oxor(pin.o0, o_invert) - pin_o1 = get_oxor(pin.o1, o_invert) + pin_o0 = get_oneg(pin.o0, o_invert) + pin_o1 = get_oneg(pin.o1, o_invert) i = o = t = None if "i" in pin.dir: @@ -274,7 +258,7 @@ class LatticeECP5Platform(TemplatedPlatform): self._check_feature("single-ended input", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, i_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, i_invert=invert) for bit in range(len(port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("IB", i_I=port[bit], @@ -286,7 +270,7 @@ class LatticeECP5Platform(TemplatedPlatform): self._check_feature("single-ended output", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, o_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, o_invert=invert) for bit in range(len(port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("OB", i_I=o[bit], @@ -298,7 +282,7 @@ class LatticeECP5Platform(TemplatedPlatform): self._check_feature("single-ended tristate", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, o_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, o_invert=invert) for bit in range(len(port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("OBZ", i_T=t, @@ -311,8 +295,7 @@ class LatticeECP5Platform(TemplatedPlatform): self._check_feature("single-ended input/output", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, i_invert=True if invert else None, - o_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, i_invert=invert, o_invert=invert) for bit in range(len(port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("BB", i_T=t, @@ -326,7 +309,7 @@ class LatticeECP5Platform(TemplatedPlatform): self._check_feature("differential input", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, i_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, i_invert=invert) for bit in range(len(p_port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("IB", i_I=p_port[bit], @@ -338,7 +321,7 @@ class LatticeECP5Platform(TemplatedPlatform): self._check_feature("differential output", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, o_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, o_invert=invert) for bit in range(len(p_port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("OB", i_I=o[bit], @@ -350,7 +333,7 @@ class LatticeECP5Platform(TemplatedPlatform): self._check_feature("differential tristate", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, o_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, o_invert=invert) for bit in range(len(p_port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("OBZ", i_T=t, @@ -363,8 +346,7 @@ class LatticeECP5Platform(TemplatedPlatform): self._check_feature("differential input/output", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, i_invert=True if invert else None, - o_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, i_invert=invert, o_invert=invert) for bit in range(len(p_port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("BB", i_T=t, diff --git a/nmigen/vendor/lattice_ice40.py b/nmigen/vendor/lattice_ice40.py index 5c1880b..21e9297 100644 --- a/nmigen/vendor/lattice_ice40.py +++ b/nmigen/vendor/lattice_ice40.py @@ -174,7 +174,8 @@ class LatticeICE40Platform(TemplatedPlatform): return True return False - def _get_io_buffer(self, m, pin, port, attrs, i_invert=None, o_invert=None): + def _get_io_buffer(self, m, pin, port, attrs, *, i_invert=False, o_invert=False, + invert_lut=False): def get_dff(clk, d, q): m.submodules += Instance("$dff", p_CLK_POLARITY=1, @@ -183,35 +184,43 @@ class LatticeICE40Platform(TemplatedPlatform): i_D=d, o_Q=q) - def get_ixor(y, invert): - if invert is None: - return y - else: + def get_ineg(y, invert): + if invert_lut: a = Signal.like(y, name_suffix="_x{}".format(1 if invert else 0)) for bit in range(len(y)): m.submodules += Instance("SB_LUT4", - p_LUT_INIT=0b01 if invert else 0b10, + p_LUT_INIT=Const(0b01 if invert else 0b10, 16), i_I0=a[bit], i_I1=Const(0), i_I2=Const(0), i_I3=Const(0), o_O=y[bit]) return a - - def get_oxor(a, invert): - if invert is None: + elif invert: + a = Signal.like(y, name_suffix="_n") + m.d.comb += y.eq(~a) return a else: + return y + + def get_oneg(a, invert): + if invert_lut: y = Signal.like(a, name_suffix="_x{}".format(1 if invert else 0)) for bit in range(len(a)): m.submodules += Instance("SB_LUT4", - p_LUT_INIT=0b01 if invert else 0b10, + p_LUT_INIT=Const(0b01 if invert else 0b10, 16), i_I0=a[bit], i_I1=Const(0), i_I2=Const(0), i_I3=Const(0), o_O=y[bit]) return y + elif invert: + y = Signal.like(a, name_suffix="_n") + m.d.comb += y.eq(~a) + return y + else: + return a if "GLOBAL" in attrs: is_global_input = bool(attrs["GLOBAL"]) @@ -222,16 +231,16 @@ class LatticeICE40Platform(TemplatedPlatform): if "i" in pin.dir: if pin.xdr < 2: - pin_i = get_ixor(pin.i, i_invert) + pin_i = get_ineg(pin.i, i_invert) elif pin.xdr == 2: - pin_i0 = get_ixor(pin.i0, i_invert) - pin_i1 = get_ixor(pin.i1, i_invert) + pin_i0 = get_ineg(pin.i0, i_invert) + pin_i1 = get_ineg(pin.i1, i_invert) if "o" in pin.dir: if pin.xdr < 2: - pin_o = get_oxor(pin.o, o_invert) + pin_o = get_oneg(pin.o, o_invert) elif pin.xdr == 2: - pin_o0 = get_oxor(pin.o0, o_invert) - pin_o1 = get_oxor(pin.o1, o_invert) + pin_o0 = get_oneg(pin.o0, o_invert) + pin_o1 = get_oneg(pin.o1, o_invert) if "i" in pin.dir and pin.xdr == 2: i0_ff = Signal.like(pin_i0, name_suffix="_ff") @@ -310,29 +319,28 @@ class LatticeICE40Platform(TemplatedPlatform): self._check_feature("single-ended input", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - self._get_io_buffer(m, pin, port, attrs, i_invert=True if invert else None) + self._get_io_buffer(m, pin, port, attrs, i_invert=invert) return m def get_output(self, pin, port, attrs, invert): self._check_feature("single-ended output", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - self._get_io_buffer(m, pin, port, attrs, o_invert=True if invert else None) + self._get_io_buffer(m, pin, port, attrs, o_invert=invert) return m def get_tristate(self, pin, port, attrs, invert): self._check_feature("single-ended tristate", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - self._get_io_buffer(m, pin, port, attrs, o_invert=True if invert else None) + self._get_io_buffer(m, pin, port, attrs, o_invert=invert) return m def get_input_output(self, pin, port, attrs, invert): self._check_feature("single-ended input/output", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - self._get_io_buffer(m, pin, port, attrs, i_invert=True if invert else None, - o_invert=True if invert else None) + self._get_io_buffer(m, pin, port, attrs, i_invert=invert, o_invert=invert) return m def get_diff_input(self, pin, p_port, n_port, attrs, invert): @@ -340,7 +348,7 @@ class LatticeICE40Platform(TemplatedPlatform): valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() # See comment in should_skip_port_component above. - self._get_io_buffer(m, pin, p_port, attrs, i_invert=True if invert else None) + self._get_io_buffer(m, pin, p_port, attrs, i_invert=invert) return m def get_diff_output(self, pin, p_port, n_port, attrs, invert): @@ -351,8 +359,8 @@ class LatticeICE40Platform(TemplatedPlatform): # output pin. The inverter introduces a delay, so for a non-inverting output pin, # an identical delay is introduced by instantiating a LUT. This makes the waveform # perfectly symmetric in the xdr=0 case. - self._get_io_buffer(m, pin, p_port, attrs, o_invert=invert) - self._get_io_buffer(m, pin, n_port, attrs, o_invert=not invert) + self._get_io_buffer(m, pin, p_port, attrs, o_invert= invert, invert_lut=True) + self._get_io_buffer(m, pin, n_port, attrs, o_invert=not invert, invert_lut=True) return m # Tristate and bidirectional buffers are not supported on iCE40 because it requires external diff --git a/nmigen/vendor/xilinx_7series.py b/nmigen/vendor/xilinx_7series.py index a7620ec..be59017 100644 --- a/nmigen/vendor/xilinx_7series.py +++ b/nmigen/vendor/xilinx_7series.py @@ -143,14 +143,14 @@ class Xilinx7SeriesPlatform(TemplatedPlatform): m.d.comb += ResetSignal("sync").eq(rst_i) return m - def _get_xdr_buffer(self, m, pin, i_invert=None, o_invert=None): + def _get_xdr_buffer(self, m, pin, *, i_invert=False, o_invert=False): def get_dff(clk, d, q): # SDR I/O is performed by packing a flip-flop into the pad IOB. for bit in range(len(q)): _q = Signal() _q.attrs["IOB"] = "TRUE" - # XXX: Vivado 2019.1 seems to make this flip-flop ineligible for IOB packing - # unless we prevent it from being optimized. + # Vivado 2019.1 seems to make this flip-flop ineligible for IOB packing unless + # we prevent it from being optimized. _q.attrs["DONT_TOUCH"] = "TRUE" m.submodules += Instance("FDCE", i_C=clk, @@ -187,44 +187,34 @@ class Xilinx7SeriesPlatform(TemplatedPlatform): o_Q=q[bit] ) - def get_ixor(y, invert): - if invert is None: - return y - else: - a = Signal.like(y, name_suffix="_x{}".format(1 if invert else 0)) - for bit in range(len(y)): - m.submodules += Instance("LUT1", - p_INIT=0b01 if invert else 0b10, - i_I0=a[bit], - o_O=y[bit] - ) - return a - - def get_oxor(a, invert): - if invert is None: + def get_ineg(y, invert): + if invert: + a = Signal.like(y, name_suffix="_n") + m.d.comb += y.eq(~a) return a else: - y = Signal.like(a, name_suffix="_x{}".format(1 if invert else 0)) - for bit in range(len(a)): - m.submodules += Instance("LUT1", - p_INIT=0b01 if invert else 0b10, - i_I0=a[bit], - o_O=y[bit] - ) return y + def get_oneg(a, invert): + if invert: + y = Signal.like(a, name_suffix="_n") + m.d.comb += y.eq(~a) + return y + else: + return a + if "i" in pin.dir: if pin.xdr < 2: - pin_i = get_ixor(pin.i, i_invert) + pin_i = get_ineg(pin.i, i_invert) elif pin.xdr == 2: - pin_i0 = get_ixor(pin.i0, i_invert) - pin_i1 = get_ixor(pin.i1, i_invert) + pin_i0 = get_ineg(pin.i0, i_invert) + pin_i1 = get_ineg(pin.i1, i_invert) if "o" in pin.dir: if pin.xdr < 2: - pin_o = get_oxor(pin.o, o_invert) + pin_o = get_oneg(pin.o, o_invert) elif pin.xdr == 2: - pin_o0 = get_oxor(pin.o0, o_invert) - pin_o1 = get_oxor(pin.o1, o_invert) + pin_o0 = get_oneg(pin.o0, o_invert) + pin_o1 = get_oneg(pin.o1, o_invert) i = o = t = None if "i" in pin.dir: @@ -264,7 +254,7 @@ class Xilinx7SeriesPlatform(TemplatedPlatform): self._check_feature("single-ended input", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, i_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, i_invert=invert) for bit in range(len(port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("IBUF", i_I=port[bit], @@ -276,7 +266,7 @@ class Xilinx7SeriesPlatform(TemplatedPlatform): self._check_feature("single-ended output", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, o_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, o_invert=invert) for bit in range(len(port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("OBUF", i_I=o[bit], @@ -288,7 +278,7 @@ class Xilinx7SeriesPlatform(TemplatedPlatform): self._check_feature("single-ended tristate", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, o_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, o_invert=invert) for bit in range(len(port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("OBUFT", i_T=t, @@ -301,8 +291,7 @@ class Xilinx7SeriesPlatform(TemplatedPlatform): self._check_feature("single-ended input/output", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, i_invert=True if invert else None, - o_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, i_invert=invert, o_invert=invert) for bit in range(len(port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("IOBUF", i_T=t, @@ -316,7 +305,7 @@ class Xilinx7SeriesPlatform(TemplatedPlatform): self._check_feature("differential input", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, i_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, i_invert=invert) for bit in range(len(p_port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("IBUFDS", i_I=p_port[bit], i_IB=n_port[bit], @@ -328,7 +317,7 @@ class Xilinx7SeriesPlatform(TemplatedPlatform): self._check_feature("differential output", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, o_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, o_invert=invert) for bit in range(len(p_port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("OBUFDS", i_I=o[bit], @@ -340,7 +329,7 @@ class Xilinx7SeriesPlatform(TemplatedPlatform): self._check_feature("differential tristate", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, o_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, o_invert=invert) for bit in range(len(p_port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("OBUFTDS", i_T=t, @@ -353,8 +342,7 @@ class Xilinx7SeriesPlatform(TemplatedPlatform): self._check_feature("differential input/output", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, i_invert=True if invert else None, - o_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, i_invert=invert, o_invert=invert) for bit in range(len(p_port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("IOBUFDS", i_T=t, diff --git a/nmigen/vendor/xilinx_spartan_3_6.py b/nmigen/vendor/xilinx_spartan_3_6.py index bda5116..050a3e3 100644 --- a/nmigen/vendor/xilinx_spartan_3_6.py +++ b/nmigen/vendor/xilinx_spartan_3_6.py @@ -193,7 +193,7 @@ class XilinxSpartan3Or6Platform(TemplatedPlatform): m.d.comb += ResetSignal("sync").eq(rst_i) return m - def _get_xdr_buffer(self, m, pin, i_invert=None, o_invert=None): + def _get_xdr_buffer(self, m, pin, *, i_invert=False, o_invert=False): def get_dff(clk, d, q): # SDR I/O is performed by packing a flip-flop into the pad IOB. for bit in range(len(q)): @@ -234,44 +234,34 @@ class XilinxSpartan3Or6Platform(TemplatedPlatform): o_Q=q[bit] ) - def get_ixor(y, invert): - if invert is None: - return y - else: - a = Signal.like(y, name_suffix="_x{}".format(1 if invert else 0)) - for bit in range(len(y)): - m.submodules += Instance("LUT1", - p_INIT=0b01 if invert else 0b10, - i_I0=a[bit], - o_O=y[bit] - ) - return a - - def get_oxor(a, invert): - if invert is None: + def get_ineg(y, invert): + if invert: + a = Signal.like(y, name_suffix="_n") + m.d.comb += y.eq(~a) return a else: - y = Signal.like(a, name_suffix="_x{}".format(1 if invert else 0)) - for bit in range(len(a)): - m.submodules += Instance("LUT1", - p_INIT=0b01 if invert else 0b10, - i_I0=a[bit], - o_O=y[bit] - ) return y + def get_oneg(a, invert): + if invert: + y = Signal.like(a, name_suffix="_n") + m.d.comb += y.eq(~a) + return y + else: + return a + if "i" in pin.dir: if pin.xdr < 2: - pin_i = get_ixor(pin.i, i_invert) + pin_i = get_ineg(pin.i, i_invert) elif pin.xdr == 2: - pin_i0 = get_ixor(pin.i0, i_invert) - pin_i1 = get_ixor(pin.i1, i_invert) + pin_i0 = get_ineg(pin.i0, i_invert) + pin_i1 = get_ineg(pin.i1, i_invert) if "o" in pin.dir: if pin.xdr < 2: - pin_o = get_oxor(pin.o, o_invert) + pin_o = get_oneg(pin.o, o_invert) elif pin.xdr == 2: - pin_o0 = get_oxor(pin.o0, o_invert) - pin_o1 = get_oxor(pin.o1, o_invert) + pin_o0 = get_oneg(pin.o0, o_invert) + pin_o1 = get_oneg(pin.o1, o_invert) i = o = t = None if "i" in pin.dir: @@ -315,7 +305,7 @@ class XilinxSpartan3Or6Platform(TemplatedPlatform): self._check_feature("single-ended input", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, i_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, i_invert=invert) for bit in range(len(port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("IBUF", i_I=port[bit], @@ -327,7 +317,7 @@ class XilinxSpartan3Or6Platform(TemplatedPlatform): self._check_feature("single-ended output", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, o_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, o_invert=invert) for bit in range(len(port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("OBUF", i_I=o[bit], @@ -339,7 +329,7 @@ class XilinxSpartan3Or6Platform(TemplatedPlatform): self._check_feature("single-ended tristate", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, o_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, o_invert=invert) for bit in range(len(port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("OBUFT", i_T=t, @@ -352,8 +342,7 @@ class XilinxSpartan3Or6Platform(TemplatedPlatform): self._check_feature("single-ended input/output", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, i_invert=True if invert else None, - o_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, i_invert=invert, o_invert=invert) for bit in range(len(port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("IOBUF", i_T=t, @@ -367,7 +356,7 @@ class XilinxSpartan3Or6Platform(TemplatedPlatform): self._check_feature("differential input", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, i_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, i_invert=invert) for bit in range(len(p_port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("IBUFDS", i_I=p_port[bit], i_IB=n_port[bit], @@ -379,7 +368,7 @@ class XilinxSpartan3Or6Platform(TemplatedPlatform): self._check_feature("differential output", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, o_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, o_invert=invert) for bit in range(len(p_port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("OBUFDS", i_I=o[bit], @@ -391,7 +380,7 @@ class XilinxSpartan3Or6Platform(TemplatedPlatform): self._check_feature("differential tristate", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, o_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, o_invert=invert) for bit in range(len(p_port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("OBUFTDS", i_T=t, @@ -404,8 +393,7 @@ class XilinxSpartan3Or6Platform(TemplatedPlatform): self._check_feature("differential input/output", pin, attrs, valid_xdrs=(0, 1, 2), valid_attrs=True) m = Module() - i, o, t = self._get_xdr_buffer(m, pin, i_invert=True if invert else None, - o_invert=True if invert else None) + i, o, t = self._get_xdr_buffer(m, pin, i_invert=invert, o_invert=invert) for bit in range(len(p_port)): m.submodules["{}_{}".format(pin.name, bit)] = Instance("IOBUFDS", i_T=t, -- 2.30.2