build/efinix/ifacewriter: Cosmetic cleanup (Replace " with ' when possible) and move add_ddr_lvds to the end.

This commit is contained in:
Florent Kermarrec 2021-11-09 14:29:00 +01:00
parent 02c0ed2de7
commit aec8276cdb
1 changed files with 114 additions and 114 deletions

View File

@ -26,7 +26,7 @@ class InterfaceWriter:
self.efinity_path = efinity_path self.efinity_path = efinity_path
self.blocks = [] self.blocks = []
self.xml_blocks = [] self.xml_blocks = []
self.filename = '' self.filename = ""
self.platform = None self.platform = None
def set_build_params(self, platform, build_name): def set_build_params(self, platform, build_name):
@ -34,15 +34,15 @@ class InterfaceWriter:
self.platform = platform self.platform = platform
def generate_xml_blocks(self): def generate_xml_blocks(self):
et.register_namespace('efxpt', "http://www.efinixinc.com/peri_design_db") et.register_namespace("efxpt", "http://www.efinixinc.com/peri_design_db")
tree = et.parse(self.filename + '.peri.xml') tree = et.parse(self.filename + ".peri.xml")
root = tree.getroot() root = tree.getroot()
for block in self.xml_blocks: for block in self.xml_blocks:
if block['type'] == 'LVDS': if block["type"] == "LVDS":
self.add_ddr_lvds(root, block) self.add_ddr_lvds(root, block)
xml_string = et.tostring(root, 'utf-8') xml_string = et.tostring(root, "utf-8")
reparsed = expatbuilder.parseString(xml_string, False) reparsed = expatbuilder.parseString(xml_string, False)
print_string = reparsed.toprettyxml(indent=" ") print_string = reparsed.toprettyxml(indent=" ")
@ -51,45 +51,6 @@ class InterfaceWriter:
tools.write_to_file("{}.peri.xml".format(self.filename), print_string) tools.write_to_file("{}.peri.xml".format(self.filename), print_string)
def add_ddr_lvds(self, root, params):
lvds_info = root.find('efxpt:lvds_info', namespaces)
if params['mode'] == 'OUTPUT':
dir = 'tx'
mode = 'out'
else:
dir = 'rx'
mode = 'in'
pad = self.platform.parser.get_gpio_instance_from_pin(params['location'][0])
pad = pad.replace('TXP', 'TX')
pad = pad.replace('TXN', 'TX')
pad = pad.replace('RXP', 'RX')
pad = pad.replace('RXN', 'RX')
# Sometimes there is an extra identifier at the end
# TODO: do a better parser
if pad.count('_') == 2:
pad = pad.rsplit('_', 1)[0]
lvds = et.SubElement(lvds_info, 'efxpt:lvds',
name = params['name'],
lvds_def = pad,
ops_type = dir
)
et.SubElement(lvds, 'efxpt:ltx_info',
pll_instance = '',
fast_clock_name = '{}'.format(params['fast_clk']),
slow_clock_name = '{}'.format(params['slow_clk']),
reset_name = '',
out_bname = '{}'.format(params['name']),
oe_name = '',
clock_div = '1',
mode = '{}'.format(mode),
serialization = '{}'.format(params['serialisation']),
reduced_swing = 'false',
load = '3'
)
def header(self, build_name, partnumber): def header(self, build_name, partnumber):
header = "# Autogenerated by LiteX / git: " + tools.get_litex_git_revision() header = "# Autogenerated by LiteX / git: " + tools.get_litex_git_revision()
header += """ header += """
@ -97,15 +58,15 @@ import os
import sys import sys
import pprint import pprint
home = '{0}' home = "{0}"
os.environ['EFXPT_HOME'] = home + '/pt' os.environ["EFXPT_HOME"] = home + "/pt"
os.environ['EFXPGM_HOME'] = home + '/pgm' os.environ["EFXPGM_HOME"] = home + "/pgm"
os.environ['EFXDBG_HOME'] = home + '/debugger' os.environ["EFXDBG_HOME"] = home + "/debugger"
os.environ['EFXIPM_HOME'] = home + '/ipm' os.environ["EFXIPM_HOME"] = home + "/ipm"
sys.path.append(home + '/pt/bin') sys.path.append(home + "/pt/bin")
sys.path.append(home + '/lib/python3.8/site-packages') sys.path.append(home + "/lib/python3.8/site-packages")
from api_service.design import DesignAPI from api_service.design import DesignAPI
from api_service.device import DeviceAPI from api_service.device import DeviceAPI
@ -115,105 +76,105 @@ is_verbose = {1}
design = DesignAPI(is_verbose) design = DesignAPI(is_verbose)
device = DeviceAPI(is_verbose) device = DeviceAPI(is_verbose)
design.create('{2}', '{3}', './../gateware', overwrite=True) design.create("{2}", "{3}", "./../gateware", overwrite=True)
""" """
return header.format(self.efinity_path, 'True', build_name, partnumber) return header.format(self.efinity_path, "True", build_name, partnumber)
def get_block(self, name): def get_block(self, name):
for b in self.blocks: for b in self.blocks:
if b['name'] == name: if b["name"] == name:
return b return b
return None return None
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"]
cmd = '' cmd = ""
if mode == 'INOUT': if mode == "INOUT":
if len(block['location']) == 1: if len(block["location"]) == 1:
cmd += 'design.create_inout_gpio("{}")\n'.format(name) cmd += f'design.create_inout_gpio("{name}")\n'
cmd += 'design.assign_pkg_pin("{}","{}")\n'.format(name, block['location'][0]) cmd += f'design.assign_pkg_pin("{name}","{block["location"][0]}")\n'
else: else:
cmd += 'design.create_inout_gpio("{}",{},0)\n'.format(name, block['size']-1) 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 += 'design.assign_pkg_pin("{}[{}]","{}")\n'.format(name, i, pad) cmd += f'design.assign_pkg_pin("{name}[{i}]","{pad}")\n'
cmd += '\n' cmd += "\n"
return cmd return cmd
if mode == 'INPUT': if mode == "INPUT":
if len(block['location']) == 1: if len(block["location"]) == 1:
cmd += 'design.create_input_gpio("{}")\n'.format(name) cmd += f'design.create_input_gpio("{name}")\n'
cmd += 'design.assign_pkg_pin("{}","{}")\n'.format(name, block['location'][0]) cmd += f'design.assign_pkg_pin("{name}","{block["location"][0]}")\n'
else: else:
cmd += 'design.create_input_gpio("{}",{},0)\n'.format(name, block['size']-1) cmd += f'design.create_input_gpio("{name}",{block["size"]-1},0)\n'
for i, pad in enumerate(block['location']): for i, pad in enumerate(block["location"]):
cmd += 'design.assign_pkg_pin("{}[{}]","{}")\n'.format(name, i, pad) cmd += f'design.assign_pkg_pin("{name}[{i}]","{pad}")\n'
if 'in_reg' in block: if "in_reg" in block:
cmd += 'design.set_property("{}","IN_REG","{}")\n'.format(name, block['in_reg']) cmd += f'design.set_property("{name}","IN_REG","{block["in_reg"]}")\n'
cmd += 'design.set_property("{}","IN_CLK_PIN","{}")\n'.format(name, block['in_clk_pin']) cmd += f'design.set_property("{name}","IN_CLK_PIN","{block["in_clk_pin"]}")\n'
return cmd return cmd
if mode == 'OUTPUT': if mode == "OUTPUT":
if len(block['location']) == 1: if len(block["location"]) == 1:
cmd += 'design.create_output_gpio("{}")\n'.format(name) cmd += 'design.create_output_gpio("{}")\n'.format(name)
cmd += 'design.assign_pkg_pin("{}","{}")\n'.format(name, block['location'][0]) cmd += 'design.assign_pkg_pin("{}","{}")\n'.format(name, block["location"][0])
else: else:
cmd += 'design.create_input_gpio("{}",{},0)\n'.format(name, block['size']-1) cmd += 'design.create_input_gpio("{}",{},0)\n'.format(name, block["size"]-1)
for i, pad in enumerate(block['location']): for i, pad in enumerate(block["location"]):
cmd += 'design.assign_pkg_pin("{}[{}]","{}")\n'.format(name, i, pad) cmd += 'design.assign_pkg_pin("{}[{}]","{}")\n'.format(name, i, pad)
if 'out_reg' in block: if "out_reg" in block:
cmd += 'design.set_property("{}","OUT_REG","{}")\n'.format(name, block['out_reg']) 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']) cmd += 'design.set_property("{}","OUT_CLK_PIN","{}")\n'.format(name, block["out_clk_pin"])
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"])
cmd += '\n' cmd += "\n"
return cmd return cmd
if mode == 'INPUT_CLK': if mode == "INPUT_CLK":
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"])
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"])
return cmd return cmd
cmd = '# TODO: ' + str(block) +'\n' cmd = "# TODO: " + str(block) +"\n"
return cmd return cmd
def generate_pll(self, block, partnumber, verbose=True): def generate_pll(self, block, partnumber, verbose=True):
name = block['name'] name = block["name"]
cmd = '# ---------- PLL {} ---------\n'.format(name) cmd = "# ---------- PLL {} ---------\n".format(name)
cmd += 'design.create_block("{}", block_type="PLL")\n'.format(name) cmd += 'design.create_block("{}", block_type="PLL")\n'.format(name)
cmd += 'pll_config = {{ "REFCLK_FREQ":"{}" }}\n'.format(block['input_freq'] / 1e6) cmd += 'pll_config = {{ "REFCLK_FREQ":"{}" }}\n'.format(block["input_freq"] / 1e6)
cmd += 'design.set_property("{}", pll_config, block_type="PLL")\n\n'.format(name) cmd += 'design.set_property("{}", pll_config, block_type="PLL")\n\n'.format(name)
if block['input_clock'] == 'EXTERNAL': if block["input_clock"] == "EXTERNAL":
# PLL V1 has a different configuration # PLL V1 has a different configuration
if partnumber[0:2] in ["T4", "T8"]: if partnumber[0:2] in ["T4", "T8"]:
cmd += 'design.gen_pll_ref_clock("{}", pll_res="{}", refclk_res="{}", refclk_name="{}", ext_refclk_no="{}")\n\n' \ cmd += 'design.gen_pll_ref_clock("{}", pll_res="{}", refclk_res="{}", refclk_name="{}", ext_refclk_no="{}")\n\n' \
.format(name, block['resource'], block['input_clock_pad'], block['input_clock_name'], block['clock_no']) .format(name, block["resource"], block["input_clock_pad"], block["input_clock_name"], block["clock_no"])
else: else:
cmd += 'design.gen_pll_ref_clock("{}", pll_res="{}", refclk_src="{}", refclk_name="{}", ext_refclk_no="{}")\n\n' \ cmd += 'design.gen_pll_ref_clock("{}", pll_res="{}", refclk_src="{}", refclk_name="{}", ext_refclk_no="{}")\n\n' \
.format(name, block['resource'], block['input_clock'], block['input_clock_name'], block['clock_no']) .format(name, block["resource"], block["input_clock"], block["input_clock_name"], block["clock_no"])
else: else:
cmd += 'design.gen_pll_ref_clock("{}", pll_res="{}", refclk_name="{}", refclk_src="CORE")\n'.format(name, block['resource'], block['input_signal']) cmd += 'design.gen_pll_ref_clock("{}", pll_res="{}", refclk_name="{}", refclk_src="CORE")\n'.format(name, block["resource"], block["input_signal"])
cmd += 'design.set_property("{}", "CORE_CLK_PIN", "{}", block_type="PLL")\n\n'.format(name, block['input_signal']) cmd += 'design.set_property("{}", "CORE_CLK_PIN", "{}", block_type="PLL")\n\n'.format(name, block["input_signal"])
cmd += 'design.set_property("{}","LOCKED_PIN","{}", block_type="PLL")\n'.format(name, block['locked']) cmd += 'design.set_property("{}","LOCKED_PIN","{}", block_type="PLL")\n'.format(name, block["locked"])
if block['rstn'] != '': if block["rstn"] != "":
cmd += 'design.set_property("{}","RSTN_PIN","{}", block_type="PLL")\n\n'.format(name, block['rstn']) cmd += 'design.set_property("{}","RSTN_PIN","{}", block_type="PLL")\n\n'.format(name, block["rstn"])
# Output clock 0 is enabled by default # Output clock 0 is enabled by default
for i, clock in enumerate(block['clk_out']): for i, clock in enumerate(block["clk_out"]):
if i > 0: if i > 0:
cmd += 'pll_config = {{ "CLKOUT{}_EN":"1", "CLKOUT{}_PIN":"{}" }}\n'.format(i, i, clock[0]) cmd += 'pll_config = {{ "CLKOUT{}_EN":"1", "CLKOUT{}_PIN":"{}" }}\n'.format(i, i, clock[0])
else: else:
@ -221,18 +182,18 @@ design.create('{2}', '{3}', './../gateware', overwrite=True)
cmd += 'design.set_property("{}", pll_config, block_type="PLL")\n\n'.format(name) cmd += 'design.set_property("{}", pll_config, block_type="PLL")\n\n'.format(name)
for i, clock in enumerate(block['clk_out']): for i, clock in enumerate(block["clk_out"]):
cmd += 'design.set_property("{}","CLKOUT{}_PHASE","{}","PLL")\n'.format(name, i, clock[2]) cmd += 'design.set_property("{}","CLKOUT{}_PHASE","{}","PLL")\n'.format(name, i, clock[2])
cmd += 'target_freq = {\n' cmd += "target_freq = {\n"
for i, clock in enumerate(block['clk_out']): for i, clock in enumerate(block["clk_out"]):
cmd += ' "CLKOUT{}_FREQ": "{}",\n'.format(i, clock[1] / 1e6) cmd += ' "CLKOUT{}_FREQ": "{}",\n'.format(i, clock[1] / 1e6)
cmd += '}\n' cmd += "}\n"
cmd += 'calc_result = design.auto_calc_pll_clock("{}", target_freq)\n'.format(name) cmd += 'calc_result = design.auto_calc_pll_clock("{}", target_freq)\n'.format(name)
if 'extra' in block: if "extra" in block:
cmd += block['extra'] cmd += block["extra"]
cmd += '\n' cmd += "\n"
if verbose: if verbose:
cmd += 'print("#### {} ####")\n'.format(name) cmd += 'print("#### {} ####")\n'.format(name)
@ -244,15 +205,15 @@ design.create('{2}', '{3}', './../gateware', overwrite=True)
cmd += 'prop_map = design.get_property("{}", clock_source_prop, block_type="PLL")\n'.format(name) cmd += 'prop_map = design.get_property("{}", clock_source_prop, block_type="PLL")\n'.format(name)
cmd += 'pprint.pprint(prop_map)\n' cmd += 'pprint.pprint(prop_map)\n'
cmd += '# ---------- END PLL {} ---------\n\n'.format(name) cmd += "# ---------- END PLL {} ---------\n\n".format(name)
return cmd return cmd
def generate(self, partnumber): def generate(self, partnumber):
output = '' output = ""
for b in self.blocks: for b in self.blocks:
if b['type'] == 'PLL': if b["type"] == "PLL":
output += self.generate_pll(b, partnumber) output += self.generate_pll(b, partnumber)
if b['type'] == 'GPIO': if b["type"] == "GPIO":
output += self.generate_gpio(b) output += self.generate_gpio(b)
return output return output
@ -264,3 +225,42 @@ design.generate(enable_bitstream=True)
# Save the configured periphery design # Save the configured periphery design
design.save()""" design.save()"""
def add_ddr_lvds(self, root, params):
lvds_info = root.find("efxpt:lvds_info", namespaces)
if params["mode"] == "OUTPUT":
dir = "tx"
mode = "out"
else:
dir = "rx"
mode = "in"
pad = self.platform.parser.get_gpio_instance_from_pin(params["location"][0])
pad = pad.replace("TXP", "TX")
pad = pad.replace("TXN", "TX")
pad = pad.replace("RXP", "RX")
pad = pad.replace("RXN", "RX")
# Sometimes there is an extra identifier at the end
# TODO: do a better parser
if pad.count("_") == 2:
pad = pad.rsplit("_", 1)[0]
lvds = et.SubElement(lvds_info, "efxpt:lvds",
name = params["name"],
lvds_def = pad,
ops_type = dir
)
et.SubElement(lvds, "efxpt:ltx_info",
pll_instance = "",
fast_clock_name = "{}".format(params["fast_clk"]),
slow_clock_name = "{}".format(params["slow_clk"]),
reset_name = "",
out_bname = "{}".format(params["name"]),
oe_name = "",
clock_div = "1",
mode = "{}".format(mode),
serialization = "{}".format(params["serialisation"]),
reduced_swing = "false",
load = "3"
)