Skip to content

Commit

Permalink
Merge pull request #2083 from VOGL-electronic/efinix_common_improve
Browse files Browse the repository at this point in the history
build: efinix: EfinixTristateImpl: use GPIO Bus
  • Loading branch information
enjoy-digital authored Sep 26, 2024
2 parents c67dfa8 + a825c61 commit 95e5e73
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 46 deletions.
107 changes: 61 additions & 46 deletions litex/build/efinix/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from migen.fhdl.module import Module
from migen.genlib.resetsync import AsyncResetSynchronizer

from litex.gen import *
from litex.build.io import *

from litex.build.generic_platform import Pins
Expand Down Expand Up @@ -72,7 +73,8 @@ def lower(dr):

class EfinixClkInputImpl(Module):
n = 0
def __init__(self, platform, i, o):
def __init__(self, i, o):
platform = LiteXContext.platform
self.name = f"clk_input{self.n}"
if isinstance(o, Signal):
clk_out_name = f"{o.name_override}{self.name}_clk"
Expand Down Expand Up @@ -103,13 +105,14 @@ def __init__(self, platform, i, o):
class EfinixClkInput(Module):
@staticmethod
def lower(dr):
return EfinixClkInputImpl(dr.platform, dr.i, dr.o)
return EfinixClkInputImpl(dr.i, dr.o)

# Efinix Clk Output --------------------------------------------------------------------------------

class EfinixClkOutputImpl(Module):
def __init__(self, platform, i, o):
def __init__(self, i, o):
assert_is_signal_or_clocksignal(i)
platform = LiteXContext.platform
block = {
"type" : "GPIO",
"size" : 1,
Expand All @@ -121,49 +124,54 @@ def __init__(self, platform, i, o):
platform.toolchain.ifacewriter.blocks.append(block)
platform.toolchain.excluded_ios.append(o)


class EfinixClkOutput(Module):
@staticmethod
def lower(dr):
return EfinixClkOutputImpl(dr.platform, dr.i, dr.o)
return EfinixClkOutputImpl(dr.i, dr.o)

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

class EfinixTristateImpl(Module):
def __init__(self, platform, io, o, oe, i=None):
nbits, sign = value_bits_sign(io)

for bit in range(nbits):
io_name = platform.get_pin_name(io[bit])
io_loc = platform.get_pin_location(io[bit])
io_prop = platform.get_pin_properties(io[bit])
io_o = platform.add_iface_io(io_name + "_OUT")
io_oe = platform.add_iface_io(io_name + "_OE")
io_i = platform.add_iface_io(io_name + "_IN")
self.comb += io_o.eq(o >> bit)
self.comb += io_oe.eq(oe)
if i is not None:
self.comb += i[bit].eq(io_i)
block = {
"type" : "GPIO",
"mode" : "INOUT",
"name" : io_name,
"location" : [io_loc[0]],
"properties" : io_prop
}

platform.toolchain.ifacewriter.blocks.append(block)
def __init__(self, io, o, oe, i=None):
platform = LiteXContext.platform
if len(io) == 1:
io_name = platform.get_pin_name(io)
io_pad = platform.get_pin_location(io)
io_prop = platform.get_pin_properties(io)
else:
io_name = platform.get_pins_name(io)
io_pad = platform.get_pins_location(io)
io_prop = platform.get_pin_properties(io[0])
io_prop_dict = dict(io_prop)
io_data_i = platform.add_iface_io(io_name + "_OUT")
io_data_o = platform.add_iface_io(io_name + "_IN")
io_data_e = platform.add_iface_io(io_name + "_OE")
self.comb += io_data_i.eq(o)
self.comb += io_data_e.eq(oe)
if i is not None:
self.comb += i.eq(io_data_o)
block = {
"type" : "GPIO",
"mode" : "INOUT",
"name" : io_name,
"location" : io_pad,
"properties" : io_prop,
"size" : len(io),
"drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4")
}
platform.toolchain.ifacewriter.blocks.append(block)
platform.toolchain.excluded_ios.append(platform.get_pin(io))

class EfinixTristate(Module):
@staticmethod
def lower(dr):
return EfinixTristateImpl(dr.platform, dr.target, dr.o, dr.oe, dr.i)
return EfinixTristateImpl(dr.target, dr.o, dr.oe, dr.i)

# Efinix DifferentialOutput ------------------------------------------------------------------------

class EfinixDifferentialOutputImpl(Module):
def __init__(self, platform, i, o_p, o_n):
def __init__(self, i, o_p, o_n):
platform = LiteXContext.platform
# only keep _p
io_name = platform.get_pin_name(o_p)
io_pad = platform.get_pad_name(o_p) # need real pad name
Expand Down Expand Up @@ -202,12 +210,13 @@ def __init__(self, platform, i, o_p, o_n):
class EfinixDifferentialOutput:
@staticmethod
def lower(dr):
return EfinixDifferentialOutputImpl(dr.platform, dr.i, dr.o_p, dr.o_n)
return EfinixDifferentialOutputImpl(dr.i, dr.o_p, dr.o_n)

# Efinix DifferentialInput -------------------------------------------------------------------------

class EfinixDifferentialInputImpl(Module):
def __init__(self, platform, i_p, i_n, o):
def __init__(self, i_p, i_n, o):
platform = LiteXContext.platform
# only keep _p
io_name = platform.get_pin_name(i_p)
io_pad = platform.get_pad_name(i_p) # need real pad name
Expand Down Expand Up @@ -261,14 +270,15 @@ def __init__(self, platform, i_p, i_n, o):
class EfinixDifferentialInput:
@staticmethod
def lower(dr):
return EfinixDifferentialInputImpl(dr.platform, dr.i_p, dr.i_n, dr.o)
return EfinixDifferentialInputImpl(dr.i_p, dr.i_n, dr.o)

