def build_timing_constraints(self, vns): sdc = [] # Clock constraints for clk, period in sorted(self.clocks.items(), key=lambda x: x[0].duid): is_port = False for sig, pins, others, resname in self.named_sc: if sig == self._vns.get_name(clk): is_port = True if is_port: tpl = "create_clock -name {clk} -period {period} [get_ports {{{clk}}}]" sdc.append( tpl.format(clk=self._vns.get_name(clk), period=str(period))) else: tpl = "create_clock -name {clk} -period {period} [get_nets {{{clk}}}]" sdc.append( tpl.format(clk=self._vns.get_name(clk), period=str(period))) # False path constraints for from_, to in sorted(self.false_paths, key=lambda x: (x[0].duid, x[1].duid)): tpl = "set_false_path -from [get_clocks {{{from_}}}] -to [get_clocks {{{to}}}]" sdc.append( tpl.format(from_=self._vns.get_name(from_), to=self._vns.get_name(to))) # Add additional commands sdc += self.additional_sdc_commands # Generate .sdc tools.write_to_file("{}.sdc".format(self._build_name), "\n".join(sdc)) return (self._build_name + ".sdc", "SDC")
def build_io_constraints(self): pythonpath = "" header = self.ifacewriter.header(self._build_name, self.platform.device) gen = self.ifacewriter.generate(self.platform.device) #TODO : move this to ifacewriter gpio = self._build_iface_gpio() add = "\n".join(self.additional_iface_commands) footer = self.ifacewriter.footer() tools.write_to_file("iface.py", header + gen + gpio + add + footer) if tools.subprocess_call_filtered( [self.efinity_path + "/bin/python3", "iface.py"], common.colors) != 0: raise OSError( "Error occurred during Efinity peri script execution.") # Some IO blocks don't have Python API so we need to configure them # directly in the peri.xml file # We also need to configure the bank voltage here if self.ifacewriter.xml_blocks or self.platform.iobank_info: self.ifacewriter.generate_xml_blocks() # Because the Python API is sometimes bugged, we need to tweak the generated xml if self.ifacewriter.fix_xml: self.ifacewriter.fix_xml_values()
def build_project(self): now = datetime.datetime.now() # Create Project. root = et.Element("efx:project") root.attrib["xmlns:efx"] = "http://www.efinixinc.com/enf_proj" root.attrib["name"] = self._build_name root.attrib["location"] = str(pathlib.Path().resolve()) root.attrib[ "sw_version"] = "2021.1.165.2.19" # TODO: read it from sw_version.txt root.attrib[ "last_change_date"] = f"Date : {now.strftime('%Y-%m-%d %H:%M')}" # Add Device. device_info = et.SubElement(root, "efx:device_info") et.SubElement(device_info, "efx:family", name=self.platform.family) et.SubElement(device_info, "efx:device", name=self.platform.device) et.SubElement(device_info, "efx:timing_model", name=self.platform.timing_model) # Add Design Info. design_info = et.SubElement(root, "efx:design_info") et.SubElement(design_info, "efx:top_module", name=self._build_name) # Add Design Sources. for filename, language, library, *copy in self.platform.sources: if language is None: continue et.SubElement( design_info, "efx:design_file", { "name": filename, "version": "default", "library": "default" if ".vh" not in filename else library, }) # Add Timing Constraints. constraint_info = et.SubElement(root, "efx:constraint_info") et.SubElement(constraint_info, "efx:sdc_file", name=f"{self._build_name}.sdc") # Add Misc Info. misc_info = et.SubElement(root, "efx:misc_info") # Add IP Info. ip_info = et.SubElement(root, "efx:ip_info") # Generate .xml xml_str = et.tostring(root, "utf-8") xml_str = expatbuilder.parseString(xml_str, False) xml_str = xml_str.toprettyxml(indent=" ") tools.write_to_file("{}.xml".format(self._build_name), xml_str)
def _build_peri(efinity_path, build_name, partnumber, named_sc, named_pc, fragment, platform, additional_iface_commands, excluded_ios): pythonpath = "" header = platform.toolchain.ifacewriter.header(build_name, partnumber) gen = platform.toolchain.ifacewriter.generate(partnumber) #TODO: move this to ifacewriter gpio = _build_iface_gpio(named_sc, named_pc, fragment, platform, excluded_ios) add = '\n'.join(additional_iface_commands) footer = platform.toolchain.ifacewriter.footer() tools.write_to_file("iface.py", header + gen + gpio + add + footer) if subprocess.call([efinity_path + '/bin/python3', 'iface.py']) != 0: raise OSError("Error occurred during Efinity peri script execution.")
def _build_peri(efinity_path, build_name, device, named_sc, named_pc, fragment, platform, additional_iface_commands, excluded_ios): pythonpath = "" header = platform.toolchain.ifacewriter.header(build_name, device) gen = platform.toolchain.ifacewriter.generate(device) #TODO : move this to ifacewriter gpio = _build_iface_gpio(named_sc, named_pc, fragment, platform, excluded_ios) add = "\n".join(additional_iface_commands) footer = platform.toolchain.ifacewriter.footer() tools.write_to_file("iface.py", header + gen + gpio + add + footer) if tools.subprocess_call_filtered( [efinity_path + "/bin/python3", "iface.py"], common.colors) != 0: raise OSError("Error occurred during Efinity peri script execution.")
def _build_xml(partnumber, timing_model, build_name, sources, additional_xml_commands): root = et.Element('efx:project') now = datetime.datetime.now() date_str = " Date: " + now.strftime("%Y-%m-%d %H:%M") + " " # Add the required attributes root.attrib['xmlns:efx'] = 'http://www.efinixinc.com/enf_proj' root.attrib['xmlns:xsi'] = "http://www.w3.org/2001/XMLSchema-instance" root.attrib['name'] = build_name root.attrib['description'] = '' root.attrib['last_change_date'] = date_str root.attrib['location'] = str(pathlib.Path().resolve()) root.attrib['sw_version'] = '2021.1.165.2.19' # TODO: read it from sw_version.txt root.attrib['last_run_state'] = '' root.attrib['last_run_tool'] = '' root.attrib['last_run_flow'] = '' root.attrib['config_result_in_sync'] = 'sync' root.attrib['design_ood'] = 'sync' root.attrib['place_ood'] = 'sync' root.attrib['route_ood'] = 'sync' root.attrib['xsi:schemaLocation'] = 'http://www.efinixinc.com/enf_proj enf_proj.xsd' device_info = et.SubElement(root, 'efx:device_info') et.SubElement(device_info, 'efx:family', name = 'Trion') et.SubElement(device_info, 'efx:device', name = partnumber) et.SubElement(device_info, 'efx:timing_model', name = timing_model) design_info = et.SubElement(root, 'efx:design_info') et.SubElement(design_info, "efx:top_module", name = build_name) for filename, language, library in sources: if '.vh' not in filename: val = {'name':filename, 'version':'default', 'library':'default'} et.SubElement(design_info, "efx:design_file", val) et.SubElement(design_info, "efx:top_vhdl_arch", name = "") constraint_info = et.SubElement(root, "efx:constraint_info") et.SubElement(constraint_info, "efx:sdc_file", name = "{}.sdc".format(build_name)) misc_info = et.SubElement(root, "efx:misc_info") ip_info = et.SubElement(root, "efx:ip_info") synthesis = et.SubElement(root, "efx:synthesis", tool_name="efx_map") for l in additional_xml_commands: if l[0] == 'efx_map': val = {'name':l[1], 'value':l[2], 'value_type':l[3]} et.SubElement(synthesis, "efx:param", val) place_and_route = et.SubElement(root, "efx:place_and_route", tool_name="efx_pnr") for l in additional_xml_commands: if l[0] == 'efx_pnr': val = {'name':l[1], 'value':l[2], 'value_type':l[3]} et.SubElement(place_and_route, "efx:param", val) bitstream_generation = et.SubElement(root, "efx:bitstream_generation", tool_name="efx_pgm") for l in additional_xml_commands: if l[0] == 'efx_pgm': val = {'name':l[1], 'value':l[2], 'value_type':l[3]} et.SubElement(bitstream_generation, "efx:param", val) xml_string = et.tostring(root, 'utf-8') reparsed = expatbuilder.parseString(xml_string, False) print_string = reparsed.toprettyxml(indent=" ") # Generate .xml tools.write_to_file("{}.xml".format(build_name), print_string)