Merge pull request #2100 from VOGL-electronic/efinix_io_optimize

efinix: gpio: use constant output option
This commit is contained in:
enjoy-digital 2024-11-15 09:38:50 +01:00 committed by GitHub
commit 8041969e00
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 48 additions and 43 deletions

View File

@ -38,6 +38,20 @@ if _have_colorama:
def assert_is_signal_or_clocksignal(obj):
assert isinstance(obj, (ClockSignal, Signal)), f"Object {obj} is not a ClockSignal or Signal"
def const_output_calc(o, io):
if o.value == 0:
const_output = 0
elif len(o) == 1:
const_output = 1
else:
const_output = []
for bit in range(len(io)):
if o.value & (1 << bit):
const_output.append(1)
else:
const_output.append(0)
return const_output
# Efinix AsyncResetSynchronizer --------------------------------------------------------------------
class EfinixAsyncResetSynchronizerImpl(LiteXModule):
@ -142,12 +156,16 @@ class EfinixTristateImpl(LiteXModule):
io_pad = platform.get_pins_location(io)
io_prop = platform.get_pin_properties(io[0])
io_prop_dict = dict(io_prop)
if isinstance(o, Constant):
const_output = const_output_calc(o, io)
else:
const_output = "NONE"
io_data_i = platform.add_iface_io(io_name + "_OUT", len(io))
io_data_o = platform.add_iface_io(io_name + "_IN", len(io))
io_data_e = platform.add_iface_io(io_name + "_OE", len(io))
self.comb += io_data_i.eq(o)
io_data_e = platform.add_iface_io(io_name + "_OE", len(io))
self.comb += io_data_e.eq(oe)
if i is not None:
io_data_o = platform.add_iface_io(io_name + "_IN", len(io))
self.comb += i.eq(io_data_o)
block = {
"type" : "GPIO",
@ -156,6 +174,7 @@ class EfinixTristateImpl(LiteXModule):
"location" : io_pad,
"properties" : io_prop,
"size" : len(io),
"const_output" : const_output,
"drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4")
}
platform.toolchain.ifacewriter.blocks.append(block)
@ -326,10 +345,14 @@ class EfinixSDRTristateImpl(LiteXModule):
io_pad = platform.get_pin_location(io)
io_prop = platform.get_pin_properties(io)
io_prop_dict = dict(io_prop)
if isinstance(o, Constant):
const_output = const_output_calc(o, io)
else:
const_output = "NONE"
io_data_i = platform.add_iface_io(io_name + "_OUT")
self.comb += io_data_i.eq(o)
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)
self.comb += i.eq(io_data_o)
block = {
@ -343,6 +366,7 @@ class EfinixSDRTristateImpl(LiteXModule):
"in_clk_pin" : clk,
"out_reg" : "REG",
"out_clk_pin" : clk,
"const_output" : const_output,
"oe_reg" : "REG",
"in_clk_inv" : 0,
"out_clk_inv" : 0,
@ -367,6 +391,10 @@ class EfinixSDROutputImpl(LiteXModule):
io_pad = platform.get_pin_location(o)
io_prop = platform.get_pin_properties(o)
io_prop_dict = dict(io_prop)
if isinstance(i, Constant):
const_output = const_output_calc(i, o)
else:
const_output = "NONE"
io_data_i = platform.add_iface_io(io_name)
self.comb += io_data_i.eq(i)
block = {
@ -378,6 +406,7 @@ class EfinixSDROutputImpl(LiteXModule):
"size" : 1,
"out_reg" : "REG",
"out_clk_pin" : clk,
"const_output" : const_output,
"out_clk_inv" : 0,
"drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4")
}

View File