# Efinix DDRTristate -------------------------------------------------------------------------------

class EfinixDDRTristateImpl(Module):
def __init__(self, platform, io, o1, o2, oe1, oe2, i1, i2, clk):
def __init__(self, io, o1, o2, oe1, oe2, i1, i2, clk):
assert oe1 == oe2
assert_is_signal_or_clocksignal(clk)
platform = LiteXContext.platform
io_name = platform.get_pin_name(io)
io_pad = platform.get_pin_location(io)
io_prop = platform.get_pin_properties(io)
Expand Down Expand Up @@ -305,13 +315,14 @@ def __init__(self, platform, io, o1, o2, oe1, oe2, i1, i2, clk):
class EfinixDDRTristate:
@staticmethod
def lower(dr):
return EfinixDDRTristateImpl(dr.platform, 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)

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

class EfinixSDRTristateImpl(EfinixDDRTristateImpl):
def __init__(self, platform, io, o, oe, i, clk):
class EfinixSDRTristateImpl(Module):
def __init__(self, io, o, oe, i, clk):
assert_is_signal_or_clocksignal(clk)
platform = LiteXContext.platform
io_name = platform.get_pin_name(io)
io_pad = platform.get_pin_location(io)
io_prop = platform.get_pin_properties(io)
Expand Down Expand Up @@ -345,13 +356,14 @@ def __init__(self, platform, io, o, oe, i, clk):
class EfinixSDRTristate(Module):
@staticmethod
def lower(dr):
return EfinixSDRTristateImpl(dr.platform, dr.io, dr.o, dr.oe, dr.i, dr.clk)
return EfinixSDRTristateImpl(dr.io, dr.o, dr.oe, dr.i, dr.clk)

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

class EfinixSDROutputImpl(Module):
def __init__(self, platform, i, o, clk):
def __init__(self, i, o, clk):
assert_is_signal_or_clocksignal(clk)
platform = LiteXContext.platform
io_name = platform.get_pin_name(o)
io_pad = platform.get_pin_location(o)
io_prop = platform.get_pin_properties(o)
Expand All @@ -377,13 +389,14 @@ def __init__(self, platform, i, o, clk):
class EfinixSDROutput(Module):
@staticmethod
def lower(dr):
return EfinixSDROutputImpl(dr.platform, dr.i, dr.o, dr.clk)
return EfinixSDROutputImpl(dr.i, dr.o, dr.clk)

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

class EfinixDDROutputImpl(Module):
def __init__(self, platform, i1, i2, o, clk):
def __init__(self, i1, i2, o, clk):
assert_is_signal_or_clocksignal(clk)
platform = LiteXContext.platform
io_name = platform.get_pin_name(o)
io_pad = platform.get_pin_location(o)
io_prop = platform.get_pin_properties(o)
Expand All @@ -410,13 +423,14 @@ def __init__(self, platform, i1, i2, o, clk):
class EfinixDDROutput:
@staticmethod
def lower(dr):
return EfinixDDROutputImpl(dr.platform, dr.i1, dr.i2, dr.o, dr.clk)
return EfinixDDROutputImpl(dr.i1, dr.i2, dr.o, dr.clk)

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

class EfinixSDRInputImpl(Module):
def __init__(self, platform, i, o, clk):
def __init__(self, i, o, clk):
assert_is_signal_or_clocksignal(clk)
platform = LiteXContext.platform
io_name = platform.get_pin_name(i)
io_pad = platform.get_pin_location(i)
io_prop = platform.get_pin_properties(i)
Expand All @@ -439,13 +453,14 @@ def __init__(self, platform, i, o, clk):
class EfinixSDRInput:
@staticmethod
def lower(dr):
return EfinixSDRInputImpl(dr.platform, dr.i, dr.o, dr.clk)
return EfinixSDRInputImpl(dr.i, dr.o, dr.clk)

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

class EfinixDDRInputImpl(Module):
def __init__(self, platform, i, o1, o2, clk):
def __init__(self, i, o1, o2, clk):
assert_is_signal_or_clocksignal(clk)
platform = LiteXContext.platform
io_name = platform.get_pin_name(i)
io_pad = platform.get_pin_location(i)
io_prop = platform.get_pin_properties(i)
Expand All @@ -470,7 +485,7 @@ def __init__(self, platform, i, o1, o2, clk):
class EfinixDDRInput:
@staticmethod
def lower(dr):
return EfinixDDRInputImpl(dr.platform, dr.i, dr.o1, dr.o2, dr.clk)
return EfinixDDRInputImpl(dr.i, dr.o1, dr.o2, dr.clk)

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

Expand Down
21 changes: 21 additions & 0 deletions litex/build/efinix/platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,15 @@ def get_pin_location(self, sig):
return [pins[idx]]
return None

def get_pins_location(self, sig):
if sig is None:
return None
sc = self.constraint_manager.get_sig_constraints()
for s, pins, others, resource in sc:
if (s == sig) and (pins[0] != 'X'):
return pins
return None

def get_pin_properties(self, sig):
ret = []
if sig is None:
Expand Down Expand Up @@ -150,6 +159,18 @@ def get_pin_name(self, sig):
return name
return None

def get_pins_name(self, sig):
if sig is None:
return None
sc = self.constraint_manager.get_sig_constraints()
for s, pins, others, resource in sc:
if s == sig:
name = resource[0] + (f"{resource[1]}" if resource[1] is not None else "")
if resource[2]:
name = name + "_" + resource[2]
return name
return None

def get_pad_name(self, sig):
""" Return pin name (GPIOX_Y_ZZZ).
Expand Down

0 comments on commit 95e5e73

Please sign in to comment.