def _parse_subckt(self, line, fp_l): """ Read all lines in subckt""" insts = [] subckt_param_all = {} while not (line.lower().startswith('end') or line.lower().startswith('.end')): if any(c in line.lower() for c in ("//", '*')): line = self.get_next_line(fp_l, 1) pass elif 'param' in line.lower(): subckt_param = self._parse_param(line, fp_l) if subckt_param: if subckt_param_all: subckt_param_all.update(subckt_param) else: subckt_param_all = subckt_param #for param,value in subckt_param.items(): # logging.info('Found subckt param: %s, value:%s', param, value); line = self.get_next_line(fp_l, 1) else: node1 = _parse_inst(line) if node1: insts.append(node1) line = self.get_next_line(fp_l, 1) return insts, subckt_param_all
def _parse_subckt(self, line, fp_l): """ Read all lines in subckt""" insts = [] while not (line.lower().startswith('end') or line.lower().startswith('.end')): if any(c in line.lower() for c in ("//", '*')): line = fp_l.readline() pass node1 = _parse_inst(line) if node1: insts.append(node1) line = fp_l.readline() while line.strip().endswith('\\'): line += fp_l.readline().strip() return insts
def sp_parser(self): """Parse the defined file line wise""" if not os.path.isfile(self.netlist): print("File doesn't exist") else: logging.info("File exist: %s", self.netlist) fp_l = open(self.netlist, "r") line = fp_l.readline() while ".END" not in line: # if "**" in line.lower(): pass comment line while line.strip().endswith('\\'): line += fp_l.readline().strip() if any(c in line.lower() for c in ("//", "**")): #line = fp_l.readline() pass elif not line.strip(): pass elif "global" in line.lower(): self._parse_global(line, fp_l) elif ".temp" in line.lower(): temp_line = line elif ".option" in line.lower(): self._parse_option(line, fp_l) elif "subckt" in line.lower(): self._parse_subckt_info(line, fp_l) elif ".param" in line.lower(): self._parse_param(line, fp_l) elif "include" in line.lower() or "info" in line.lower(): self._parse_include(line, fp_l) line = fp_l.readline() continue else: parsed_inst = _parse_inst(line) if parsed_inst: self.top_insts.append(parsed_inst) line = fp_l.readline() if not line: break print("INFO: PARSING LIBRARY FILE DONE") if self.params: #self.params.remove('+') self.params = filter(lambda a: a != '+', self.params) #logging.info(" ".join(self.params)) elif self.option: self.option = filter(lambda a: a != '+', self.option) #logging.info(" ".join(self.option)) #logging.info("Printing parsed netlist") elif self._global: self._global = filter(lambda a: a != '+', self._global) #print("Printing parsed netlist") for subckt_name, elements in self.subckts.items(): subckt_ports = ' '.join(elements["ports"]) subckt_graph = self._create_bipartite_circuit_graph( elements["nodes"], subckt_ports) self.subckts[subckt_name]['node_graph'] = subckt_graph logging.info("Saving graph: %s", subckt_name) #_show_circuit_graph(subckt_name, subckt_graph, "./library_graph_images/") _write_circuit_graph(subckt_name, subckt_graph, "./library_graphs/") fp_l.close()
def sp_parser(self): """Parse the defined file line wise""" if not os.path.isfile(self.netlist): print("File doesn't exist") else: logging.info("File exist: %s", self.netlist) fp_l = open(self.netlist, "r") line = self.get_next_line(fp_l, 1) while ".END" not in line: # if "**" in line.lower(): pass if any(c in line.lower() for c in ("//", "**",'*.')): #line = fp_l.readline() pass elif not line.strip(): pass elif "global" in line.lower(): self._parse_global(line, fp_l) elif ".temp" in line.lower(): temp_line = line logging.info("Temp line: %s", temp_line) elif ".option" in line.lower(): self._parse_option(line, fp_l) elif "subckt" in line.lower() and not "subckts" in line.lower(): self._parse_subckt_info(line, fp_l) elif "include" in line.lower() or "info" in line.lower(): self._parse_include(line, fp_l) #line = fp_l.readline() #continue elif "param" in line.lower(): check_param = self._parse_param(line, fp_l) if check_param: if self.params: self.params.update(check_param) else: self.params = check_param else: parsed_inst = _parse_inst(line) if parsed_inst: self.top_insts.append(parsed_inst) line = self.get_next_line(fp_l, 1) if not line: break print("INFO: PARSING INPUT NETLIST FILE DONE") if self.params: for param, value in self.params.items(): logging.info('Found top_param: %s, value:%s', param, value) elif self.option: self.option = filter(lambda a: a != '+', self.option) elif self._global: self._global = filter(lambda a: a != '+', self._global) if self.top_ckt_name == '__top__' or not self.top_ckt_name in self.subckts: top = os.path.basename(self.netlist).split('.')[0] logging.info('NO subckt defined, \ checking for any instance at top') logging.info("picking subckt name as filename: %s", top) if not self.top_insts: if top in self.subckts.keys(): self.top_ckt_name = os.path.basename( self.netlist).split('.')[0] logging.info( 'No top instance found. Top:%s', self.top_ckt_name) elif self.subckts.keys(): self.top_ckt_name = list(self.top_ckt_name())[0] logging.info( 'No top instance found. Top:%s', self.top_ckt_name) else: logging.info( 'No subckt found in design. Check format.') return 0 else: logging.info( 'Instances found at top, adding dummy subckt: %s', top) if self.params: for index, node in enumerate(self.top_insts): if "values" in node.keys(): #print(node) for param, value in node["values"].items(): if '*' in value: logging.info ("found function in values") value_function = value.split('*') for val in value_function: try: mult=int(val) except: value=val if value in self.params: self.top_insts[index]["values"][param] = self.params[value] try: mult except NameError: self.top_insts[index]["values"][param] = self.top_insts[index]["values"][param] else: self.top_insts[index]["values"][param] = str(mult)+'*'+self.top_insts[index]["values"][param] del mult logging.info( 'assigning top parameter %s value %s to node: %s', param, self.top_insts[index]["values"][param], node["inst"]) else: logging.error("No sizing info:%s",node["inst"]) self.top_ckt_name = top self.subckts[self.top_ckt_name] = { "ports": ["gnd", "vdd!"], "nodes": self.top_insts, "params": self.params } logging.info("List of subckts in design: %s \n", " ".join(self.subckts)) logging.info( "###################\ PARSING DONE \ #################### \n") ## remove source from tesbench circuit self._remove_source() if self.flat: logging.info("Flatten circuit: %s ", self.top_ckt_name) design = self._flatten_circuit(self.top_ckt_name) else: design = self._hier_circuit(self.top_ckt_name) subckt_ports = self.subckts[self.top_ckt_name]["ports"] logging.info( "\n###################\ FINAL CIRCUIT AFTER initialization\ #################### \n" ) logging.info("DISPLAYING circuit") for node in design: logging.info(node) logging.info( "################### \ CREATING BIPARTITE GRAPH \ #################### \n" ) self.circuit_graph = self._create_bipartite_circuit_graph( design, subckt_ports) #self._show_circuit_graph("circuit", self.circuit_graph,"./circuit_graph_images/") return self.circuit_graph
def test_subckt_param_spaces(): dev = _parse_inst("xdp D S G nmos p = 1") assert len(dev["values"].items()) == 1
def sp_parser(self): """Parse the defined file line wise""" if not os.path.isfile(self.netlist): print("File doesn't exist",self.netlist) else: logging.info("File exist: %s", self.netlist) fp_l = open(self.netlist, "r") line = self.get_next_line(fp_l, 1) while ".END" not in line: # if "**" in line.lower(): pass if any(c in line.lower() for c in ("//", "**",'*.')): #line = fp_l.readline() pass elif not line.strip(): pass elif "global" in line.lower(): self._parse_global(line, fp_l) elif ".temp" in line.lower(): temp_line = line logging.info("Temp line: %s", temp_line) elif ".option" in line.lower(): self._parse_option(line, fp_l) elif "subckt" in line.lower() and not "subckts" in line.lower(): self._parse_subckt_info(line, fp_l) elif "include" in line.lower() or "info" in line.lower(): self._parse_include(line, fp_l) elif "param" in line.lower(): check_param = self._parse_param(line, fp_l) if check_param: if self.params: self.params.update(check_param) else: self.params = check_param else: parsed_inst = _parse_inst(line) if parsed_inst: self.top_insts.append(parsed_inst) line = self.get_next_line(fp_l, 1) if not line: break print("INFO: PARSING INPUT NETLIST FILE DONE") if self.params: for param, value in self.params.items(): logging.info('Found top_param: %s, value:%s', param, value) elif self.option: self.option = filter(lambda a: a != '+', self.option) elif self._global: self._global = filter(lambda a: a != '+', self._global) logging.info("List of subckts in design: %s \n", " ".join(self.subckts)) # %% ## remove source from testbench circuit self._remove_source() if not self.top_ckt_name : logging.info("No top circuit name provided, returning multiple graphs") for name in self.subckts: design = self._hier_circuit(name) subckt_graph = self._create_bipartite_circuit_graph( design, self.subckts[name]["ports"]) self.circuits_list.append({ "name": name, "graph": subckt_graph, "ports": self.subckts[name]["ports"], }) elif self.top_insts and self.top_ckt_name not in self.subckts.keys(): logging.info( 'Instances found at top, adding dummy subckt: %s', self.top_ckt_name) if self.params: resolve_top_param() self.subckts[self.top_ckt_name] = { "ports": [], "nodes": self.top_insts, "params": self.params } design=self.resolve_hierarchy() circuit_graph = self._create_bipartite_circuit_graph( design, []) for node, attr in circuit_graph.nodes(data=True): if 'net' in attr['inst_type'] and \ len(list(circuit_graph.neighbors(node)))==1: circuit_graph.nodes[node]["net_type"]="external" self.subckts[self.top_ckt_name]["ports"].append(node) self.circuits_list.append({ "name": self.top_ckt_name, "graph": circuit_graph, "ports": self.subckts[self.top_ckt_name]["ports"], }) elif self.top_ckt_name in self.subckts.keys(): design=self.resolve_hierarchy() subckt_ports = self.subckts[self.top_ckt_name]["ports"] circuit_graph = self._create_bipartite_circuit_graph( design, subckt_ports) self.circuits_list.append({ "name": self.top_ckt_name, "graph": circuit_graph, "ports": self.subckts[self.top_ckt_name]["ports"], }) else: logging.error("No design found") return 0 logging.info( "################### PARSING DONE \ #################### \n") logging.info( "\n###################\ FINAL CIRCUIT AFTER initialization\ #################### \n" ) for node in design: logging.info(node) #self._show_circuit_graph("circuit", self.circuit_graph,"./circuit_graph_images/") return self.circuits_list
def test_pmos_param(): dev = _parse_inst("m0 3 2 1 1 p nfin = 1") assert len(dev.items()) == 6
def test_subckt_param_backslash(): dev = _parse_inst('xdp D G S / nmos p=1') assert len(dev["values"].items()) == 1
def test_nmos1(): dev = _parse_inst("m0 (3 2 1 1) n nfin=1") assert len(dev.items()) == 6
def test_nmos_err(): _parse_inst("m0 3 2=4 1 1 n nfin=1") assert AttributeError
def test_i_source(): dev = _parse_inst("i0 1 0 1.0") assert len(dev.items()) == 6
def test_e_source(): dev = _parse_inst("e0 1 0 2 0 1.0") assert len(dev.items()) == 6
def test_v_source(): dev = _parse_inst("v0 1 0 1.0") assert len(dev.items()) == 6 assert dev['inst_type'] == "v_source"
def test_r(): dev = _parse_inst("ra 1 0 10k") assert len(dev.items()) == 6 assert dev['inst_type'] == "res"
def test_blank(): be = _parse_inst("") assert be is None