Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: efinix: allow clk inverting and different in clk on reg tristates #2087

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 25 additions & 24 deletions litex/build/efinix/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def lower(dr):
# Efinix Clk Output --------------------------------------------------------------------------------

class EfinixClkOutputImpl(LiteXModule):
def __init__(self, i, o):
def __init__(self, i, o, out_clk_inv=False):
assert_is_signal_or_clocksignal(i)
platform = LiteXContext.platform
block = {
Expand All @@ -119,14 +119,15 @@ def __init__(self, i, o):
"properties" : platform.get_pin_properties(o),
"name" : i,
"mode" : "OUTPUT_CLK",
"out_clk_inv": 1 if out_clk_inv else 0,
}
platform.toolchain.ifacewriter.blocks.append(block)
platform.toolchain.excluded_ios.append(o)

class EfinixClkOutput(LiteXModule):
@staticmethod
def lower(dr):
return EfinixClkOutputImpl(dr.i, dr.o)
return EfinixClkOutputImpl(dr.i, dr.o, **dr.kwargs)

# Efinix Tristate ----------------------------------------------------------------------------------

Expand Down Expand Up @@ -274,7 +275,7 @@ def lower(dr):
# Efinix DDRTristate -------------------------------------------------------------------------------

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, out_clk_inv=False, in_clk_inv=False, in_clk=None):
assert oe1 == oe2
assert_is_signal_or_clocksignal(clk)
platform = LiteXContext.platform
Expand All @@ -300,12 +301,12 @@ def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk):
"properties" : io_prop,
"size" : 1,
"in_reg" : "DDIO_RESYNC",
"in_clk_pin" : clk,
"in_clk_pin" : clk if in_clk is None else in_clk,
"out_reg" : "DDIO_RESYNC",
"out_clk_pin" : clk,
"oe_reg" : "REG",
"in_clk_inv" : 0,
"out_clk_inv" : 0,
"in_clk_inv" : 1 if in_clk_inv else 0,
"out_clk_inv" : 1 if out_clk_inv else 0,
"drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4")
}
platform.toolchain.ifacewriter.blocks.append(block)
Expand All @@ -314,12 +315,12 @@ def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk):
class EfinixDDRTristate:
@staticmethod
def lower(dr):
return EfinixDDRTristateImpl(dr.io, dr.o1, dr.o2, dr.oe1, dr.oe2, dr.i1, dr.i2, dr.clk)
return EfinixDDRTristateImpl(dr.io, dr.o1, dr.o2, dr.oe1, dr.oe2, dr.i1, dr.i2, dr.clk, **dr.kwargs)

# Efinix SDRTristate -------------------------------------------------------------------------------

class EfinixSDRTristateImpl(LiteXModule):
def __init__(self, io, o, oe, i, clk):
def __init__(self, io, o, oe, i, clk, out_clk_inv=False, in_clk_inv=False, in_clk=None):
assert_is_signal_or_clocksignal(clk)
platform = LiteXContext.platform
io_name = platform.get_pin_name(io)
Expand All @@ -340,12 +341,12 @@ def __init__(self, io, o, oe, i, clk):
"properties" : io_prop,
"size" : 1,
"in_reg" : "REG",
"in_clk_pin" : clk,
"in_clk_pin" : clk if in_clk is None else in_clk,
"out_reg" : "REG",
"out_clk_pin" : clk,
"oe_reg" : "REG",
"in_clk_inv" : 0,
"out_clk_inv" : 0,
"in_clk_inv" : 1 if in_clk_inv else 0,
"out_clk_inv" : 1 if out_clk_inv else 0,
"drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4")
}
platform.toolchain.ifacewriter.blocks.append(block)
Expand All @@ -355,12 +356,12 @@ def __init__(self, io, o, oe, i, clk):
class EfinixSDRTristate(LiteXModule):
@staticmethod
def lower(dr):
return EfinixSDRTristateImpl(dr.io, dr.o, dr.oe, dr.i, dr.clk)
return EfinixSDRTristateImpl(dr.io, dr.o, dr.oe, dr.i, dr.clk, **dr.kwargs)

# Efinix SDROutput ---------------------------------------------------------------------------------

