def checkargs(self, line, template): """ check line with template """ argline = line.split(" ") argtemplate = template.split(" ") try: argline.remove('') except ValueError: pass if len(argline) < self.minArgNumber(template, ' ') or \ len(argline) > self.maxArgNumber(template, ' '): raise PodError( "Wrong argument number:\n%s\n instead of\n %s" % (line, template), 0) for argl, argt in zip(argline, argtemplate): if re.match(r"^\.\.", argl): subargline = argl[2:].split(".") subargline[0] = ".." + subargline[0] elif re.match(r"^\.", argl): subargline = argl[1:].split(".") subargline[0] = "." + subargline[0] else: subargline = argl.split(".") if (len(subargline) < self.minArgNumber(argt, '.')) or\ (len(subargline) > self.maxArgNumber(argt, '.')): raise PodError( "Wrong subargument:\n%s\ninstead of\n%s" % (argl, argt), 0)
def auto_connect_busses(self): """ autoconnect busses """ masters = self.interfaces_master # autoconnection can be made only if they are 1 master interface if len(masters) < 1: raise PodError("No bus master in project", 0) elif len(masters) > 1: for i in range(len(masters) - 1): for j in range(i + 1, len(masters)): if (masters[i].bus_name == masters[j].bus_name): raise PodError( masters[i].parent.instancename + " and " + masters[j].parent.instancename + " has the same bus type : , " + masters[i].bus_name + " bus connection " + "must be made by hand", 0) # find slaves bus slaves = self.interfaces_slave if len(slaves) == 0: raise PodError(" No slave bus in project", 0) # connect each slave with the same bus name than master for master in masters: for interfaceslave in slaves: if interfaceslave.bus_name == master.bus_name: try: # connect bus master.connect_bus(interfaceslave.parent, interfaceslave.name) except PodError as error: error.level = 2 DISPLAY.msg(str(error)) DISPLAY.msg("Bus connected") self.save()
def do_generateproject(self, line): """\ Usage : generateproject <simulationtoolchain> Make projects files for simulation (makefile and testbench sources) """ if line.strip() != "": try: self.do_selecttoolchain(line) except PodError as error: print(str(error)) return elif self._project.simulation is None: print(PodError("Simulation toolchain must be selected before")) return if self._project.simulation_toolchain is None: print(PodError("Choose a toolchain before", 0)) for toolchain in \ self._project.get_simulation_toolchains(): print(str(toolchain.name)) return try: filename = self._project.simulation.generate_template() filename = self._project.simulation.generate_makefile() except PodError as error: print(str(error)) return print(str(DISPLAY)) print("Testbench with name : " + filename + " Done") print("Makefile generated with name : " + filename + " Done")
def add_subnode(self, **keys): """ Add a subnode in the object tree add_subnode(self,nodename,subnode) add_subnode(self,nodename,subnodename,attributename,value) add_subnode(self,nodename,subnodename,attributedict) """ if "nodename" in keys: node = self.get_node(nodename=keys["nodename"]) if node is None: node = self.add_node(nodename=keys["nodename"]) if "subnode" in keys: return node.add_node(node=keys["subnode"]) elif "subnodename" in keys: subnodename = keys["subnodename"] if "attributename" in keys: return node.add_node(nodename=subnodename, attributename=keys["attributename"], value=keys["value"]) elif "attributedict" in keys: return node.add_node(nodename=subnodename, attributedict=keys["attributedict"]) else: raise PodError("Key not known in addSubNode " + str(keys)) else: raise PodError("Key not known in addSubNode" + str(keys)) else: raise PodError("Key not known in addSubNode" + str(keys))
def fill_all_templates(self): """ fill template """ project = self.project op_sys = self.name if op_sys is None: raise PodError("Operating system must be selected", 0) for component in project.instances: if component.num == "0": driver_template = component.get_driver_template(op_sys) if driver_template is not None: DISPLAY.msg("Copy and fill template for " + component.name) for templatefile in driver_template.template_names: try: template = open( self.project.projectpath + COMPONENTSPATH + "/" + component.instancename + "/" + DRIVERS_TEMPLATES_PATH + "/" + op_sys + "/" + templatefile, "r") destfile = open( self.project.projectpath + DRIVERSPATH + "/" + component.name + "/" + templatefile, "w") except IOError as error: raise PodError(str(error), 0) self.fill_template(template, destfile, component) template.close() destfile.close()
def master(self, masterinterface): """ set master interface """ if self.interface_class != "slave": raise PodError("interface " + self.name + " must be slave", 0) elif masterinterface.interface_class != "master": raise PodError("interface " + masterinterface.interface_class + " must be master", 0) self.interfacemaster = masterinterface
def master(self): """ Get the master bus if exist """ if self.interface_class != "slave": raise PodError("Only slave interface could have a master", 0) if self.interfacemaster is None: raise PodError("Interface " + self.name + " is not connected on a master", 0) return self.interfacemaster
def load_new_instance(self, libraryname, componentname, componentversion, instancename): """ Load a new component from library """ project = self.parent # verify component name if project.name == instancename: raise PodError( "Instance name can't be " + "the same name as projectname", 0) # test if component exist if not sy.file_exist( project.library.library_path(libraryname) + "/" + componentname): raise PodError( "No component with name " + libraryname + "." + componentname, 0) # test if several componentversion if componentversion is None: if len(project.get_components_versions(libraryname, componentname)) > 1: raise PodError( "Component version must be chosen :" + str( project.get_components_versions( libraryname, componentname)), 0) else: try: componentversion = project.get_components_versions( libraryname, componentname)[0] except IndexError: raise PodError("No xml description of component", 0) if instancename is None: instancename =\ componentname + "%02d" %\ len(project.get_instances_list_of_component(componentname)) # copy and rename directory sy.cp_dir( project.library.library_path(libraryname) + "/" + componentname, self.parent.projectpath + COMPONENTSPATH) try: sy.rename_dir( self.parent.projectpath + COMPONENTSPATH + "/" + componentname, self.parent.projectpath + COMPONENTSPATH + "/" + instancename) except PodError: # if directory exist pass # Rename xml file sy.rename_file( self.parent.projectpath + COMPONENTSPATH + "/" + instancename + "/" + componentversion + XMLEXT, self.parent.projectpath + COMPONENTSPATH + "/" + instancename + "/" + instancename + XMLEXT) # load component self.load(instancename) # Connect platform connection self.autoconnect_pins()
def base_addr(self): """ get base address register value """ try: base = self.get_attr_value("base", "registers") if base is None: raise PodError("Base address register not set", 0) return int(base, 16) except AttributeError: raise PodError("Base address register not set", 0)
def get_attr_names(self, subnodename=None): """ get attribute name list """ if subnodename is None: return self.tree.keys() else: node = self.tree.find(subnodename) if node is None: raise PodError("No tag named " + str(subnodename)) return node.keys() raise PodError("get_attr_names error")
def unconnected_value(self, value): """ Set unconnected value """ if self.direction != "in": raise PodError("Unconnected Value can be set only on 'in' port") if str(value).isdigit(): if int(value) in [0, 1]: self.set_attr("unconnected_value", str(value)) else: raise PodError("Wrong value : " + str(value)) else: raise PodError("Wrong value : " + str(value), 0)
def get_attr_value(self, key, subnodename=None): """ Get attribute value of node """ if subnodename is None: return self.tree.get(key) else: node = self.tree.find(subnodename) if node is None: raise PodError("No tag named " + str(subnodename)) return node.get(key) raise PodError("No attribute named " + key + " for tag " + str(subnodename))
def connect_port(self, port_dest): """ Connect all pins of a port on all pin on same size port dest """ size = self.size if size != port_dest.size: raise PodError("The two ports have differents size") if self.pins != [] and self.direction == "in": raise PodError("Port connection " + self.name + " is not void") if port_dest.pins != []: raise PodError("Port connection " + port_dest.name + " is not void") self.connect_all_pins(port_dest)
def force(self, force): """ Setting force platform io for this port """ listofpins = self.pins if len(listofpins) > 1: raise PodError("Force multiple pin port is not implemented") if len(listofpins) == 1: raise PodError("This pin is already connected") forcevalues = ["gnd", "vcc", "undef"] if force in forcevalues: self.set_attr("force", force) else: raise PodError("force value must be in " + str(forcevalues))
def check_lib(self, path): """ check if lib and component are not duplicated """ libname = path.split("/")[-1] # check if lib name exist if libname in self.libraries: raise PodError("Library " + libname + " already exist", 0) # check if components under library are new componentlist = sy.list_dir(path) for component in componentlist: for libraryname in self.libraries: if component in self.list_components(libraryname): raise PodError( "Library " + libname + " contain a component that exist in '" + libraryname + "' : " + component, 0)
def set_force(self, portname, state): """ May the force be with you """ platform = self.platform interfaces_list = platform.interfaces if len(interfaces_list) != 1: raise PodError("I found " + str(len(interfaces_list)) + " FPGAs (" + str(interfaces_list) + ") and multiple FPGA project " + "is not implemented yet.") port = interfaces_list[0].get_port(portname) if port.direction == "in": raise PodError("The value of this port can't be set " + "because of it's direction (in)") port.force = state self.save()
def connect_pin(self, pin_dest): """ Make connection between two pin """ message = "trying to connect " +\ self.parent.parent.parent.name + "." +\ self.parent.parent.name + "." +\ self.parent.name + "." +\ self.num + " -> " +\ pin_dest.parent.parent.parent.name + "." +\ pin_dest.parent.parent.name + "." +\ pin_dest.parent.name + "." +\ pin_dest.num if self.parent.force_defined(): raise PodError(message + " : Port " + str(self.parent.name) + " is forced, can't be connected") if pin_dest.parent.force_defined(): raise PodError(message + " : Port " + str(pin_dest.parent.name) + " is forced, can't be connected") if self.parent.direction == "in": if len(self.connections) != 0: try: pin_dest.del_connection(self) self.del_connection(pin_dest) except PodError: pass if len(self.connections) != 0: raise PodError(message + " : Can't connect more than " + "one pin on 'in' pin") interface_dest = pin_dest.parent.parent instance_dest = interface_dest.parent interface_source = self.parent.parent instance_source = interface_source.parent if not self.is_connection_exists(pin_dest): self.add_connection_raw(instance_dest.instancename, interface_dest.name, pin_dest.parent.name, pin_dest.num) if not pin_dest.is_connection_exists(self): pin_dest.add_connection_raw(instance_source.instancename, interface_source.name, self.parent.name, self.num)
def scope(self, scope): """ setting scope """ lscope = ["both", "fpga", "driver"] if scope.lower() in lscope: self.set_attr("scope", scope) else: raise PodError("Unknown scope " + str(scope))
def instance_port_part(self, indent, component): """ Declare instance signals ports """ out = "" for interface in component.interfaces: out += indent + self.insert_comment(interface.name) for port in interface.ports: if port.is_hidden: continue destname = "" if len(port.pins) != 0: if (port.direction == "inout") or\ (port.direction == "in"): try: destname = sorted([ aport.extended_name for aport in port.ports_with_same_connection ])[0] except IndexError: raise PodError( "{} port {} has no connection".format( port.direction, port.name)) else: destname = port.extended_name out += indent + \ self.instance_add_port(port.name, destname) else: out += 3 * ONETAB + self.instance_add_unc_port(port) # Suppress the #!@ last comma out = out[:-2] + "\n" return out
def __init__(self, parent): self.parent = parent filepath = self.parent.projectpath + "/" +\ SIMULATIONPATH + "/simulation" + XMLEXT if not sy.file_exist(filepath): raise PodError("No simulation project found", 3) WrapperXml.__init__(self, file=filepath)
def ports(self): """ return list of ports in component display_port = list of: {"interfacename":[portname1,portname2]} """ display_port = {} tophdlfile = self.get_hdl_top() notassignedports = [port.name for port in tophdlfile.ports] interfacelist = self.interfaces for interface in interfacelist: key = interface.name display_port[key] = [] port_name_list = [port.name for port in interface.ports] for port_name in port_name_list: try: notassignedports.remove(port_name) except ValueError: raise PodError("HDL top file and XML component " + "description are not consistant. Port " + port_name + " in component" + " description is not present in HDL file ") display_port[key].append(port_name) if len(notassignedports) != 0: display_port["Not_assigned_Ports"] = notassignedports return display_port
def get_interface(self, interfacename): """ Get an interface by name """ for interface in self._interfaceslist: if interface.name == interfacename: return interface raise PodError("Interface " + str(interfacename) + " does not exists", 0)
def add_slave_interface(self, interface): """ adding slave interface """ if interface.interface_class != "slave": raise PodError(interface.name + " is not a slave", 0) # add slave interface to list self.listinterfaceslave.append(interface) # set base address size = interface.mem_size if size > 0: try: base = interface.base_addr except PodError: base = int(self.lastaddress / size) if (self.lastaddress % size) != 0: base = base + 1 interface.base_addr = base * size DISPLAY.msg("setting base address " + hex(base * size) + " for " + interface.parent.instancename + "." + interface.name) else: DISPLAY.msg("Base address is " + hex(base) + " for " + interface.parent.instancename + "." + interface.name) self.lastaddress = size * (base + 1) else: DISPLAY.msg("No addressing value in this type of bus")
def generatelibraryconstraints(self): """ Adds constraints specified by a component, such as placement for a PLL, multiplier, etc. or clock informations about PLL output signals """ out = "# components constraints \n" for instance in self.project.instances: for constraint in instance.constraints: instance_name = instance.instancename attr_val = str(constraint.get_attr_value("name")) if constraint.get_attr_value("type") == "clk": out += "NET \"" + instance_name + "/" + attr_val + \ "\" TNM_NET = " + instance_name + "/" +\ attr_val + ";\n" out += "TIMESPEC TS_" + instance_name + "_" + \ attr_val.replace('/', '_') + " = PERIOD \"" + \ instance_name + "/" + attr_val + "\"" out += " %g" %\ (1000 / float(constraint.get_attr_value("frequency"))) + \ " ns HIGH 50%;\n" elif constraint.get_attr_value("type") == "placement": out += "INST \"" + instance_name + "/" +\ attr_val + "\" LOC=" +\ constraint.get_attr_value("loc") + ";\n" else: raise PodError( "component " + instance.name + " has an unknown type " + constraint.get_attr_value("type"), 0) return out
def __init__(self, **args): """ init function, __init__(self,node) # parameter is wrapperXml node __init__(self,etnode) # parameter is ElementTree node __init__(self,nodename) __init__(self,nodestring) __init__(self,file) """ if not hasattr(self, 'parent'): self.parent = None if not hasattr(self, 'tree'): self.tree = None if not hasattr(self, 'void'): self.void = True if "node" in args: self.__initnode(args["node"]) elif "etnode" in args: self.__initetnode(args["etnode"]) elif "nodename" in args: self.__initnodename(args["nodename"]) elif "nodestring" in args: self.__initnodestring(args["nodestring"]) elif "file" in args: self.__initfile(args["file"]) else: raise PodError("Keys unknown in WrapperXml", 0)
def del_library(self, libraryname): """ delete library path from config file """ if libraryname in self.official_libraries(): raise PodError("Can't delete an official library") libpath = self.get_pers_lib_path(libraryname) SETTINGS.configfile.del_library(libpath)
def add_node(self, **keys): """ Add a node in the tree, add_node(self,node) add_node(self,nodename) add_node(self,nodename,attributename,value) add_node(self,nodename,attributedict) """ if "node" in keys: node = keys["node"] elif "nodename" in keys: node = WrapperXml(nodename=keys["nodename"]) if "attributename" in keys: node.set_attr(keys["attributename"], keys["value"]) elif "attributedict" in keys: attributedict = keys["attributedict"] for key in attributedict: node.set_attr(key, attributedict[key]) else: raise PodError("Keys not known in addNode", 0) try: self.tree.append(node.tree) except AttributeError: # if tree doesn't exits self.tree = node.tree return node
def set_bsp_directory(self, directory): """ set the directory where drivers files must be copied """ lastdir = directory.split("/")[-1] if lastdir != "POD": raise PodError( "The directory must be named POD and not " + lastdir, 0) if sy.dir_exist(directory): if self.get_node(nodename="bsp") is not None: self.get_node(nodename="bsp").set_attr("directory", directory) else: self.add_node(nodename="bsp", attributename="directory", value=directory) self.bspdir = directory else: raise PodError("Directory " + directory + " does not exist", 0)
def generate_project(self): """ copy all hdl file in synthesis project directory """ for component in self.parent.instances: if component.num == "0": # Make directory compdir = self.parent.projectpath +\ SYNTHESISPATH + "/" +\ component.name if sy.dir_exist(compdir): DISPLAY.msg("Directory " + compdir + " exist, will be deleted") sy.rm_dir(compdir) sy.mkdir(compdir) DISPLAY.msg("Make directory for " + component.name) # copy hdl files for hdlfile in component.hdl_files: try: sy.cp_file( self.parent.projectpath + COMPONENTSPATH + "/" + component.instancename + "/hdl/" + hdlfile.filename, compdir + "/") except IOError as error: print(DISPLAY) raise PodError(str(error), 0)
def data_size(self): """ Get size of data""" size = self.get_attr_value("datasize") if size is None: raise PodError("No datasize attribute in bus " + self.name, 0) else: return size