Merge pull request #1134 from fjullien/efinix_titanium_support
Efinix titanium support
This commit is contained in:
commit
321b91d551
|
@ -65,24 +65,38 @@ class EfinixAsyncResetSynchronizer:
|
||||||
class EfinixTristateImpl(Module):
|
class EfinixTristateImpl(Module):
|
||||||
def __init__(self, platform, io, o, oe, i=None):
|
def __init__(self, platform, io, o, oe, i=None):
|
||||||
nbits, sign = value_bits_sign(io)
|
nbits, sign = value_bits_sign(io)
|
||||||
assert nbits == 1
|
|
||||||
io_name = platform.get_pin_name(io)
|
for bit in range(nbits):
|
||||||
io_loc = platform.get_pin_location(io)
|
io_name = platform.get_pin_name(io[bit])
|
||||||
io_o = platform.add_iface_io(io_name + "_OUT")
|
io_loc = platform.get_pin_location(io[bit])
|
||||||
io_oe = platform.add_iface_io(io_name + "_OE")
|
io_prop = platform.get_pin_properties(io[bit])
|
||||||
io_i = platform.add_iface_io(io_name + "_IN")
|
io_o = platform.add_iface_io(io_name + "_OUT")
|
||||||
self.comb += io_o.eq(o)
|
io_oe = platform.add_iface_io(io_name + "_OE")
|
||||||
self.comb += io_oe.eq(oe)
|
io_i = platform.add_iface_io(io_name + "_IN")
|
||||||
if i is not None:
|
self.comb += io_o.eq(o[bit])
|
||||||
self.comb += i.eq(io_i)
|
self.comb += io_oe.eq(oe)
|
||||||
block = {
|
if i[bit] is not None:
|
||||||
"type" : "GPIO",
|
self.comb += i[bit].eq(io_i)
|
||||||
"mode" : "INOUT",
|
block = {
|
||||||
"name" : io_name,
|
"type" : "GPIO",
|
||||||
"location" : [io_loc[0]],
|
"mode" : "INOUT",
|
||||||
}
|
"name" : io_name,
|
||||||
platform.toolchain.ifacewriter.blocks.append(block)
|
"location" : [io_loc[0]],
|
||||||
platform.toolchain.excluded_ios.append(io_name)
|
"properties" : io_prop
|
||||||
|
}
|
||||||
|
|
||||||
|
platform.toolchain.ifacewriter.blocks.append(block)
|
||||||
|
|
||||||
|
# Remove the group from the io list
|
||||||
|
exclude = platform.get_pin_name(io[0], without_index=True)
|
||||||
|
|
||||||
|
# In case of a single signal, there is still a '0' index
|
||||||
|
# to be remove at the end
|
||||||
|
if (nbits == 1) and (exclude[:-1] == '0'):
|
||||||
|
exclude = exclude[:-1]
|
||||||
|
|
||||||
|
platform.toolchain.excluded_ios.append(exclude)
|
||||||
|
|
||||||
|
|
||||||
class EfinixTristate(Module):
|
class EfinixTristate(Module):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -115,6 +115,10 @@ def _format_constraint(c, signame, fmt_r, fragment, platform):
|
||||||
prop = "DRIVE_STRENGTH"
|
prop = "DRIVE_STRENGTH"
|
||||||
val = c.misc.split("=")[1]
|
val = c.misc.split("=")[1]
|
||||||
|
|
||||||
|
if "SLEWRATE" in c.misc:
|
||||||
|
prop = "SLEW_RATE"
|
||||||
|
val = "1"
|
||||||
|
|
||||||
if prop == "":
|
if prop == "":
|
||||||
# Print error, warning ??
|
# Print error, warning ??
|
||||||
return ""
|
return ""
|
||||||
|
|
|
@ -108,6 +108,7 @@ design.create("{2}", "{3}", "./../gateware", overwrite=True)
|
||||||
def generate_gpio(self, block, verbose=True):
|
def generate_gpio(self, block, verbose=True):
|
||||||
name = block["name"]
|
name = block["name"]
|
||||||
mode = block["mode"]
|
mode = block["mode"]
|
||||||
|
prop = block["properties"]
|
||||||
cmd = ""
|
cmd = ""
|
||||||
|
|
||||||
if mode == "INOUT":
|
if mode == "INOUT":
|
||||||
|
@ -118,6 +119,9 @@ design.create("{2}", "{3}", "./../gateware", overwrite=True)
|
||||||
cmd += f'design.create_inout_gpio("{name}",{block["size"]-1},0)\n'
|
cmd += f'design.create_inout_gpio("{name}",{block["size"]-1},0)\n'
|
||||||
for i, pad in enumerate(block["location"]):
|
for i, pad in enumerate(block["location"]):
|
||||||
cmd += f'design.assign_pkg_pin("{name}[{i}]","{pad}")\n'
|
cmd += f'design.assign_pkg_pin("{name}[{i}]","{pad}")\n'
|
||||||
|
if prop:
|
||||||
|
for p, val in prop:
|
||||||
|
cmd += 'design.set_property("{}","{}","{}")\n'.format(name, p, val)
|
||||||
cmd += "\n"
|
cmd += "\n"
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
|
@ -132,6 +136,10 @@ design.create("{2}", "{3}", "./../gateware", overwrite=True)
|
||||||
if "in_reg" in block:
|
if "in_reg" in block:
|
||||||
cmd += f'design.set_property("{name}","IN_REG","{block["in_reg"]}")\n'
|
cmd += f'design.set_property("{name}","IN_REG","{block["in_reg"]}")\n'
|
||||||
cmd += f'design.set_property("{name}","IN_CLK_PIN","{block["in_clk_pin"]}")\n'
|
cmd += f'design.set_property("{name}","IN_CLK_PIN","{block["in_clk_pin"]}")\n'
|
||||||
|
if prop:
|
||||||
|
for p, val in prop:
|
||||||
|
cmd += 'design.set_property("{}","{}","{}")\n'.format(name, p, val)
|
||||||
|
cmd += "\n"
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
if mode == "OUTPUT":
|
if mode == "OUTPUT":
|
||||||
|
@ -150,6 +158,9 @@ design.create("{2}", "{3}", "./../gateware", overwrite=True)
|
||||||
if "drive_strength" in block:
|
if "drive_strength" in block:
|
||||||
cmd += 'design.set_property("{}","DRIVE_STRENGTH","4")\n'.format(name, block["drive_strength"])
|
cmd += 'design.set_property("{}","DRIVE_STRENGTH","4")\n'.format(name, block["drive_strength"])
|
||||||
|
|
||||||
|
if prop:
|
||||||
|
for p, val in prop:
|
||||||
|
cmd += 'design.set_property("{}","{}","{}")\n'.format(name, p, val)
|
||||||
cmd += "\n"
|
cmd += "\n"
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
|
@ -157,12 +168,20 @@ design.create("{2}", "{3}", "./../gateware", overwrite=True)
|
||||||
cmd += 'design.create_input_clock_gpio("{}")\n'.format(name)
|
cmd += 'design.create_input_clock_gpio("{}")\n'.format(name)
|
||||||
cmd += 'design.set_property("{}","IN_PIN","{}")\n'.format(name, name)
|
cmd += 'design.set_property("{}","IN_PIN","{}")\n'.format(name, name)
|
||||||
cmd += 'design.assign_pkg_pin("{}","{}")\n\n'.format(name, block["location"])
|
cmd += 'design.assign_pkg_pin("{}","{}")\n\n'.format(name, block["location"])
|
||||||
|
if prop:
|
||||||
|
for p, val in prop:
|
||||||
|
cmd += 'design.set_property("{}","{}","{}")\n'.format(name, p, val)
|
||||||
|
cmd += "\n"
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
if mode == "OUTPUT_CLK":
|
if mode == "OUTPUT_CLK":
|
||||||
cmd += 'design.create_clockout_gpio("{}")\n'.format(name)
|
cmd += 'design.create_clockout_gpio("{}")\n'.format(name)
|
||||||
cmd += 'design.set_property("{}","OUT_CLK_PIN","{}")\n'.format(name, name)
|
cmd += 'design.set_property("{}","OUT_CLK_PIN","{}")\n'.format(name, name)
|
||||||
cmd += 'design.assign_pkg_pin("{}","{}")\n\n'.format(name, block["location"])
|
cmd += 'design.assign_pkg_pin("{}","{}")\n\n'.format(name, block["location"])
|
||||||
|
if prop:
|
||||||
|
for p, val in prop:
|
||||||
|
cmd += 'design.set_property("{}","{}","{}")\n'.format(name, p, val)
|
||||||
|
cmd += "\n"
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
cmd = "# TODO: " + str(block) +"\n"
|
cmd = "# TODO: " + str(block) +"\n"
|
||||||
|
|
|
@ -86,7 +86,36 @@ class EfinixPlatform(GenericPlatform):
|
||||||
return [pins[idx]]
|
return [pins[idx]]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_pin_name(self, sig):
|
def get_pin_properties(self, sig):
|
||||||
|
ret = []
|
||||||
|
if sig is None:
|
||||||
|
return None
|
||||||
|
assert len(sig) == 1
|
||||||
|
|
||||||
|
if isinstance(sig, _Slice):
|
||||||
|
sig = sig.value
|
||||||
|
sc = self.constraint_manager.get_sig_constraints()
|
||||||
|
for s, pins, others, resource in sc:
|
||||||
|
if (s == sig) and (pins[0] != 'X'):
|
||||||
|
for o in others:
|
||||||
|
if isinstance(o, IOStandard):
|
||||||
|
ret.append(('IO_STANDARD', o.name))
|
||||||
|
if isinstance(o, Misc):
|
||||||
|
if o.misc in ["WEAK_PULLUP", "WEAK_PULLDOWN"]:
|
||||||
|
prop = "PULL_OPTION"
|
||||||
|
val = o.misc
|
||||||
|
if "DRIVE_STRENGTH" in o.misc:
|
||||||
|
prop = "DRIVE_STRENGTH"
|
||||||
|
val = o.misc.split("=")[1]
|
||||||
|
ret.append((prop, val))
|
||||||
|
if "SLEWRATE" in o.misc:
|
||||||
|
prop = "SLEW_RATE"
|
||||||
|
val = "1"
|
||||||
|
ret.append((prop, val))
|
||||||
|
return ret
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_pin_name(self, sig, without_index=False):
|
||||||
if sig is None:
|
if sig is None:
|
||||||
return None
|
return None
|
||||||
assert len(sig) == 1
|
assert len(sig) == 1
|
||||||
|
@ -100,7 +129,10 @@ class EfinixPlatform(GenericPlatform):
|
||||||
for s, pins, others, resource in sc:
|
for s, pins, others, resource in sc:
|
||||||
if s == sig:
|
if s == sig:
|
||||||
if resource[2]:
|
if resource[2]:
|
||||||
return resource[0] + "_" + resource[2] + (f"{idx}" if slc else "")
|
name = resource[0] + "_" + resource[2]
|
||||||
|
if without_index is False:
|
||||||
|
name = name + (f"{idx}" if slc else "")
|
||||||
|
return name
|
||||||
else:
|
else:
|
||||||
return resource[0] + (f"{idx}" if slc else "")
|
return resource[0] + (f"{idx}" if slc else "")
|
||||||
return None
|
return None
|
||||||
|
|
Loading…
Reference in New Issue