class EfinixSDROutputImpl(LiteXModule):
def __init__(self, i, o, clk):
def __init__(self, i, o, clk, out_clk_inv=False):
assert_is_signal_or_clocksignal(clk)
platform = LiteXContext.platform
io_name = platform.get_pin_name(o)
Expand All @@ -378,7 +379,7 @@ def __init__(self, i, o, clk):
"size" : 1,
"out_reg" : "REG",
"out_clk_pin" : clk,
"out_clk_inv" : 0,
"out_clk_inv" : 1 if out_clk_inv else 0,
"drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4")
}
platform.toolchain.ifacewriter.blocks.append(block)
Expand All @@ -388,12 +389,12 @@ def __init__(self, i, o, clk):
class EfinixSDROutput(LiteXModule):
@staticmethod
def lower(dr):
return EfinixSDROutputImpl(dr.i, dr.o, dr.clk)
return EfinixSDROutputImpl(dr.i, dr.o, dr.clk, **dr.kwargs)

# Efinix DDROutput ---------------------------------------------------------------------------------

class EfinixDDROutputImpl(LiteXModule):
def __init__(self, i1, i2, o, clk):
def __init__(self, i1, i2, o, clk, out_clk_inv=False):
assert_is_signal_or_clocksignal(clk)
platform = LiteXContext.platform
io_name = platform.get_pin_name(o)
Expand All @@ -413,7 +414,7 @@ def __init__(self, i1, i2, o, clk):
"size" : 1,
"out_reg" : "DDIO_RESYNC",
"out_clk_pin" : clk,
"out_clk_inv" : 0,
"out_clk_inv" : 1 if out_clk_inv else 0,
"drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4")
}
platform.toolchain.ifacewriter.blocks.append(block)
Expand All @@ -422,12 +423,12 @@ def __init__(self, i1, i2, o, clk):
class EfinixDDROutput:
@staticmethod
def lower(dr):
return EfinixDDROutputImpl(dr.i1, dr.i2, dr.o, dr.clk)
return EfinixDDROutputImpl(dr.i1, dr.i2, dr.o, dr.clk, **dr.kwargs)

# Efinix SDRInput ----------------------------------------------------------------------------------

class EfinixSDRInputImpl(LiteXModule):
def __init__(self, i, o, clk):
def __init__(self, i, o, clk, in_clk_inv=False):
assert_is_signal_or_clocksignal(clk)
platform = LiteXContext.platform
io_name = platform.get_pin_name(i)
Expand All @@ -444,20 +445,20 @@ def __init__(self, i, o, clk):
"size" : 1,
"in_reg" : "REG",
"in_clk_pin" : clk,
"in_clk_inv" : 0
"in_clk_inv" : 1 if in_clk_inv else 0,
}
platform.toolchain.ifacewriter.blocks.append(block)
platform.toolchain.excluded_ios.append(platform.get_pin(i))

class EfinixSDRInput:
@staticmethod
def lower(dr):
return EfinixSDRInputImpl(dr.i, dr.o, dr.clk)
return EfinixSDRInputImpl(dr.i, dr.o, dr.clk, **dr.kwargs)

# Efinix DDRInput ----------------------------------------------------------------------------------

class EfinixDDRInputImpl(LiteXModule):
def __init__(self, i, o1, o2, clk):
def __init__(self, i, o1, o2, clk, in_clk_inv=False):
assert_is_signal_or_clocksignal(clk)
platform = LiteXContext.platform
io_name = platform.get_pin_name(i)
Expand All @@ -476,15 +477,15 @@ def __init__(self, i, o1, o2, clk):
"size" : 1,
"in_reg" : "DDIO_RESYNC",
"in_clk_pin" : clk,
"in_clk_inv" : 0
"in_clk_inv" : 1 if in_clk_inv else 0,
}
platform.toolchain.ifacewriter.blocks.append(block)
platform.toolchain.excluded_ios.append(platform.get_pin(i))

class EfinixDDRInput:
@staticmethod
def lower(dr):
return EfinixDDRInputImpl(dr.i, dr.o1, dr.o2, dr.clk)
return EfinixDDRInputImpl(dr.i, dr.o1, dr.o2, dr.clk, **dr.kwargs)

# Efinix Special Overrides -------------------------------------------------------------------------

Expand Down
2 changes: 2 additions & 0 deletions litex/build/efinix/ifacewriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,8 @@ def generate_gpio(self, block, verbose=True):
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 "out_clk_inv" in block:
cmd += f'design.set_property("{name}","IS_OUTCLK_INVERTED","{block["out_clk_inv"]}")\n'
if prop:
for p, val in prop:
cmd += 'design.set_property("{}","{}","{}")\n'.format(name, p, val)
Expand Down
27 changes: 18 additions & 9 deletions litex/build/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@
# Differential Input/Output ------------------------------------------------------------------------

class DifferentialInput(Special):
def __init__(self, i_p, i_n, o):
def __init__(self, i_p, i_n, o, **kwargs):
Special.__init__(self)
self.i_p = wrap(i_p)
self.i_n = wrap(i_n)
self.o = wrap(o)
self.kwargs = kwargs