@ -169,38 +169,9 @@ design.create("{2}", "{3}", "./../gateware", overwrite=True)
for i, pad in enumerate(block["location"]):
cmd += f'design.assign_pkg_pin("{name}[{i}]","{pad}")\n'
if "out_reg" in block:
cmd += f'design.set_property("{name}","OUT_REG","{block["out_reg"]}")\n'
cmd += f'design.set_property("{name}","OUT_CLK_PIN","{block["out_clk_pin"]}")\n'
if "out_delay" in block:
cmd += f'design.set_property("{name}","OUTDELAY","{block["out_delay"]}")\n'
if "out_clk_inv" in block:
cmd += f'design.set_property("{name}","IS_OUTCLK_INVERTED","{block["out_clk_inv"]}")\n'
if "in_reg" in block:
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'
if "in_delay" in block:
cmd += f'design.set_property("{name}","INDELAY","{block["in_delay"]}")\n'
if "in_clk_inv" in block:
cmd += f'design.set_property("{name}","IS_INCLK_INVERTED","{block["in_clk_inv"]}")\n'
if "oe_reg" in block:
cmd += f'design.set_property("{name}","OE_REG","{block["oe_reg"]}")\n'
if "drive_strength" in block:
cmd += 'design.set_property("{}","DRIVE_STRENGTH","{}")\n'.format(name, block["drive_strength"])
if "slewrate" in block:
cmd += 'design.set_property("{}","SLEWRATE","{}")\n'.format(name, block["slewrate"])
if prop:
for p, val in prop:
cmd += 'design.set_property("{}","{}","{}")\n'.format(name, p, val)
cmd += "\n"
return cmd
if mode == "INPUT":
if len(block["location"]) == 1:
cmd += f'design.create_input_gpio("{name}")\n'
@ -209,6 +180,8 @@ design.create("{2}", "{3}", "./../gateware", overwrite=True)
cmd += f'design.create_input_gpio("{name}",{block["size"]-1},0)\n'
for i, pad in enumerate(block["location"]):
cmd += f'design.assign_pkg_pin("{name}[{i}]","{pad}")\n'
if mode == "INPUT" or mode == "INOUT":
if "in_reg" in block:
in_clk_pin = block["in_clk_pin"]
if isinstance(in_clk_pin, ClockSignal):
@ -225,21 +198,17 @@ design.create("{2}", "{3}", "./../gateware", overwrite=True)
cmd += f'design.set_property("{name}","INDELAY","{block["in_delay"]}")\n'
if "in_clk_inv" in block:
cmd += f'design.set_property("{name}","IS_INCLK_INVERTED","{block["in_clk_inv"]}")\n'
if prop:
for p, val in prop:
cmd += 'design.set_property("{}","{}","{}")\n'.format(name, p, val)
cmd += "\n"
return cmd
if mode == "OUTPUT":
if len(block["location"]) == 1:
cmd += 'design.create_output_gpio("{}")\n'.format(name)
cmd += 'design.assign_pkg_pin("{}","{}")\n'.format(name, block["location"][0])
else:
cmd += 'design.create_input_gpio("{}",{},0)\n'.format(name, block["size"]-1)
cmd += 'design.create_output_gpio("{}",{},0)\n'.format(name, block["size"]-1)
for i, pad in enumerate(block["location"]):
cmd += 'design.assign_pkg_pin("{}[{}]","{}")\n'.format(name, i, pad)
if mode == "OUTPUT" or mode == "INOUT":
if "out_reg" in block:
cmd += 'design.set_property("{}","OUT_REG","{}")\n'.format(name, block["out_reg"])
cmd += 'design.set_property("{}","OUT_CLK_PIN","{}")\n'.format(name, block["out_clk_pin"])
@ -253,7 +222,14 @@ design.create("{2}", "{3}", "./../gateware", overwrite=True)
cmd += 'design.set_property("{}","DRIVE_STRENGTH","{}")\n'.format(name, block["drive_strength"])
if "slewrate" in block:
cmd += 'design.set_property("{}","SLEWRATE","{}")\n'.format(name, block["slewrate"])
if "const_output" in block:
if not isinstance(block["const_output"], list):
cmd += f'design.set_property("{name}","CONST_OUTPUT","{block["const_output"]}")\n'
else:
for i, val in enumerate(block["const_output"]):
cmd += f'design.set_property("{name}[{i}]","CONST_OUTPUT","{val}")\n'
if mode == "INOUT" or mode == "INPUT" or mode == "OUTPUT":
if prop:
for p, val in prop:
cmd += 'design.set_property("{}","{}","{}")\n'.format(name, p, val)

View File

@ -120,13 +120,13 @@ class InferedSDRTristate(Module):
class SDRTristate(Special):
def __init__(self, io, o, oe, i, clk=None):
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()
assert len(self.i) == len(self.o) == len(self.oe)
def iter_expressions(self):
yield self, "io" , SPECIAL_INOUT