Skip to content

Commit

Permalink
build: efinix: implement QDR input, output and tristade.
Browse files Browse the repository at this point in the history
implement QDR input, output and
tristade for the titanium.

Signed-off-by: Fin Maaß <[email protected]>
  • Loading branch information
maass-hamburg committed Sep 19, 2024
1 parent 47b6f1e commit 1080ea6
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 0 deletions.
126 changes: 126 additions & 0 deletions litex/build/efinix/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,129 @@ class EfinixDDRInput:
def lower(dr):
return EfinixDDRInputImpl(dr.platform, dr.i, dr.o1, dr.o2, dr.clk)

# Efinix QDROutput ---------------------------------------------------------------------------------

class EfinixQDROutputImpl(Module):
def __init__(self, platform, i1, i2, i3, i4, o, clk, fastclk):
assert fastclk is not None
io_name = platform.get_pin_name(o)
io_pad = platform.get_pin_location(o)
io_prop = platform.get_pin_properties(o)
io_prop_dict = dict(io_prop)
io_data = platform.add_iface_io(io_name, 4)
self.comb += io_data[0].eq(i1)
self.comb += io_data[1].eq(i2)
self.comb += io_data[2].eq(i3)
self.comb += io_data[3].eq(i4)
block = {
"type" : "GPIO",
"mode" : "OUTPUT",
"name" : io_name,
"location" : io_pad,
"properties" : io_prop,
"size" : 1,
"out_reg" : "SERIAL",
"out_clk_pin" : clk.name_override, # FIXME.
"outfastclk_pin" : fastclk.name_override, # FIXME.
"is_inclk_inverted" : False,
"drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4")
}
platform.toolchain.ifacewriter.blocks.append(block)
platform.toolchain.excluded_ios.append(platform.get_pin(o))

class EfinixQDROutput:
@staticmethod
def lower(dr):
if dr.platform.family == "Trion":
raise NotImplementedError("Attempted to use a QDR output, but platform does not support them")
return EfinixQDROutputImpl(dr.platform, dr.i1, dr.i2, dr.i3, dr.i4, dr.o, dr.clk, dr.fastclk)

# Efinix QDRInput ----------------------------------------------------------------------------------

class EfinixQDRInputImpl(Module):
def __init__(self, platform, i, o1, o2, o3, o4, clk, fastclk):
assert fastclk is not None
io_name = platform.get_pin_name(i)
io_pad = platform.get_pin_location(i)
io_prop = platform.get_pin_properties(i)
io_data = platform.add_iface_io(io_name, 4)
self.comb += o1.eq(io_data[0])
self.comb += o2.eq(io_data[1])
self.comb += o3.eq(io_data[2])
self.comb += o4.eq(io_data[3])
block = {
"type" : "GPIO",
"mode" : "INPUT",
"name" : io_name,
"location" : io_pad,
"properties" : io_prop,
"size" : 1,
"in_reg" : "SERIAL",
"in_clk_pin" : clk.name_override, # FIXME.
"infastclk_pin" : fastclk.name_override, # FIXME.
"is_inclk_inverted" : False,
}
platform.toolchain.ifacewriter.blocks.append(block)
platform.toolchain.excluded_ios.append(platform.get_pin(i))

class EfinixQDRInput:
@staticmethod
def lower(dr):
if dr.platform.family == "Trion":
raise NotImplementedError("Attempted to use a QDR input, but platform does not support them")
return EfinixQDRInputImpl(dr.platform, dr.i, dr.o1, dr.o2, dr.o3, dr.o4, dr.clk, dr.fastclk)

# Efinix QDRTristate ---------------------------------------------------------------------------------

