build: io: allow in clk to be different on SDR/DDR Tristate

allow in clk to be different on SDR/DDR Tristate.

Signed-off-by: Fin Maaß <f.maass@vogl-electronic.com>
This commit is contained in:
Fin Maaß 2024-09-30 12:49:04 +02:00
parent 3ced4ac850
commit 418d6f8c00
6 changed files with 40 additions and 34 deletions

View file

@ -226,14 +226,14 @@ class Agilex5SDRInput:
# Agilex5 SDRTristate ------------------------------------------------------------------------------ # Agilex5 SDRTristate ------------------------------------------------------------------------------
class Agilex5SDRTristateImpl(Module): class Agilex5SDRTristateImpl(Module):
def __init__(self, io, o, oe, i, clk): def __init__(self, io, o, oe, i, clk, in_clk):
_i = Signal() _i = Signal()
_o = Signal() _o = Signal()
_oe = Signal() _oe = Signal()
self.specials += [ self.specials += [
SDRIO(o, _o, clk), SDRIO(o, _o, clk),
SDRIO(oe, _oe, clk), SDRIO(oe, _oe, clk),
SDRIO(_i, i, clk), SDRIO(_i, i, in_clk),
Instance("tennm_ph2_io_ibuf", Instance("tennm_ph2_io_ibuf",
p_bus_hold = "BUS_HOLD_OFF", p_bus_hold = "BUS_HOLD_OFF",
io_i = io, # FIXME: its an input but io is needed to have correct dir at top module io_i = io, # FIXME: its an input but io is needed to have correct dir at top module
@ -250,7 +250,7 @@ class Agilex5SDRTristateImpl(Module):
class Agilex5SDRTristate(Module): class Agilex5SDRTristate(Module):
@staticmethod @staticmethod
def lower(dr): def lower(dr):
return Agilex5SDRTristateImpl(dr.io, dr.o, dr.oe, dr.i, dr.clk) return Agilex5SDRTristateImpl(dr.io, dr.o, dr.oe, dr.i, dr.clk, dr.in_clk)
# Agilex5 Special Overrides ------------------------------------------------------------------------ # Agilex5 Special Overrides ------------------------------------------------------------------------

View file

@ -303,9 +303,10 @@ class EfinixDifferentialInput:
# Efinix DDRTristate ------------------------------------------------------------------------------- # Efinix DDRTristate -------------------------------------------------------------------------------
class EfinixDDRTristateImpl(LiteXModule): class EfinixDDRTristateImpl(LiteXModule):
def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk): def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk, in_clk):
assert oe2 is None assert oe2 is None
clk, out_clk_inv = check_clk_inverted(clk) clk, out_clk_inv = check_clk_inverted(clk)
in_clk, in_clk_inv = check_clk_inverted(in_clk)
assert_is_signal_or_clocksignal(clk) assert_is_signal_or_clocksignal(clk)
platform = LiteXContext.platform platform = LiteXContext.platform
io_name = platform.get_pin_name(io) io_name = platform.get_pin_name(io)
@ -330,11 +331,11 @@ class EfinixDDRTristateImpl(LiteXModule):
"properties" : io_prop, "properties" : io_prop,
"size" : 1, "size" : 1,
"in_reg" : "DDIO_RESYNC", "in_reg" : "DDIO_RESYNC",
"in_clk_pin" : clk, "in_clk_pin" : in_clk,
"out_reg" : "DDIO_RESYNC", "out_reg" : "DDIO_RESYNC",
"out_clk_pin" : clk, "out_clk_pin" : clk,
"oe_reg" : "REG", "oe_reg" : "REG",
"in_clk_inv" : out_clk_inv, "in_clk_inv" : in_clk_inv,
"out_clk_inv" : out_clk_inv, "out_clk_inv" : out_clk_inv,
"drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4") "drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4")
} }
@ -344,13 +345,14 @@ class EfinixDDRTristateImpl(LiteXModule):
class EfinixDDRTristate: class EfinixDDRTristate:
@staticmethod @staticmethod
def lower(dr): def lower(dr):
return EfinixDDRTristateImpl(dr.io, dr.o1, dr.o2, dr.oe1, dr.oe2, dr.i1, dr.i2, dr.clk, **dr.kwargs) return EfinixDDRTristateImpl(dr.io, dr.o1, dr.o2, dr.oe1, dr.oe2, dr.i1, dr.i2, dr.clk, dr.in_clk)
# Efinix SDRTristate ------------------------------------------------------------------------------- # Efinix SDRTristate -------------------------------------------------------------------------------
class EfinixSDRTristateImpl(LiteXModule): class EfinixSDRTristateImpl(LiteXModule):
def __init__(self, io, o, oe, i, clk): def __init__(self, io, o, oe, i, clk, in_clk):
clk, out_clk_inv = check_clk_inverted(clk) clk, out_clk_inv = check_clk_inverted(clk)
in_clk, in_clk_inv = check_clk_inverted(in_clk)
assert_is_signal_or_clocksignal(clk) assert_is_signal_or_clocksignal(clk)
platform = LiteXContext.platform platform = LiteXContext.platform
io_name = platform.get_pin_name(io) io_name = platform.get_pin_name(io)
@ -375,12 +377,12 @@ class EfinixSDRTristateImpl(LiteXModule):
"properties" : io_prop, "properties" : io_prop,
"size" : 1, "size" : 1,
"in_reg" : "REG", "in_reg" : "REG",
"in_clk_pin" : clk, "in_clk_pin" : in_clk,
"out_reg" : "REG", "out_reg" : "REG",
"out_clk_pin" : clk, "out_clk_pin" : clk,
"const_output" : const_output, "const_output" : const_output,
"oe_reg" : "REG", "oe_reg" : "REG",
"in_clk_inv" : out_clk_inv, "in_clk_inv" : in_clk_inv,
"out_clk_inv" : out_clk_inv, "out_clk_inv" : out_clk_inv,
"drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4") "drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4")
} }
@ -391,7 +393,7 @@ class EfinixSDRTristateImpl(LiteXModule):
class EfinixSDRTristate(LiteXModule): class EfinixSDRTristate(LiteXModule):
@staticmethod @staticmethod
def lower(dr): def lower(dr):
return EfinixSDRTristateImpl(dr.io, dr.o, dr.oe, dr.i, dr.clk, **dr.kwargs) return EfinixSDRTristateImpl(dr.io, dr.o, dr.oe, dr.i, dr.clk, dr.in_clk)
# Efinix SDROutput --------------------------------------------------------------------------------- # Efinix SDROutput ---------------------------------------------------------------------------------