def iter_expressions(self):
yield self, "i_p", SPECIAL_INPUT
Expand All @@ -28,11 +29,12 @@ def lower(dr):


class DifferentialOutput(Special):
def __init__(self, i, o_p, o_n):
def __init__(self, i, o_p, o_n, **kwargs):
Special.__init__(self)
self.i = wrap(i)
self.o_p = wrap(o_p)
self.o_n = wrap(o_n)
self.kwargs = kwargs

def iter_expressions(self):
yield self, "i" , SPECIAL_INPUT
Expand All @@ -46,10 +48,11 @@ def lower(dr):
# Clk Input/Output ---------------------------------------------------------------------------------

class ClkInput(Special):
def __init__(self, i, o):
def __init__(self, i, o, **kwargs):
Special.__init__(self)
self.i = wrap(i)
self.o = o if isinstance(o, str) else wrap(o)
self.kwargs = kwargs

def iter_expressions(self):
yield self, "i", SPECIAL_INPUT
Expand All @@ -61,10 +64,11 @@ def lower(dr):


class ClkOutput(Special):
def __init__(self, i, o):
def __init__(self, i, o, **kwargs):
Special.__init__(self)
self.i = i if isinstance(i, str) else wrap(i)
self.o = wrap(o)
self.kwargs = kwargs

def iter_expressions(self):
yield self, "i", SPECIAL_INPUT
Expand All @@ -83,7 +87,7 @@ def __init__(self, i, o, clk):
self.sync.sdrio += o.eq(i)

class SDRIO(Special):
def __init__(self, i, o, clk=None):
def __init__(self, i, o, clk=None, **kwargs):
assert len(i) == len(o) == 1
Special.__init__(self)
self.i = wrap(i)
Expand All @@ -92,6 +96,7 @@ def __init__(self, i, o, clk=None):
clk = ClockSignal()
self.clk = wrap(clk)
self.clk_domain = None if not hasattr(clk, "cd") else clk.cd
self.kwargs = kwargs

def iter_expressions(self):
yield self, "i" , SPECIAL_INPUT
Expand Down Expand Up @@ -119,14 +124,15 @@ def __init__(self, io, o, oe, i, clk):
self.specials += Tristate(io, _o, _oe, _i)

class SDRTristate(Special):
def __init__(self, io, o, oe, i, clk=None):
def __init__(self, io, o, oe, i, clk=None, **kwargs):
assert len(i) == len(o) == len(oe)
Special.__init__(self)
self.io = wrap(io)
self.o = wrap(o)
self.oe = wrap(oe)
self.i = wrap(i)
self.clk = wrap(clk) if clk is not None else ClockSignal()
self.kwargs = kwargs

def iter_expressions(self):
yield self, "io" , SPECIAL_INOUT
Expand All @@ -142,14 +148,15 @@ def lower(dr):
# DDR Input/Output ---------------------------------------------------------------------------------

class DDRInput(Special):
def __init__(self, i, o1, o2, clk=None):
def __init__(self, i, o1, o2, clk=None, **kwargs):
Special.__init__(self)
self.i = wrap(i)
self.o1 = wrap(o1)
self.o2 = wrap(o2)
if clk is None:
clk = ClockSignal()
self.clk = clk if isinstance(clk, str) else wrap(clk)
self.kwargs = kwargs

def iter_expressions(self):
yield self, "i" , SPECIAL_INPUT
Expand All @@ -163,14 +170,15 @@ def lower(dr):


class DDROutput(Special):
def __init__(self, i1, i2, o, clk=None):
def __init__(self, i1, i2, o, clk=None, **kwargs):
Special.__init__(self)
self.i1 = wrap(i1)
self.i2 = wrap(i2)
self.o = wrap(o)
if clk is None:
clk = ClockSignal()
self.clk = clk if isinstance(clk, str) else wrap(clk)
self.kwargs = kwargs

def iter_expressions(self):
yield self, "i1" , SPECIAL_INPUT
Expand All @@ -195,7 +203,7 @@ def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk):
self.specials += Tristate(io, _o, _oe, _i)

class DDRTristate(Special):
def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk=None):
def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk=None, **kwargs):
Special.__init__(self)
self.io = io
self.o1 = o1
Expand All @@ -205,6 +213,7 @@ def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk=None):
self.i1 = i1
self.i2 = i2
self.clk = clk if clk is not None else ClockSignal()
self.kwargs = kwargs

def iter_expressions(self):
yield self, "io" , SPECIAL_INOUT
Expand Down
Loading