parent
b0ef53e095
commit
c77274c1ad
72
nmigen/vendor/lattice_ecp5.py
vendored
72
nmigen/vendor/lattice_ecp5.py
vendored
|
@ -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,
|
||||
|
|
56
nmigen/vendor/lattice_ice40.py
vendored
56
nmigen/vendor/lattice_ice40.py
vendored
|
@ -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
|
||||
|
|
70
nmigen/vendor/xilinx_7series.py
vendored
70
nmigen/vendor/xilinx_7series.py
vendored
|
@ -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]
|
||||
)
|
||||
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
|
||||
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]
|
||||
)
|
||||
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,
|
||||
|
|
66
nmigen/vendor/xilinx_spartan_3_6.py
vendored
66
nmigen/vendor/xilinx_spartan_3_6.py
vendored
|
@ -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]
|
||||
)
|
||||
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
|
||||
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]
|
||||
)
|
||||
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,
|
||||
|
|
Loading…
Reference in a new issue