class EfinixQDRTristateImpl(Module):
def __init__(self, platform, io, o1, o2, o3, o4, oe, i1, i2, i3, i4, clk, fastclk):
assert fastclk is not None
io_name = platform.get_pin_name(io)
io_pad = platform.get_pin_location(io)
io_prop = platform.get_pin_properties(io)
io_prop_dict = dict(io_prop)
io_data_i = platform.add_iface_io(io_name + "_OUT", 4)
io_data_o = platform.add_iface_io(io_name + "_IN", 4)
io_data_e = platform.add_iface_io(io_name + "_OE")
self.comb += io_data_i[0].eq(o1)
self.comb += io_data_i[1].eq(o2)
self.comb += io_data_i[2].eq(o3)
self.comb += io_data_i[3].eq(o4)
self.comb += io_data_e.eq(oe)
self.comb += i1.eq(io_data_o[0])
self.comb += i2.eq(io_data_o[1])
self.comb += i3.eq(io_data_o[2])
self.comb += i4.eq(io_data_o[3])
block = {
"type" : "GPIO",
"mode" : "INOUT",
"name" : io_name,
"location" : io_pad,
"properties" : io_prop,
"size" : 1,
"in_reg" : "SERIAL",
"in_clk_pin" : clk.name_override, # FIXME.
"infastclk_pin" : fastclk.name_override, # FIXME.
"out_reg" : "SERIAL",
"out_clk_pin" : clk.name_override, # FIXME.
"outfastclk_pin" : fastclk.name_override, # FIXME.
"oe_reg" : "REG",
"is_inclk_inverted" : False,
"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 EfinixQDRTristate:
@staticmethod
def lower(dr):
assert dr.oe2 is None
assert dr.oe3 is None
assert dr.oe4 is None
if dr.platform.family == "Trion":
raise NotImplementedError("Attempted to use a QDR tristate, but platform does not support them")
return EfinixQDRTristateImpl(dr.platform, dr.io, dr.o1, dr.o2, dr.o3, dr.o4, dr.oe1, dr.i1, dr.i2, dr.i3, dr.i4, dr.clk, dr.fastclk)

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

efinix_special_overrides = {
Expand All @@ -436,4 +559,7 @@ def lower(dr):
DDROutput : EfinixDDROutput,
DDRInput : EfinixDDRInput,
DDRTristate : EfinixDDRTristate,
QDRInput : EfinixQDRInput,
QDROutput : EfinixQDROutput,
QDRTristate : EfinixQDRTristate,
}
11 changes: 11 additions & 0 deletions litex/build/efinix/ifacewriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ def generate_gpio(self, block, verbose=True):
if "out_delay" in block:
cmd += f'design.set_property("{name}","OUTDELAY","{block["out_delay"]}")\n'

if "outfastclk_pin" in block:
cmd += 'design.set_property("{}","OUTFASTCLK_PIN","{}")\n'.format(name, block["outfastclk_pin"])

if "out_clk_inv" in block:
cmd += f'design.set_property("{name}","IS_OUTCLK_INVERTED","{block["out_clk_inv"]}")\n'
cmd += f'design.set_property("{name}","OE_CLK_PIN_INV","{block["out_clk_inv"]}")\n'
Expand All @@ -184,6 +187,9 @@ def generate_gpio(self, block, verbose=True):
if "in_delay" in block:
cmd += f'design.set_property("{name}","INDELAY","{block["in_delay"]}")\n'

if "infastclk_pin" in block:
cmd += 'design.set_property("{}","INFASTCLK_PIN","{}")\n'.format(name, block["infastclk_pin"])

if "in_clk_inv" in block:
cmd += f'design.set_property("{name}","IS_INCLK_INVERTED","{block["in_clk_inv"]}")\n'

Expand Down Expand Up @@ -216,6 +222,8 @@ def generate_gpio(self, block, verbose=True):
cmd += f'design.set_property("{name}","IN_CLK_PIN","{block["in_clk_pin"]}")\n'
if "in_delay" in block:
cmd += f'design.set_property("{name}","INDELAY","{block["in_delay"]}")\n'
if "infastclk_pin" in block:
cmd += 'design.set_property("{}","INFASTCLK_PIN","{}")\n'.format(name, block["infastclk_pin"])
if prop:
for p, val in prop:
cmd += 'design.set_property("{}","{}","{}")\n'.format(name, p, val)
Expand All @@ -237,6 +245,9 @@ def generate_gpio(self, block, verbose=True):
if "out_delay" in block:
cmd += 'design.set_property("{}","OUTDELAY","{}")\n'.format(name, block["out_delay"])

if "outfastclk_pin" in block:
cmd += 'design.set_property("{}","OUTFASTCLK_PIN","{}")\n'.format(name, block["outfastclk_pin"])

if "out_clk_inv" in block:
cmd += f'design.set_property("{name}","IS_OUTCLK_INVERTED","{block["out_clk_inv"]}")\n'
cmd += f'design.set_property("{name}","OE_CLK_PIN_INV","{block["out_clk_inv"]}")\n'
Expand Down

0 comments on commit 1080ea6

Please sign in to comment.