diff --git a/litex/build/efinix/ifacewriter.py b/litex/build/efinix/ifacewriter.py index b969c4374..f2e5f7321 100644 --- a/litex/build/efinix/ifacewriter.py +++ b/litex/build/efinix/ifacewriter.py @@ -26,7 +26,7 @@ class InterfaceWriter: self.efinity_path = efinity_path self.blocks = [] self.xml_blocks = [] - self.filename = '' + self.filename = "" self.platform = None def set_build_params(self, platform, build_name): @@ -34,15 +34,15 @@ class InterfaceWriter: self.platform = platform def generate_xml_blocks(self): - et.register_namespace('efxpt', "http://www.efinixinc.com/peri_design_db") - tree = et.parse(self.filename + '.peri.xml') + et.register_namespace("efxpt", "http://www.efinixinc.com/peri_design_db") + tree = et.parse(self.filename + ".peri.xml") root = tree.getroot() for block in self.xml_blocks: - if block['type'] == 'LVDS': + if block["type"] == "LVDS": 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) print_string = reparsed.toprettyxml(indent=" ") @@ -51,45 +51,6 @@ class InterfaceWriter: 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): header = "# Autogenerated by LiteX / git: " + tools.get_litex_git_revision() header += """ @@ -97,15 +58,15 @@ import os import sys import pprint -home = '{0}' +home = "{0}" -os.environ['EFXPT_HOME'] = home + '/pt' -os.environ['EFXPGM_HOME'] = home + '/pgm' -os.environ['EFXDBG_HOME'] = home + '/debugger' -os.environ['EFXIPM_HOME'] = home + '/ipm' +os.environ["EFXPT_HOME"] = home + "/pt" +os.environ["EFXPGM_HOME"] = home + "/pgm" +os.environ["EFXDBG_HOME"] = home + "/debugger" +os.environ["EFXIPM_HOME"] = home + "/ipm" -sys.path.append(home + '/pt/bin') -sys.path.append(home + '/lib/python3.8/site-packages') +sys.path.append(home + "/pt/bin") +sys.path.append(home + "/lib/python3.8/site-packages") from api_service.design import DesignAPI from api_service.device import DeviceAPI @@ -115,105 +76,105 @@ is_verbose = {1} design = DesignAPI(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): for b in self.blocks: - if b['name'] == name: + if b["name"] == name: return b return None def generate_gpio(self, block, verbose=True): - name = block['name'] - mode = block['mode'] - cmd = '' + name = block["name"] + mode = block["mode"] + cmd = "" - if mode == 'INOUT': - if len(block['location']) == 1: - cmd += 'design.create_inout_gpio("{}")\n'.format(name) - cmd += 'design.assign_pkg_pin("{}","{}")\n'.format(name, block['location'][0]) + if mode == "INOUT": + if len(block["location"]) == 1: + cmd += f'design.create_inout_gpio("{name}")\n' + cmd += f'design.assign_pkg_pin("{name}","{block["location"][0]}")\n' else: - cmd += 'design.create_inout_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) - cmd += '\n' + cmd += f'design.create_inout_gpio("{name}",{block["size"]-1},0)\n' + for i, pad in enumerate(block["location"]): + cmd += f'design.assign_pkg_pin("{name}[{i}]","{pad}")\n' + cmd += "\n" return cmd - if mode == 'INPUT': - if len(block['location']) == 1: - cmd += 'design.create_input_gpio("{}")\n'.format(name) - cmd += 'design.assign_pkg_pin("{}","{}")\n'.format(name, block['location'][0]) + if mode == "INPUT": + if len(block["location"]) == 1: + cmd += f'design.create_input_gpio("{name}")\n' + cmd += f'design.assign_pkg_pin("{name}","{block["location"][0]}")\n' else: - cmd += 'design.create_input_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 'in_reg' in block: - cmd += 'design.set_property("{}","IN_REG","{}")\n'.format(name, block['in_reg']) - cmd += 'design.set_property("{}","IN_CLK_PIN","{}")\n'.format(name, block['in_clk_pin']) + 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 "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' return cmd - if mode == 'OUTPUT': - if len(block['location']) == 1: + 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]) + cmd += 'design.assign_pkg_pin("{}","{}")\n'.format(name, block["location"][0]) else: - cmd += 'design.create_input_gpio("{}",{},0)\n'.format(name, block['size']-1) - for i, pad in enumerate(block['location']): + cmd += 'design.create_input_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 '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']) + 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"]) - if 'drive_strength' in block: - cmd += 'design.set_property("{}","DRIVE_STRENGTH","4")\n'.format(name, block['drive_strength']) + if "drive_strength" in block: + cmd += 'design.set_property("{}","DRIVE_STRENGTH","4")\n'.format(name, block["drive_strength"]) - cmd += '\n' + cmd += "\n" return cmd - if mode == 'INPUT_CLK': + if mode == "INPUT_CLK": cmd += 'design.create_input_clock_gpio("{}")\n'.format(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 - if mode == 'OUTPUT_CLK': + if mode == "OUTPUT_CLK": cmd += 'design.create_clockout_gpio("{}")\n'.format(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 - cmd = '# TODO: ' + str(block) +'\n' + cmd = "# TODO: " + str(block) +"\n" return cmd def generate_pll(self, block, partnumber, verbose=True): - name = block['name'] - cmd = '# ---------- PLL {} ---------\n'.format(name) + name = block["name"] + cmd = "# ---------- 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) - if block['input_clock'] == 'EXTERNAL': + if block["input_clock"] == "EXTERNAL": # PLL V1 has a different configuration if partnumber[0:2] in ["T4", "T8"]: 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: 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: - 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.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("{}","LOCKED_PIN","{}", block_type="PLL")\n'.format(name, block['locked']) - if block['rstn'] != '': - cmd += 'design.set_property("{}","RSTN_PIN","{}", block_type="PLL")\n\n'.format(name, block['rstn']) + cmd += 'design.set_property("{}","LOCKED_PIN","{}", block_type="PLL")\n'.format(name, block["locked"]) + if block["rstn"] != "": + cmd += 'design.set_property("{}","RSTN_PIN","{}", block_type="PLL")\n\n'.format(name, block["rstn"]) # 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: cmd += 'pll_config = {{ "CLKOUT{}_EN":"1", "CLKOUT{}_PIN":"{}" }}\n'.format(i, i, clock[0]) 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) - 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 += 'target_freq = {\n' - for i, clock in enumerate(block['clk_out']): + cmd += "target_freq = {\n" + for i, clock in enumerate(block["clk_out"]): 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) - if 'extra' in block: - cmd += block['extra'] - cmd += '\n' + if "extra" in block: + cmd += block["extra"] + cmd += "\n" if verbose: 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 += 'pprint.pprint(prop_map)\n' - cmd += '# ---------- END PLL {} ---------\n\n'.format(name) + cmd += "# ---------- END PLL {} ---------\n\n".format(name) return cmd def generate(self, partnumber): - output = '' + output = "" for b in self.blocks: - if b['type'] == 'PLL': + if b["type"] == "PLL": output += self.generate_pll(b, partnumber) - if b['type'] == 'GPIO': + if b["type"] == "GPIO": output += self.generate_gpio(b) return output @@ -264,3 +225,42 @@ design.generate(enable_bitstream=True) # Save the configured periphery design 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" + )