View file

@ -165,14 +165,14 @@ class Gw5ASDRInput:
# Gw5A SDRTristate --------------------------------------------------------------------------------- # Gw5A SDRTristate ---------------------------------------------------------------------------------
class Gw5ASDRTristateImpl(Module): class Gw5ASDRTristateImpl(Module):
def __init__(self, io, o, oe, i, clk): def __init__(self, io, o, oe, i, clk, in_clk):
_o = Signal() _o = Signal()
_oe_n = Signal() _oe_n = Signal()
_i = Signal() _i = Signal()
self.specials += [ self.specials += [
SDROutput(o, _o, clk), SDROutput(o, _o, clk),
SDROutput(~oe, _oe_n, clk), SDROutput(~oe, _oe_n, clk),
SDRInput(_i, i, clk), SDRInput(_i, i, in_clk),
Instance("IOBUF", Instance("IOBUF",
io_IO = io, io_IO = io,
o_O = _i, o_O = _i,
@ -184,7 +184,7 @@ class Gw5ASDRTristateImpl(Module):
class Gw5ASDRTristate: class Gw5ASDRTristate:
@staticmethod @staticmethod
def lower(dr): def lower(dr):
return Gw5ASDRTristateImpl(dr.io, dr.o, dr.oe, dr.i, dr.clk) return Gw5ASDRTristateImpl(dr.io, dr.o, dr.oe, dr.i, dr.clk, dr.in_clk)
# Gw5A Special Overrides --------------------------------------------------------------------------- # Gw5A Special Overrides ---------------------------------------------------------------------------

View file

@ -109,23 +109,24 @@ class SDROutput(SDRIO): pass
# SDR Tristate ------------------------------------------------------------------------------------- # SDR Tristate -------------------------------------------------------------------------------------
class InferedSDRTristate(Module): class InferedSDRTristate(Module):
def __init__(self, io, o, oe, i, clk): def __init__(self, io, o, oe, i, clk, in_clk):
_o = Signal() _o = Signal()
_oe = Signal() _oe = Signal()
_i = Signal() _i = Signal()
self.specials += SDROutput(o, _o, clk) self.specials += SDROutput(o, _o, clk)
self.specials += SDRInput(_i, i, clk) self.specials += SDRInput(_i, i, in_clk)
self.submodules += InferedSDRIO(oe, _oe, clk) self.submodules += InferedSDRIO(oe, _oe, clk)
self.specials += Tristate(io, _o, _oe, _i) self.specials += Tristate(io, _o, _oe, _i)
class SDRTristate(Special): class SDRTristate(Special):
def __init__(self, io, o, oe, i, clk=None): def __init__(self, io, o, oe, i, clk=None, in_clk=None):
Special.__init__(self) Special.__init__(self)
self.io = wrap(io) self.io = wrap(io)
self.o = wrap(o) self.o = wrap(o)
self.oe = wrap(oe) self.oe = wrap(oe)
self.i = wrap(i) self.i = wrap(i)
self.clk = wrap(clk) if clk is not None else ClockSignal() self.clk = wrap(clk) if clk is not None else ClockSignal()
self.in_clk = wrap(in_clk) if in_clk is not None else self.clk
assert len(self.i) == len(self.o) == len(self.oe) assert len(self.i) == len(self.o) == len(self.oe)
def iter_expressions(self): def iter_expressions(self):
@ -134,10 +135,11 @@ class SDRTristate(Special):
yield self, "oe" , SPECIAL_INPUT yield self, "oe" , SPECIAL_INPUT
yield self, "i" , SPECIAL_OUTPUT yield self, "i" , SPECIAL_OUTPUT
yield self, "clk", SPECIAL_INPUT yield self, "clk", SPECIAL_INPUT
yield self, "in_clk", SPECIAL_INPUT
@staticmethod @staticmethod
def lower(dr): def lower(dr):
return InferedSDRTristate(dr.io, dr.o, dr.oe, dr.i, dr.clk) return InferedSDRTristate(dr.io, dr.o, dr.oe, dr.i, dr.clk, dr.in_clk)
# DDR Input/Output --------------------------------------------------------------------------------- # DDR Input/Output ---------------------------------------------------------------------------------
@ -185,17 +187,17 @@ class DDROutput(Special):
# DDR Tristate ------------------------------------------------------------------------------------- # DDR Tristate -------------------------------------------------------------------------------------
class InferedDDRTristate(Module): class InferedDDRTristate(Module):
def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk): def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk, in_clk):
_o = Signal() _o = Signal()
_oe = Signal() _oe = Signal()
_i = Signal() _i = Signal()
self.specials += DDROutput(o1, o2, _o, clk) self.specials += DDROutput(o1, o2, _o, clk)
self.specials += DDROutput(oe1, oe2, _oe, clk) if oe2 is not None else SDROutput(oe1, _oe, clk) self.specials += DDROutput(oe1, oe2, _oe, clk) if oe2 is not None else SDROutput(oe1, _oe, clk)
self.specials += DDRInput(_i, i1, i2, clk) self.specials += DDRInput(_i, i1, i2, in_clk)
self.specials += Tristate(io, _o, _oe, _i) self.specials += Tristate(io, _o, _oe, _i)
class DDRTristate(Special): class DDRTristate(Special):
def __init__(self, io, o1, o2, oe1, oe2=None, i1=None, i2=None, clk=None): def __init__(self, io, o1, o2, oe1, oe2=None, i1=None, i2=None, clk=None, in_clk=None):
Special.__init__(self) Special.__init__(self)
self.io = io self.io = io
self.o1 = o1 self.o1 = o1
@ -205,6 +207,7 @@ class DDRTristate(Special):
self.i1 = i1 if i1 is not None else Signal() self.i1 = i1 if i1 is not None else Signal()
self.i2 = i2 if i2 is not None else Signal() self.i2 = i2 if i2 is not None else Signal()
self.clk = clk if clk is not None else ClockSignal() self.clk = clk if clk is not None else ClockSignal()
self.in_clk = in_clk if in_clk is not None else self.clk
def iter_expressions(self): def iter_expressions(self):
yield self, "io" , SPECIAL_INOUT yield self, "io" , SPECIAL_INOUT
@ -215,10 +218,11 @@ class DDRTristate(Special):
yield self, "i1" , SPECIAL_OUTPUT yield self, "i1" , SPECIAL_OUTPUT
yield self, "i2" , SPECIAL_OUTPUT yield self, "i2" , SPECIAL_OUTPUT
yield self, "clk", SPECIAL_INPUT yield self, "clk", SPECIAL_INPUT
yield self, "in_clk", SPECIAL_INPUT
@staticmethod @staticmethod
def lower(dr): def lower(dr):
return InferedDDRTristate(dr.io, dr.o1, dr.o2, dr.oe1, dr.oe2, dr.i1, dr.i2, dr.clk) return InferedDDRTristate(dr.io, dr.o1, dr.o2, dr.oe1, dr.oe2, dr.i1, dr.i2, dr.clk, dr.in_clk)
# Clock Reset Generator ---------------------------------------------------------------------------- # Clock Reset Generator ----------------------------------------------------------------------------

View file

@ -323,21 +323,21 @@ class LatticeNXDDROutput:
# NX DDR Tristate ---------------------------------------------------------------------------------- # NX DDR Tristate ----------------------------------------------------------------------------------
class LatticeNXDDRTristateImpl(Module): class LatticeNXDDRTristateImpl(Module):
def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk): def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk, in_clk):
assert oe2 is None assert oe2 is None
_o = Signal() _o = Signal()
_oe = Signal() _oe = Signal()
_i = Signal() _i = Signal()
self.specials += DDROutput(o1, o2, _o, clk) self.specials += DDROutput(o1, o2, _o, clk)
self.specials += SDROutput(oe1, _oe, clk) self.specials += SDROutput(oe1, _oe, clk)
self.specials += DDRInput(_i, i1, i2, clk) self.specials += DDRInput(_i, i1, i2, in_clk)
self.specials += Tristate(io, _o, _oe, _i) self.specials += Tristate(io, _o, _oe, _i)
_oe.attr.add("syn_useioff") _oe.attr.add("syn_useioff")
class LatticeNXDDRTristate: class LatticeNXDDRTristate:
@staticmethod @staticmethod
def lower(dr): def lower(dr):
return LatticeNXDDRTristateImpl(dr.io, dr.o1, dr.o2, dr.oe1, dr.oe2, dr.i1, dr.i2, dr.clk) return LatticeNXDDRTristateImpl(dr.io, dr.o1, dr.o2, dr.oe1, dr.oe2, dr.i1, dr.i2, dr.clk, dr.in_clk)
# NX Special Overrides ----------------------------------------------------------------------------- # NX Special Overrides -----------------------------------------------------------------------------
@ -498,11 +498,11 @@ class LatticeiCE40SDRInput:
# iCE40 SDR Tristate ------------------------------------------------------------------------------- # iCE40 SDR Tristate -------------------------------------------------------------------------------
class LatticeiCE40SDRTristateImpl(Module): class LatticeiCE40SDRTristateImpl(Module):
def __init__(self, io, o, oe, i, clk): def __init__(self, io, o, oe, i, clk, in_clk):
self.specials += Instance("SB_IO", self.specials += Instance("SB_IO",
p_PIN_TYPE = C(0b110100, 6), # PIN_OUTPUT_REGISTERED_ENABLE_REGISTERED + PIN_INPUT_REGISTERED p_PIN_TYPE = C(0b110100, 6), # PIN_OUTPUT_REGISTERED_ENABLE_REGISTERED + PIN_INPUT_REGISTERED
io_PACKAGE_PIN = io, io_PACKAGE_PIN = io,
i_INPUT_CLK = clk, i_INPUT_CLK = in_clk,
i_OUTPUT_CLK = clk, i_OUTPUT_CLK = clk,
i_OUTPUT_ENABLE = oe, i_OUTPUT_ENABLE = oe,
i_D_OUT_0 = o, i_D_OUT_0 = o,
@ -512,7 +512,7 @@ class LatticeiCE40SDRTristateImpl(Module):
class LatticeiCE40SDRTristate(Module): class LatticeiCE40SDRTristate(Module):
@staticmethod @staticmethod
def lower(dr): def lower(dr):
return LatticeiCE40SDRTristateImpl(dr.io, dr.o, dr.oe, dr.i, dr.clk) return LatticeiCE40SDRTristateImpl(dr.io, dr.o, dr.oe, dr.i, dr.clk, dr.in_clk)
# iCE40 Trellis Special Overrides ------------------------------------------------------------------ # iCE40 Trellis Special Overrides ------------------------------------------------------------------

View file

@ -137,13 +137,13 @@ class XilinxDifferentialOutput:
# Common SDRTristate ------------------------------------------------------------------------------- # Common SDRTristate -------------------------------------------------------------------------------
class XilinxSDRTristateImpl(Module): class XilinxSDRTristateImpl(Module):
def __init__(self, io, o, oe, i, clk): def __init__(self, io, o, oe, i, clk, in_clk):
_o = Signal() _o = Signal()
_oe_n = Signal() _oe_n = Signal()
_i = Signal() _i = Signal()
self.specials += SDROutput(o, _o, clk) self.specials += SDROutput(o, _o, clk)
self.specials += SDROutput(~oe, _oe_n, clk) self.specials += SDROutput(~oe, _oe_n, clk)
self.specials += SDRInput(_i, i, clk) self.specials += SDRInput(_i, i, in_clk)
self.specials += Instance("IOBUF", self.specials += Instance("IOBUF",
io_IO = io, io_IO = io,
o_O = _i, o_O = _i,
@ -154,18 +154,18 @@ class XilinxSDRTristateImpl(Module):
class XilinxSDRTristate: class XilinxSDRTristate:
@staticmethod @staticmethod
def lower(dr): def lower(dr):
return XilinxSDRTristateImpl(dr.io, dr.o, dr.oe, dr.i, dr.clk) return XilinxSDRTristateImpl(dr.io, dr.o, dr.oe, dr.i, dr.clk, dr.in_clk)
# Common DDRTristate ------------------------------------------------------------------------------- # Common DDRTristate -------------------------------------------------------------------------------
class XilinxDDRTristateImpl(Module): class XilinxDDRTristateImpl(Module):
def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk): def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk, in_clk):
_o = Signal() _o = Signal()
_oe_n = Signal() _oe_n = Signal()
_i = Signal() _i = Signal()
self.specials += DDROutput(o1, o2, _o, clk) 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 += 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 += DDRInput(_i, i1, i2, in_clk)
self.specials += Instance("IOBUF", self.specials += Instance("IOBUF",
io_IO = io, io_IO = io,
o_O = _i, o_O = _i,
@ -176,7 +176,7 @@ class XilinxDDRTristateImpl(Module):
class XilinxDDRTristate: class XilinxDDRTristate:
@staticmethod @staticmethod
def lower(dr): def lower(dr):
return XilinxDDRTristateImpl(dr.io, dr.o1, dr.o2, dr.oe1, dr.oe2, dr.i1, dr.i2, dr.clk) return XilinxDDRTristateImpl(dr.io, dr.o1, dr.o2, dr.oe1, dr.oe2, dr.i1, dr.i2, dr.clk, dr.in_clk)
# Common Special Overrides ------------------------------------------------------------------------- # Common Special Overrides -------------------------------------------------------------------------