build/efinix/ifacewriter: Cosmetic cleanup (Replace " with ' when possible) and move add_ddr_lvds to the end.
This commit is contained in:
parent
02c0ed2de7
commit
aec8276cdb
|
@ -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"
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue