mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
build: common: extend SDR/DDR
extend SDR/DDR variants to support Signals longer than 1. Signed-off-by: Fin Maaß <f.maass@vogl-electronic.com>
This commit is contained in:
parent
0d40708eaf
commit
fd6c9f8363
6 changed files with 346 additions and 306 deletions
|
@ -91,13 +91,14 @@ class AlteraDifferentialOutput:
|
|||
|
||||
class AlteraDDROutputImpl(Module):
|
||||
def __init__(self, i1, i2, o, clk):
|
||||
self.specials += Instance("ALTDDIO_OUT",
|
||||
p_WIDTH = 1,
|
||||
i_outclock = clk,
|
||||
i_datain_h = i1,
|
||||
i_datain_l = i2,
|
||||
o_dataout = o,
|
||||
)
|
||||
for j in range(len(o)):
|
||||
self.specials += Instance("ALTDDIO_OUT",
|
||||
p_WIDTH = 1,
|
||||
i_outclock = clk,
|
||||
i_datain_h = i1[j] if len(i1) > 1 else i1,
|
||||
i_datain_l = i2[j] if len(i2) > 1 else i2,
|
||||
o_dataout = o[j] if len(o) > 1 else o,
|
||||
)
|
||||
|
||||
class AlteraDDROutput:
|
||||
@staticmethod
|
||||
|
@ -108,13 +109,14 @@ class AlteraDDROutput:
|
|||
|
||||
class AlteraDDRInputImpl(Module):
|
||||
def __init__(self, i, o1, o2, clk):
|
||||
self.specials += Instance("ALTDDIO_IN",
|
||||
p_WIDTH = 1,
|
||||
i_inclock = clk,
|
||||
i_datain = i,
|
||||
o_dataout_h = o1,
|
||||
o_dataout_l = o2
|
||||
)
|
||||
for j in range(len(i)):
|
||||
self.specials += Instance("ALTDDIO_IN",
|
||||
p_WIDTH = 1,
|
||||
i_inclock = clk,
|
||||
i_datain = i[j] if len(i) > 1 else i,
|
||||
o_dataout_h = o1[j] if len(o1) > 1 else o1,
|
||||
o_dataout_l = o2[j] if len(o2) > 1 else o2,
|
||||
)
|
||||
|
||||
class AlteraDDRInput:
|
||||
@staticmethod
|
||||
|
@ -169,18 +171,19 @@ class Agilex5AsyncResetSynchronizer:
|
|||
|
||||
class Agilex5DDROutputImpl(Module):
|
||||
def __init__(self, i1, i2, o, clk):
|
||||
self.specials += Instance("tennm_ph2_ddio_out",
|
||||
p_mode = "MODE_DDR",
|
||||
p_asclr_ena = "ASCLR_ENA_NONE",
|
||||
p_sclr_ena = "SCLR_ENA_NONE",
|
||||
o_dataout = o,
|
||||
i_datainlo = i2,
|
||||
i_datainhi = i1,
|
||||
i_clk = clk,
|
||||
i_ena = Constant(1, 1),
|
||||
i_areset = Constant(1, 1),
|
||||
i_sreset = Constant(1, 1),
|
||||
)
|
||||
for j in range(len(o)):
|
||||
self.specials += Instance("tennm_ph2_ddio_out",
|
||||
p_mode = "MODE_DDR",
|
||||
p_asclr_ena = "ASCLR_ENA_NONE",
|
||||
p_sclr_ena = "SCLR_ENA_NONE",
|
||||
o_dataout = o[j] if len(o) > 1 else o,
|
||||
i_datainlo = i2[j] if len(i2) > 1 else i2,
|
||||
i_datainhi = i1[j] if len(i1) > 1 else i1,
|
||||
i_clk = clk,
|
||||
i_ena = Constant(1, 1),
|
||||
i_areset = Constant(1, 1),
|
||||
i_sreset = Constant(1, 1),
|
||||
)
|
||||
|
||||
class Agilex5DDROutput:
|
||||
@staticmethod
|
||||
|
@ -191,18 +194,19 @@ class Agilex5DDROutput:
|
|||
|
||||
class Agilex5DDRInputImpl(Module):
|
||||
def __init__(self, i, o1, o2, clk):
|
||||
self.specials += Instance("tennm_ph2_ddio_in",
|
||||
p_mode = "MODE_DDR",
|
||||
p_asclr_ena = "ASCLR_ENA_NONE",
|
||||
p_sclr_ena = "SCLR_ENA_NONE",
|
||||
i_clk = clk,
|
||||
i_datain = i,
|
||||
o_regouthi = o1,
|
||||
o_regoutlo = o2,
|
||||
i_ena = Constant(1, 1),
|
||||
i_areset = Constant(1, 1),
|
||||
i_sreset = Constant(1, 1),
|
||||
)
|
||||
for j in range(len(i)):
|
||||
self.specials += Instance("tennm_ph2_ddio_in",
|
||||
p_mode = "MODE_DDR",
|
||||
p_asclr_ena = "ASCLR_ENA_NONE",
|
||||
p_sclr_ena = "SCLR_ENA_NONE",
|
||||
i_clk = clk,
|
||||
i_datain = i[j] if len(i) > 1 else i,
|
||||
o_regouthi = o1[j] if len(o1) > 1 else o1,
|
||||
o_regoutlo = o2[j] if len(o2) > 1 else o2,
|
||||
i_ena = Constant(1, 1),
|
||||
i_areset = Constant(1, 1),
|
||||
i_sreset = Constant(1, 1),
|
||||
)
|
||||
|
||||
class Agilex5DDRInput:
|
||||
@staticmethod
|
||||
|
@ -227,26 +231,30 @@ class Agilex5SDRInput:
|
|||
|
||||
class Agilex5SDRTristateImpl(Module):
|
||||
def __init__(self, io, o, oe, i, clk):
|
||||
_i = Signal()
|
||||
_o = Signal()
|
||||
_oe = Signal()
|
||||
_i = Signal().like(i)
|
||||
_o = Signal().like(o)
|
||||
_oe = Signal().like(oe)
|
||||
self.specials += [
|
||||
SDRIO(o, _o, clk),
|
||||
SDRIO(oe, _oe, clk),
|
||||
SDRIO(_i, i, clk),
|
||||
Instance("tennm_ph2_io_ibuf",
|
||||
p_bus_hold = "BUS_HOLD_OFF",
|
||||
io_i = io, # FIXME: its an input but io is needed to have correct dir at top module
|
||||
o_o = _i,
|
||||
),
|
||||
Instance("tennm_ph2_io_obuf",
|
||||
p_open_drain = "OPEN_DRAIN_OFF",
|
||||
i_i = _o,
|
||||
i_oe = _oe,
|
||||
io_o = io, # FIXME: its an output but io is needed to have correct dir at top module
|
||||
),
|
||||
SDRIO(_i, i, clk)
|
||||
]
|
||||
|
||||
for j in range(len(io)):
|
||||
self.specials += [
|
||||
Instance("tennm_ph2_io_ibuf",
|
||||
p_bus_hold = "BUS_HOLD_OFF",
|
||||
io_i = io[j] if len(io) > 1 else io , # FIXME: its an input but io is needed to have correct dir at top module
|
||||
o_o = _i[j] if len(_i) > 1 else _i,
|
||||
),
|
||||
Instance("tennm_ph2_io_obuf",
|
||||
p_open_drain = "OPEN_DRAIN_OFF",
|
||||
i_i = _o[j] if len(_o) > 1 else _o,
|
||||
i_oe = _oe[j] if len(_oe) > 1 else _oe,
|
||||
io_o = io[j] if len(io) > 1 else io, # FIXME: its an output but io is needed to have correct dir at top module
|
||||
),
|
||||
]
|
||||
|
||||
class Agilex5SDRTristate(Module):
|
||||
@staticmethod
|
||||
def lower(dr):
|
||||
|
|
|
@ -46,30 +46,32 @@ class CologneChipAsyncResetSynchronizer:
|
|||
|
||||
class CologneChipDDRInputImpl(Module):
|
||||
def __init__(self, i, o1, o2, clk):
|
||||
self.specials += Instance("CC_IDDR",
|
||||
i_CLK = clk,
|
||||
i_D = i,
|
||||
o_Q0 = o1,
|
||||
o_Q1 = o2,
|
||||
)
|
||||
for j in range(len(i)):
|
||||
self.specials += Instance("CC_IDDR",
|
||||
i_CLK = clk,
|
||||
i_D = i[j] if len(i) > 1 else i,
|
||||
o_Q0 = o1[j] if len(o1) > 1 else o1,
|
||||
o_Q1 = o2[j] if len(o2) > 1 else o2,
|
||||
)
|
||||
|
||||
class CologneChipDDRInput:
|
||||
@staticmethod
|
||||
def lower(dr):
|
||||
return CologneChipInputImpl(dr.i, dr.o1, dr.o2, dr.clk)
|
||||
return CologneChipDDRInputImpl(dr.i, dr.o1, dr.o2, dr.clk)
|
||||
|
||||
# CologneChip DDR Output ---------------------------------------------------------------------------
|
||||
|
||||
class CologneChipDDROutputImpl(Module):
|
||||
def __init__(self, i1, i2, o, clk):
|
||||
self.specials += Instance("CC_ODDR",
|
||||
p_CLK_INV = 0,
|
||||
i_CLK = clk,
|
||||
i_DDR = ~clk,
|
||||
i_D0 = i1,
|
||||
i_D1 = i2,
|
||||
o_Q = o,
|
||||
)
|
||||
for j in range(len(o)):
|
||||
self.specials += Instance("CC_ODDR",
|
||||
p_CLK_INV = 0,
|
||||
i_CLK = clk,
|
||||
i_DDR = ~clk,
|
||||
i_D0 = i1[j] if len(i1) > 1 else i1,
|
||||
i_D1 = i2[j] if len(i2) > 1 else i2,
|
||||
o_Q = o[j] if len(o) > 1 else o,
|
||||
)
|
||||
|
||||
class CologneChipDDROutput:
|
||||
@staticmethod
|
||||
|
@ -110,10 +112,11 @@ class CologneChipDifferentialOutput:
|
|||
|
||||
class CologneChipSDRInputImpl(Module):
|
||||
def __init__(self, i, o):
|
||||
self.specials += Instance("CC_IBUF",
|
||||
i_I = i,
|
||||
o_O = o,
|
||||
)
|
||||
for j in range(len(i)):
|
||||
self.specials += Instance("CC_IBUF",
|
||||
i_I = i[j] if len(i) > 1 else i,
|
||||
o_O = o[j] if len(o) > 1 else o,
|
||||
)
|
||||
|
||||
class CologneChipSDRInput:
|
||||
@staticmethod
|
||||
|
|
|
@ -132,13 +132,14 @@ class Gw5ATristate:
|
|||
|
||||
class Gw5ASDROutputImpl(Module):
|
||||
def __init__(self, i, o, clk):
|
||||
self.specials += Instance("DFFSE",
|
||||
i_D = i,
|
||||
o_Q = o,
|
||||
i_CLK = clk,
|
||||
i_SET = Constant(0,1),
|
||||
i_CE = Constant(1,1),
|
||||
)
|
||||
for j in range(len(o)):
|
||||
self.specials += Instance("DFFSE",
|
||||
i_D = i[j] if len(i) > 1 else i,
|
||||
o_Q = o[j] if len(o) > 1 else o,
|
||||
i_CLK = clk,
|
||||
i_SET = Constant(0,1),
|
||||
i_CE = Constant(1,1),
|
||||
)
|
||||
|
||||
class Gw5ASDROutput:
|
||||
@staticmethod
|
||||
|
@ -149,13 +150,14 @@ class Gw5ASDROutput:
|
|||
|
||||
class Gw5ASDRInputImpl(Module):
|
||||
def __init__(self, i, o, clk):
|
||||
self.specials += Instance("DFFSE",
|
||||
i_D = i,
|
||||
o_Q = o,
|
||||
i_CLK = clk,
|
||||
i_SET = Constant(0,1),
|
||||
i_CE = Constant(1,1),
|
||||
)
|
||||
for j in range(len(i)):
|
||||
self.specials += Instance("DFFSE",
|
||||
i_D = i[j] if len(i) > 1 else i,
|
||||
o_Q = o[j] if len(o) > 1 else o,
|
||||
i_CLK = clk,
|
||||
i_SET = Constant(0,1),
|
||||
i_CE = Constant(1,1),
|
||||
)
|
||||
|
||||
class Gw5ASDRInput:
|
||||
@staticmethod
|
||||
|
@ -166,20 +168,22 @@ class Gw5ASDRInput:
|
|||
|
||||
class Gw5ASDRTristateImpl(Module):
|
||||
def __init__(self, io, o, oe, i, clk):
|
||||
_o = Signal()
|
||||
_oe_n = Signal()
|
||||
_i = Signal()
|
||||
_o = Signal().like(o)
|
||||
_oe_n = Signal().like(oe)
|
||||
_i = Signal().like(i)
|
||||
self.specials += [
|
||||
SDROutput(o, _o, clk),
|
||||
SDROutput(~oe, _oe_n, clk),
|
||||
SDRInput(_i, i, clk),
|
||||
Instance("IOBUF",
|
||||
io_IO = io,
|
||||
o_O = _i,
|
||||
i_I = _o,
|
||||
i_OEN = _oe_n,
|
||||
),
|
||||
]
|
||||
for j in range(len(io)):
|
||||
self.specials += Instance("IOBUF",
|
||||
io_IO = io[j] if len(io) > 1 else io,
|
||||
o_O = _i[j] if len(_i) > 1 else _i,
|
||||
i_I = _o[j] if len(_o) > 1 else _o,
|
||||
i_OEN = _oe_n[j] if len(_oe_n) > 1 else _oe_n,
|
||||
)
|
||||
|
||||
|
||||
class Gw5ASDRTristate:
|
||||
@staticmethod
|
||||
|
|
|
@ -45,13 +45,14 @@ class LatticeECP5AsyncResetSynchronizer:
|
|||
|
||||
class LatticeECP5SDRInputImpl(Module):
|
||||
def __init__(self, i, o, clk):
|
||||
self.specials += Instance("IFS1P3BX",
|
||||
i_SCLK = clk,
|
||||
i_PD = 0,
|
||||
i_SP = 1,
|
||||
i_D = i,
|
||||
o_Q = o,
|
||||
)
|
||||
for j in range(len(i)):
|
||||
self.specials += Instance("IFS1P3BX",
|
||||
i_SCLK = clk,
|
||||
i_PD = 0,
|
||||
i_SP = 1,
|
||||
i_D = i[j] if len(i) > 1 else i,
|
||||
o_Q = o[j] if len(o) > 1 else o,
|
||||
)
|
||||
|
||||
class LatticeECP5SDRInput:
|
||||
@staticmethod
|
||||
|
@ -62,13 +63,14 @@ class LatticeECP5SDRInput:
|
|||
|
||||
class LatticeECP5SDROutputImpl(Module):
|
||||
def __init__(self, i, o, clk):
|
||||
self.specials += Instance("OFS1P3BX",
|
||||
i_SCLK = clk,
|
||||
i_PD = 0,
|
||||
i_SP = 1,
|
||||
i_D = i,
|
||||
o_Q = o,
|
||||
)
|
||||
for j in range(len(o)):
|
||||
self.specials += Instance("OFS1P3BX",
|
||||
i_SCLK = clk,
|
||||
i_PD = 0,
|
||||
i_SP = 1,
|
||||
i_D = i[j] if len(i) > 1 else i,
|
||||
o_Q = o[j] if len(o) > 1 else o,
|
||||
)
|
||||
|
||||
class LatticeECP5SDROutput:
|
||||
@staticmethod
|
||||
|
@ -79,12 +81,13 @@ class LatticeECP5SDROutput:
|
|||
|
||||
class LatticeECP5DDRInputImpl(Module):
|
||||
def __init__(self, i, o1, o2, clk):
|
||||
self.specials += Instance("IDDRX1F",
|
||||
i_SCLK = clk,
|
||||
i_D = i,
|
||||
o_Q0 = o1,
|
||||
o_Q1 = o2,
|
||||
)
|
||||
for j in range(len(i)):
|
||||
self.specials += Instance("IDDRX1F",
|
||||
i_SCLK = clk,
|
||||
i_D = i[j] if len(i) > 1 else i,
|
||||
o_Q0 = o1[j] if len(o1) > 1 else o1,
|
||||
o_Q1 = o2[j] if len(o2) > 1 else o2,
|
||||
)
|
||||
|
||||
class LatticeECP5DDRInput:
|
||||
@staticmethod
|
||||
|
@ -95,12 +98,13 @@ class LatticeECP5DDRInput:
|
|||
|
||||
class LatticeECP5DDROutputImpl(Module):
|
||||
def __init__(self, i1, i2, o, clk):
|
||||
self.specials += Instance("ODDRX1F",
|
||||
i_SCLK = clk,
|
||||
i_D0 = i1,
|
||||
i_D1 = i2,
|
||||
o_Q = o,
|
||||
)
|
||||
for j in range(len(o)):
|
||||
self.specials += Instance("ODDRX1F",
|
||||
i_SCLK = clk,
|
||||
i_D0 = i1[j] if len(i1) > 1 else i1,
|
||||
i_D1 = i2[j] if len(i2) > 1 else i2,
|
||||
o_Q = o[j] if len(o) > 1 else o,
|
||||
)
|
||||
|
||||
class LatticeECP5DDROutput:
|
||||
@staticmethod
|
||||
|
@ -233,13 +237,14 @@ class LatticeNXAsyncResetSynchronizer:
|
|||
|
||||
class LatticeNXSDRInputImpl(Module):
|
||||
def __init__(self, i, o, clk):
|
||||
self.specials += Instance("IFD1P3BX",
|
||||
i_CK = clk,
|
||||
i_PD = 0,
|
||||
i_SP = 1,
|
||||
i_D = i,
|
||||
o_Q = o,
|
||||
)
|
||||
for j in range(len(i)):
|
||||
self.specials += Instance("IFD1P3BX",
|
||||
i_CK = clk,
|
||||
i_PD = 0,
|
||||
i_SP = 1,
|
||||
i_D = i[j] if len(i) > 1 else i,
|
||||
o_Q = o[j] if len(o) > 1 else o,
|
||||
)
|
||||
|
||||
class LatticeNXSDRInput:
|
||||
@staticmethod
|
||||
|
@ -250,13 +255,14 @@ class LatticeNXSDRInput:
|
|||
|
||||
class LatticeNXSDROutputImpl(Module):
|
||||
def __init__(self, i, o, clk):
|
||||
self.specials += Instance("OFD1P3BX",
|
||||
i_CK = clk,
|
||||
i_PD = 0,
|
||||
i_SP = 1,
|
||||
i_D = i,
|
||||
o_Q = o,
|
||||
)
|
||||
for j in range(len(o)):
|
||||
self.specials += Instance("OFD1P3BX",
|
||||
i_CK = clk,
|
||||
i_PD = 0,
|
||||
i_SP = 1,
|
||||
i_D = i[j] if len(i) > 1 else i,
|
||||
o_Q = o[j] if len(o) > 1 else o,
|
||||
)
|
||||
|
||||
class LatticeNXSDROutput:
|
||||
@staticmethod
|
||||
|
@ -270,13 +276,14 @@ class LatticeNXSDROutput:
|
|||
|
||||
class LatticeNXSDRFFImpl(Module):
|
||||
def __init__(self, i, o, clk):
|
||||
self.specials += Instance("FD1P3BX",
|
||||
i_CK = clk,
|
||||
i_PD = 0,
|
||||
i_SP = 1,
|
||||
i_D = i,
|
||||
o_Q = o,
|
||||
)
|
||||
for j in range(len(o)):
|
||||
self.specials += Instance("FD1P3BX",
|
||||
i_CK = clk,
|
||||
i_PD = 0,
|
||||
i_SP = 1,
|
||||
i_D = i[j] if len(i) > 1 else i,
|
||||
o_Q = o[j] if len(o) > 1 else o,
|
||||
)
|
||||
|
||||
class LatticeNXSDRInputViaFlipFlop:
|
||||
@staticmethod
|
||||
|
@ -292,12 +299,13 @@ class LatticeNXSDROutputViaFlipFlop:
|
|||
|
||||
class LatticeNXDDRInputImpl(Module):
|
||||
def __init__(self, i, o1, o2, clk):
|
||||
self.specials += Instance("IDDRX1",
|
||||
i_SCLK = clk,
|
||||
i_D = i,
|
||||
o_Q0 = o1,
|
||||
o_Q1 = o2,
|
||||
)
|
||||
for j in range(len(i)):
|
||||
self.specials += Instance("IDDRX1",
|
||||
i_SCLK = clk,
|
||||
i_D = i[j] if len(i) > 1 else i,
|
||||
o_Q0 = o1[j] if len(o1) > 1 else o1,
|
||||
o_Q1 = o2[j] if len(o2) > 1 else o2,
|
||||
)
|
||||
|
||||
class LatticeNXDDRInput:
|
||||
@staticmethod
|
||||
|
@ -308,12 +316,13 @@ class LatticeNXDDRInput:
|
|||
|
||||
class LatticeNXDDROutputImpl(Module):
|
||||
def __init__(self, i1, i2, o, clk):
|
||||
self.specials += Instance("ODDRX1",
|
||||
i_SCLK = clk,
|
||||
i_D0 = i1,
|
||||
i_D1 = i2,
|
||||
o_Q = o,
|
||||
)
|
||||
for j in range(len(o)):
|
||||
self.specials += Instance("ODDRX1",
|
||||
i_SCLK = clk,
|
||||
i_D0 = i1[j] if len(i1) > 1 else i1,
|
||||
i_D1 = i2[j] if len(i2) > 1 else i2,
|
||||
o_Q = o[j] if len(o) > 1 else o,
|
||||
)
|
||||
|
||||
class LatticeNXDDROutput:
|
||||
@staticmethod
|
||||
|
@ -325,9 +334,9 @@ class LatticeNXDDROutput:
|
|||
class LatticeNXDDRTristateImpl(Module):
|
||||
def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk):
|
||||
assert oe2 is None
|
||||
_o = Signal()
|
||||
_oe = Signal()
|
||||
_i = Signal()
|
||||
_o = Signal().like(o1)
|
||||
_oe = Signal().like(oe1)
|
||||
_i = Signal().like(i1)
|
||||
self.specials += DDROutput(o1, o2, _o, clk)
|
||||
self.specials += SDROutput(oe1, _oe, clk)
|
||||
self.specials += DDRInput(_i, i1, i2, clk)
|
||||
|
@ -429,16 +438,17 @@ class LatticeiCE40DifferentialOutput:
|
|||
|
||||
class LatticeiCE40DDROutputImpl(Module):
|
||||
def __init__(self, i1, i2, o, clk):
|
||||
self.specials += Instance("SB_IO",
|
||||
p_PIN_TYPE = C(0b010000, 6), # PIN_OUTPUT_DDR
|
||||
p_IO_STANDARD = "SB_LVCMOS",
|
||||
io_PACKAGE_PIN = o,
|
||||
i_CLOCK_ENABLE = 1,
|
||||
i_OUTPUT_CLK = clk,
|
||||
i_OUTPUT_ENABLE = 1,
|
||||
i_D_OUT_0 = i1,
|
||||
i_D_OUT_1 = i2
|
||||
)
|
||||
for j in range(len(o)):
|
||||
self.specials += Instance("SB_IO",
|
||||
p_PIN_TYPE = C(0b010000, 6), # PIN_OUTPUT_DDR
|
||||
p_IO_STANDARD = "SB_LVCMOS",
|
||||
io_PACKAGE_PIN = o[j] if len(o) > 1 else o,
|
||||
i_CLOCK_ENABLE = 1,
|
||||
i_OUTPUT_CLK = clk,
|
||||
i_OUTPUT_ENABLE = 1,
|
||||
i_D_OUT_0 = i1[j] if len(i1) > 1 else i1,
|
||||
i_D_OUT_1 = i2[j] if len(i2) > 1 else i2
|
||||
)
|
||||
|
||||
|
||||
class LatticeiCE40DDROutput:
|
||||
|
@ -450,15 +460,16 @@ class LatticeiCE40DDROutput:
|
|||
|
||||
class LatticeiCE40DDRInputImpl(Module):
|
||||
def __init__(self, i, o1, o2, clk):
|
||||
self.specials += Instance("SB_IO",
|
||||
p_PIN_TYPE = C(0b000000, 6), # PIN_INPUT_DDR
|
||||
p_IO_STANDARD = "SB_LVCMOS",
|
||||
io_PACKAGE_PIN = i,
|
||||
i_CLOCK_ENABLE = 1,
|
||||
i_INPUT_CLK = clk,
|
||||
o_D_IN_0 = o1,
|
||||
o_D_IN_1 = o2
|
||||
)
|
||||
for j in range(len(i)):
|
||||
self.specials += Instance("SB_IO",
|
||||
p_PIN_TYPE = C(0b000000, 6), # PIN_INPUT_DDR
|
||||
p_IO_STANDARD = "SB_LVCMOS",
|
||||
io_PACKAGE_PIN = i[j] if len(i) > 1 else i,
|
||||
i_CLOCK_ENABLE = 1,
|
||||
i_INPUT_CLK = clk,
|
||||
o_D_IN_0 = o1[j] if len(o1) > 1 else o1,
|
||||
o_D_IN_1 = o2[j] if len(o2) > 1 else o2
|
||||
)
|
||||
|
||||
|
||||
class LatticeiCE40DDRInput:
|
||||
|
@ -470,18 +481,19 @@ class LatticeiCE40DDRInput:
|
|||
|
||||
class LatticeiCE40SDROutputImpl(Module):
|
||||
def __init__(self, i, o, clk):
|
||||
self.specials += Instance("SB_IO",
|
||||
# i_INPUT_CLK must match between two SB_IOs in the same tile.
|
||||
# In PIN_INPUT mode, this restriction is relaxed; an unconnected
|
||||
# i_INPUT_CLK also works.
|
||||
p_PIN_TYPE = C(0b010101, 6), # PIN_OUTPUT_REGISTERED + PIN_INPUT
|
||||
p_IO_STANDARD = "SB_LVCMOS",
|
||||
io_PACKAGE_PIN = o,
|
||||
i_CLOCK_ENABLE = 1,
|
||||
i_OUTPUT_CLK = clk,
|
||||
i_OUTPUT_ENABLE = 1,
|
||||
i_D_OUT_0 = i
|
||||
)
|
||||
for j in range(len(o)):
|
||||
self.specials += Instance("SB_IO",
|
||||
# i_INPUT_CLK must match between two SB_IOs in the same tile.
|
||||
# In PIN_INPUT mode, this restriction is relaxed; an unconnected
|
||||
# i_INPUT_CLK also works.
|
||||
p_PIN_TYPE = C(0b010101, 6), # PIN_OUTPUT_REGISTERED + PIN_INPUT
|
||||
p_IO_STANDARD = "SB_LVCMOS",
|
||||
io_PACKAGE_PIN = o[j] if len(o) > 1 else o,
|
||||
i_CLOCK_ENABLE = 1,
|
||||
i_OUTPUT_CLK = clk,
|
||||
i_OUTPUT_ENABLE = 1,
|
||||
i_D_OUT_0 = i[j] if len(i) > 1 else i
|
||||
)
|
||||
|
||||
class LatticeiCE40SDROutput:
|
||||
@staticmethod
|
||||
|
@ -499,15 +511,16 @@ class LatticeiCE40SDRInput:
|
|||
|
||||
class LatticeiCE40SDRTristateImpl(Module):
|
||||
def __init__(self, io, o, oe, i, clk):
|
||||
self.specials += Instance("SB_IO",
|
||||
p_PIN_TYPE = C(0b110100, 6), # PIN_OUTPUT_REGISTERED_ENABLE_REGISTERED + PIN_INPUT_REGISTERED
|
||||
io_PACKAGE_PIN = io,
|
||||
i_INPUT_CLK = clk,
|
||||
i_OUTPUT_CLK = clk,
|
||||
i_OUTPUT_ENABLE = oe,
|
||||
i_D_OUT_0 = o,
|
||||
o_D_IN_0 = i,
|
||||
)
|
||||
for j in range(len(io)):
|
||||
self.specials += Instance("SB_IO",
|
||||
p_PIN_TYPE = C(0b110100, 6), # PIN_OUTPUT_REGISTERED_ENABLE_REGISTERED + PIN_INPUT_REGISTERED
|
||||
io_PACKAGE_PIN = io[j] if len(io) > 1 else io,
|
||||
i_INPUT_CLK = clk,
|
||||
i_OUTPUT_CLK = clk,
|
||||
i_OUTPUT_ENABLE = oe[j] if len(oe) > 1 else oe,
|
||||
i_D_OUT_0 = o[j] if len(o) > 1 else o,
|
||||
o_D_IN_0 = i[j] if len(i) > 1 else i,
|
||||
)
|
||||
|
||||
class LatticeiCE40SDRTristate(Module):
|
||||
@staticmethod
|
||||
|
|
|
@ -25,12 +25,13 @@ class SimAsyncResetSynchronizer:
|
|||
|
||||
class SimDDROutputImpl(Module):
|
||||
def __init__(self, o, i1, i2, clk):
|
||||
self.specials += Instance("DDR_OUTPUT",
|
||||
i_i1 = i1,
|
||||
i_i2 = i2,
|
||||
o_o = o,
|
||||
i_clk = clk
|
||||
)
|
||||
for j in range(len(o)):
|
||||
self.specials += Instance("DDR_OUTPUT",
|
||||
i_i1 = i1[j] if len(i1) > 1 else i1,
|
||||
i_i2 = i2[j] if len(i2) > 1 else i2,
|
||||
o_o = o[j] if len(o) > 1 else o,
|
||||
i_clk = clk
|
||||
)
|
||||
|
||||
class SimDDROutput:
|
||||
@staticmethod
|
||||
|
@ -41,12 +42,13 @@ class SimDDROutput:
|
|||
|
||||
class SimDDRInputImpl(Module):
|
||||
def __init__(self, i, o1, o2, clk):
|
||||
self.specials += Instance("DDR_INPUT",
|
||||
o_o1 = o1,
|
||||
o_o2 = o2,
|
||||
i_i = i,
|
||||
i_clk = clk
|
||||
)
|
||||
for j in range(len(i)):
|
||||
self.specials += Instance("DDR_INPUT",
|
||||
o_o1 = o1[j] if len(o1) > 1 else o1,
|
||||
o_o2 = o2[j] if len(o2) > 1 else o2,
|
||||
i_i = i[j] if len(i) > 1 else i,
|
||||
i_clk = clk
|
||||
)
|
||||
|
||||
class SimDDRInput:
|
||||
@staticmethod
|
||||
|
|
|
@ -138,18 +138,19 @@ class XilinxDifferentialOutput:
|
|||
|
||||
class XilinxSDRTristateImpl(Module):
|
||||
def __init__(self, io, o, oe, i, clk):
|
||||
_o = Signal()
|
||||
_oe_n = Signal()
|
||||
_i = Signal()
|
||||
_o = Signal().like(o)
|
||||
_oe_n = Signal().like(oe)
|
||||
_i = Signal().like(i)
|
||||
self.specials += SDROutput(o, _o, clk)
|
||||
self.specials += SDROutput(~oe, _oe_n, clk)
|
||||
self.specials += SDRInput(_i, i, clk)
|
||||
self.specials += Instance("IOBUF",
|
||||
io_IO = io,
|
||||
o_O = _i,
|
||||
i_I = _o,
|
||||
i_T = _oe_n,
|
||||
)
|
||||
for j in range(len(io)):
|
||||
self.specials += Instance("IOBUF",
|
||||
io_IO = io[j] if len(io) > 1 else io,
|
||||
o_O = _i[j] if len(_i) > 1 else _i,
|
||||
i_I = _o[j] if len(_o) > 1 else _o,
|
||||
i_T = _oe_n[j] if len(_oe_n) > 1 else _oe_n,
|
||||
)
|
||||
|
||||
class XilinxSDRTristate:
|
||||
@staticmethod
|
||||
|
@ -160,18 +161,19 @@ class XilinxSDRTristate:
|
|||
|
||||
class XilinxDDRTristateImpl(Module):
|
||||
def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk):
|
||||
_o = Signal()
|
||||
_oe_n = Signal()
|
||||
_i = Signal()
|
||||
_o = Signal().like(o1)
|
||||
_oe_n = Signal().like(oe1)
|
||||
_i = Signal().like(i1)
|
||||
self.specials += DDROutput(o1, o2, _o, clk)
|
||||
self.specials += DDROutput(~oe1, ~oe2, _oe_n, clk) if oe2 is not None else SDROutput(~oe1, _oe_n, clk)
|
||||
self.specials += DDRInput(_i, i1, i2, clk)
|
||||
self.specials += Instance("IOBUF",
|
||||
io_IO = io,
|
||||
o_O = _i,
|
||||
i_I = _o,
|
||||
i_T = _oe_n,
|
||||
)
|
||||
for j in range(len(io)):
|
||||
self.specials += Instance("IOBUF",
|
||||
io_IO = io[j] if len(io) > 1 else io,
|
||||
o_O = _i[j] if len(_i) > 1 else _i,
|
||||
i_I = _o[j] if len(_o) > 1 else _o,
|
||||
i_T = _oe_n[j] if len(_oe_n) > 1 else _oe_n,
|
||||
)
|
||||
|
||||
class XilinxDDRTristate:
|
||||
@staticmethod
|
||||
|
@ -193,19 +195,20 @@ xilinx_special_overrides = {
|
|||
|
||||
class XilinxDDROutputImplS6(Module):
|
||||
def __init__(self, i1, i2, o, clk):
|
||||
self.specials += Instance("ODDR2",
|
||||
p_DDR_ALIGNMENT = "C0",
|
||||
p_INIT = 0,
|
||||
p_SRTYPE = "ASYNC",
|
||||
i_C0 = clk,
|
||||
i_C1 = ~clk,
|
||||
i_CE = 1,
|
||||
i_S = 0,
|
||||
i_R = 0,
|
||||
i_D0 = i1,
|
||||
i_D1 = i2,
|
||||
o_Q = o
|
||||
)
|
||||
for j in range(len(o)):
|
||||
self.specials += Instance("ODDR2",
|
||||
p_DDR_ALIGNMENT = "C0",
|
||||
p_INIT = 0,
|
||||
p_SRTYPE = "ASYNC",
|
||||
i_C0 = clk,
|
||||
i_C1 = ~clk,
|
||||
i_CE = 1,
|
||||
i_S = 0,
|
||||
i_R = 0,
|
||||
i_D0 = i1[j] if len(i1) > 1 else i1,
|
||||
i_D1 = i2[j] if len(i2) > 1 else i2,
|
||||
o_Q = o[j] if len(o) > 1 else o
|
||||
)
|
||||
|
||||
|
||||
class XilinxDDROutputS6:
|
||||
|
@ -217,20 +220,21 @@ class XilinxDDROutputS6:
|
|||
|
||||
class XilinxDDRInputImplS6(Module):
|
||||
def __init__(self, i, o1, o2, clk):
|
||||
self.specials += Instance("IDDR2",
|
||||
p_DDR_ALIGNMENT = "C0",
|
||||
p_INIT_Q0 = 0,
|
||||
p_INIT_Q1 = 0,
|
||||
p_SRTYPE = "ASYNC",
|
||||
i_C0 = clk,
|
||||
i_C1 = ~clk,
|
||||
i_CE = 1,
|
||||
i_S = 0,
|
||||
i_R = 0,
|
||||
i_D = i,
|
||||
o_Q0 = o1,
|
||||
o_Q1 = o2
|
||||
)
|
||||
for j in range(len(i)):
|
||||
self.specials += Instance("IDDR2",
|
||||
p_DDR_ALIGNMENT = "C0",
|
||||
p_INIT_Q0 = 0,
|
||||
p_INIT_Q1 = 0,
|
||||
p_SRTYPE = "ASYNC",
|
||||
i_C0 = clk,
|
||||
i_C1 = ~clk,
|
||||
i_CE = 1,
|
||||
i_S = 0,
|
||||
i_R = 0,
|
||||
i_D = i[j] if len(i) > 1 else i,
|
||||
o_Q0 = o1[j] if len(o1) > 1 else o1,
|
||||
o_Q1 = o2[j] if len(o2) > 1 else o2
|
||||
)
|
||||
|
||||
|
||||
class XilinxDDRInputS6:
|
||||
|
@ -266,16 +270,17 @@ xilinx_s6_special_overrides = {
|
|||
|
||||
class XilinxDDROutputImplS7(Module):
|
||||
def __init__(self, i1, i2, o, clk):
|
||||
self.specials += Instance("ODDR",
|
||||
p_DDR_CLK_EDGE="SAME_EDGE",
|
||||
i_C = clk,
|
||||
i_CE = 1,
|
||||
i_S = 0,
|
||||
i_R = 0,
|
||||
i_D1 = i1,
|
||||
i_D2 = i2,
|
||||
o_Q = o
|
||||
)
|
||||
for j in range(len(o)):
|
||||
self.specials += Instance("ODDR",
|
||||
p_DDR_CLK_EDGE="SAME_EDGE",
|
||||
i_C = clk,
|
||||
i_CE = 1,
|
||||
i_S = 0,
|
||||
i_R = 0,
|
||||
i_D1 = i1[j] if len(i1) > 1 else i1,
|
||||
i_D2 = i2[j] if len(i2) > 1 else i2,
|
||||
o_Q = o[j] if len(o) > 1 else o
|
||||
)
|
||||
|
||||
|
||||
class XilinxDDROutputS7:
|
||||
|
@ -287,16 +292,17 @@ class XilinxDDROutputS7:
|
|||
|
||||
class XilinxDDRInputImplS7(Module):
|
||||
def __init__(self, i, o1, o2, clk):
|
||||
self.specials += Instance("IDDR",
|
||||
p_DDR_CLK_EDGE="SAME_EDGE",
|
||||
i_C = clk,
|
||||
i_CE = 1,
|
||||
i_S = 0,
|
||||
i_R = 0,
|
||||
i_D = i,
|
||||
o_Q1 = o1,
|
||||
o_Q2 = o2
|
||||
)
|
||||
for j in range(len(i)):
|
||||
self.specials += Instance("IDDR",
|
||||
p_DDR_CLK_EDGE="SAME_EDGE",
|
||||
i_C = clk,
|
||||
i_CE = 1,
|
||||
i_S = 0,
|
||||
i_R = 0,
|
||||
i_D = i[j] if len(i) > 1 else i,
|
||||
o_Q1 = o1[j] if len(o1) > 1 else o1,
|
||||
o_Q2 = o2[j] if len(o2) > 1 else o2
|
||||
)
|
||||
|
||||
|
||||
class XilinxDDRInputS7:
|
||||
|
@ -332,13 +338,14 @@ xilinx_s7_special_overrides = {
|
|||
|
||||
class XilinxDDROutputImplUS(Module):
|
||||
def __init__(self, i1, i2, o, clk):
|
||||
self.specials += Instance("ODDRE1",
|
||||
i_C = clk,
|
||||
i_SR = 0,
|
||||
i_D1 = i1,
|
||||
i_D2 = i2,
|
||||
o_Q = o
|
||||
)
|
||||
for j in range(len(o)):
|
||||
self.specials += Instance("ODDRE1",
|
||||
i_C = clk,
|
||||
i_SR = 0,
|
||||
i_D1 = i1[j] if len(i1) > 1 else i1,
|
||||
i_D2 = i2[j] if len(i2) > 1 else i2,
|
||||
o_Q = o[j] if len(o) > 1 else o
|
||||
)
|
||||
|
||||
|
||||
class XilinxDDROutputUS:
|
||||
|
@ -350,17 +357,18 @@ class XilinxDDROutputUS:
|
|||
|
||||
class XilinxDDRInputImplUS(Module):
|
||||
def __init__(self, i, o1, o2, clk):
|
||||
self.specials += Instance("IDDRE1",
|
||||
p_DDR_CLK_EDGE="SAME_EDGE_PIPELINED",
|
||||
p_IS_C_INVERTED = 0,
|
||||
p_IS_CB_INVERTED = 1,
|
||||
i_C = clk,
|
||||
i_CB = clk,
|
||||
i_R = 0,
|
||||
i_D = i,
|
||||
o_Q1 = o1,
|
||||
o_Q2 = o2
|
||||
)
|
||||
for j in range(len(i)):
|
||||
self.specials += Instance("IDDRE1",
|
||||
p_DDR_CLK_EDGE="SAME_EDGE_PIPELINED",
|
||||
p_IS_C_INVERTED = 0,
|
||||
p_IS_CB_INVERTED = 1,
|
||||
i_C = clk,
|
||||
i_CB = clk,
|
||||
i_R = 0,
|
||||
i_D = i[j] if len(i) > 1 else i,
|
||||
o_Q1 = o1[j] if len(o1) > 1 else o1,
|
||||
o_Q2 = o2[j] if len(o2) > 1 else o2
|
||||
)
|
||||
|
||||
|
||||
class XilinxDDRInputUS:
|
||||
|
@ -372,13 +380,14 @@ class XilinxDDRInputUS:
|
|||
|
||||
class XilinxSDROutputImplUS(Module):
|
||||
def __init__(self, i, o, clk):
|
||||
self.specials += Instance("FDCE",
|
||||
i_C = clk,
|
||||
i_CE = 1,
|
||||
i_CLR = 0,
|
||||
i_D = i,
|
||||
o_Q = o
|
||||
)
|
||||
for j in range(len(o)):
|
||||
self.specials += Instance("FDCE",
|
||||
i_C = clk,
|
||||
i_CE = 1,
|
||||
i_CLR = 0,
|
||||
i_D = i[j] if len(i) > 1 else i,
|
||||
o_Q = o[j] if len(o) > 1 else o
|
||||
)
|
||||
|
||||
class XilinxSDROutputUS:
|
||||
@staticmethod
|
||||
|
@ -388,13 +397,14 @@ class XilinxSDROutputUS:
|
|||
# Ultrascale SDRInput ------------------------------------------------------------------------------
|
||||
class XilinxSDRInputImplUS(Module):
|
||||
def __init__(self, i, o, clk):
|
||||
self.specials += Instance("FDCE",
|
||||
i_C = clk,
|
||||
i_CE = 1,
|
||||
i_CLR = 0,
|
||||
i_D = i,
|
||||
o_Q = o
|
||||
)
|
||||
for j in range(len(i)):
|
||||
self.specials += Instance("FDCE",
|
||||
i_C = clk,
|
||||
i_CE = 1,
|
||||
i_CLR = 0,
|
||||
i_D = i[j] if len(i) > 1 else i,
|
||||
o_Q = o[j] if len(o) > 1 else o
|
||||
)
|
||||
|
||||
class XilinxSDRInputUS:
|
||||
@staticmethod
|
||||
|
|
Loading…
Reference in a new issue