def fix_modelsim_altera_sdf_annotation(top_verilog): base, ext = os.path.splitext(top_verilog) new_file = '.'.join([base, "fixed"]) + ext; # #Load the original verilog # ast, directives = verilog_parser.parse([top_verilog]) # #Add an unused stratixiv cell # mod_def = ast.description.definitions[0] #Definition of top new_inst = vast.Instance('stratixiv_io_ibuf', 'fix_modelsim_altera_sdf_annotation', [], []); new_inst_list = vast.InstanceList('stratixiv_io_ibuf', [], [new_inst]) items = list(mod_def.items) + [new_inst_list] new_mod_def = vast.ModuleDef(mod_def.name, mod_def.paramlist, mod_def.portlist, items) # #Write out the new verilog # codegen = ASTCodeGenerator() with open(new_file, "w") as f: print >>f, codegen.visit(new_mod_def) return new_file
def test(): veriloggen.reset() test_modules = from_verilog_branchpredunit.mkMips() code = ''.join( [m.to_verilog() for m in test_modules.values() if not m.used]) from pyverilog.vparser.parser import parse from pyverilog.ast_code_generator.codegen import ASTCodeGenerator import sys import tempfile # encoding: 'utf-8' ? encode = sys.getdefaultencoding() tmp = tempfile.NamedTemporaryFile() tmp.write(expected_verilog.encode(encode)) tmp.read() filename = tmp.name print(filename) expected_ast, _ = parse([filename]) codegen = ASTCodeGenerator() expected_code = codegen.visit(expected_ast) assert (expected_code == code)
def __init__(self, files: Iterable[str]): """Construct a Module from files. """ if not files: return self.ast: ast.Source self.directives: Tuple[Directive, ...] self.ast, self.directives = parser.parse(files, debug=False) self._handshake_output_ports: Dict[str, ast.Assign] = {} self._calculate_indices()
def extract_design_info(top_verilog, blif_file): # #Load the original verilog # ast, directives = verilog_parser.parse([top_verilog]) mod_def = ast.description.definitions[0] #Definition of top #Get the module name name = mod_def.name # # For verification purposes we want the inputs to be specified # in the same order as the input blif file. # # To achieve this we quickly grab the inputs from the blif and use # that order. Otherwise VPR internally changes the order which # makes verification difficult. # inputs = None outputs = None with open(blif_file) as f: for line in continued_lines(f): line.strip() if line.startswith(".inputs"): inputs = line.split()[1:] if line.startswith(".outputs"): outputs = line.split()[1:] if inputs and outputs: break assert inputs assert outputs clock_nets = set() while True: old_clock_nets = clock_nets.copy() clock_nets = identify_clock_nets(mod_def, clock_nets) if clock_nets == old_clock_nets: break else: old_clock_nets = clock_nets #Remove any clocks that show up in the input list clocks = [x for x in inputs if x in clock_nets] inputs = [x for x in inputs if x not in clock_nets] return { 'file': top_verilog, 'module': name, 'inputs': inputs, 'outputs': outputs, 'clocks': clocks, }
def parse(verilog_filename, include_list=None, define_list=None): """ parses verilog code """ if include_list is None: include_list = [] if define_list is None: define_list = [] ast, _ = parse([verilog_filename], preprocess_include=include_list, preprocess_define=define_list) return ast
def FromVerilog(source, func, type_map, target_modules=None, shallow=False, external_modules={}): parser = VerilogParser() ast = parser.parse(source) visitor = ModuleVisitor(shallow) visitor.visit(ast) if not shallow: visitor.sort() def _get_lines(start_line, end_line): if shallow: return source lines = source.split("\n") return "\n".join(lines[start_line - 1:end_line]) if not external_modules.keys().isdisjoint(visitor.defns.keys()): intersection = external_modules.keys() & visitor.defns.keys() raise Exception(f"Modules defined in both external_modules and in " f"parsed verilog: {intersection}") magma_defns = external_modules.copy() for name, verilog_defn in visitor.defns.items(): parsed_name, args = ParseVerilogModule(verilog_defn, type_map) assert parsed_name == name magma_defn = func(name, *args) if func == DefineCircuit: # Attach relevant lines of verilog source. magma_defn.verilogFile = _get_lines(verilog_defn.lineno, verilog_defn.end_lineno) if not shallow: for instance in visitor.get_instances(verilog_defn): instance_defn = magma_defns[instance.module] instance_defn() EndDefine() magma_defn.verilog_source = source magma_defns[name] = magma_defn if len(magma_defns) == 0: logger.warning( f"Did not import any modules from verilog, either could " f"not parse or could not find any of the target_modules " f"({target_modules})") # Filter back out external modules. magma_defns = {name: magma_defns[name] for name in visitor.defns} if target_modules is None: return list(magma_defns.values()) # Filter modules based on target_modules list. return [v for k, v in magma_defns.items() if k in target_modules]
def main(): INFO = "Verilog code parser" VERSION = pyverilog.__version__ USAGE = "Usage: python example_parser.py file ..." def showVersion(): print(INFO) print(VERSION) print(USAGE) sys.exit() optparser = OptionParser() optparser.add_option("-v", "--version", action="store_true", dest="showversion", default=False, help="Show the version") optparser.add_option("-I", "--include", dest="include", action="append", default=[], help="Include path") optparser.add_option("-D", dest="define", action="append", default=[], help="Macro Definition") (options, args) = optparser.parse_args() filelist = args if options.showversion: showVersion() for f in filelist: if not os.path.exists(f): raise IOError("file not found: " + f) if len(filelist) == 0: showVersion() ast, directives = parse(filelist, preprocess_include=options.include, preprocess_define=options.define) bug_added = add_bug(ast, False) #ast.show() codegen = ASTCodeGenerator() rslt = codegen.visit(ast) print(rslt)
def main(): INFO = "Verilog code parser" VERSION = pyverilog.utils.version.VERSION USAGE = "Usage: python example_parser.py file ..." def showVersion(): print(INFO) print(VERSION) print(USAGE) sys.exit() optparser = OptionParser() optparser.add_option("-v", "--version", action="store_true", dest="showversion", default=False, help="Show the version") optparser.add_option("-I", "--include", dest="include", action="append", default=[], help="Include path") optparser.add_option("-D", dest="define", action="append", default=[], help="Macro Definition") (options, args) = optparser.parse_args() filelist = args if options.showversion: showVersion() for f in filelist: if not os.path.exists(f): raise IOError("file not found: " + f) if len(filelist) == 0: showVersion() ast, directives = parse(filelist, preprocess_include=options.include, preprocess_define=options.define) module = verilog_module.module() show(ast, module) with open('out.dot', 'w') as fh: fh.write(module.render("docs/port_template.dot"))
def main(): INFO = "Verilog code parser" VERSION = pyverilog.utils.version.VERSION USAGE = "Usage: python example_parser.py file ..." def showVersion(): print(INFO) print(VERSION) print(USAGE) sys.exit() optparser = OptionParser() optparser.add_option("-v", "--version", action="store_true", dest="showversion", default=False, help="Show the version") optparser.add_option("-I", "--include", dest="include", action="append", default=[], help="Include path") optparser.add_option("-D", dest="define", action="append", default=[], help="Macro Definition") (options, args) = optparser.parse_args() filelist = args if options.showversion: showVersion() for f in filelist: if not os.path.exists(f): raise IOError("file not found: " + f) if len(filelist) == 0: showVersion() ast, directives = parse(filelist, preprocess_include=options.include, preprocess_define=options.define) ast.show() for lineno, directive in directives: print('Line %d : %s' % (lineno, directive))
def _create_graphgen_obj(self, verilog_file, top_module, generate_cfg, generate_ast): dataflow_analyzer = PyDataflowAnalyzer(verilog_file, top_module) dataflow_analyzer.generate() binddict = dataflow_analyzer.getBinddict() terms = dataflow_analyzer.getTerms() dataflow_optimizer = PyDataflowOptimizer(terms, binddict) dataflow_optimizer.resolveConstant() resolved_terms = dataflow_optimizer.getResolvedTerms() resolved_binddict = dataflow_optimizer.getResolvedBinddict() constlist = dataflow_optimizer.getConstlist() if generate_cfg: fsm_vars = tuple(['fsm', 'state', 'count', 'cnt', 'step', 'mode']) self.cfg_graph_generator = PyControlflowAnalyzer( "top", terms, binddict, resolved_terms, resolved_binddict, constlist, fsm_vars) elif generate_ast: #when generating AST, determines which substructure (dictionary/array) to generate #before converting the json-like structure into actual json self.DICTIONARY_GEN = [ "Source", "Description", "Ioport", "Decl", "Lvalue" ] self.ARRAY_GEN = [ "ModuleDef", "Paramlist", "Portlist", "Input", "Width", "Reg", "Wire", "Rvalue", "ParseSelect", "Uplus", "Uminus", "Ulnot", "Unot", "Uand", "Unand", "Uor", "Unor", "Uxnor", "Power", "Times", "Divide", "Mod", "Plus", "Minus", "Sll", "Srl", "Sla", "Sra", "LessThan", "GreaterThan", "LessEq", "GreaterEq", "Eq", "Eql", "NotEq", "Eql", "NotEql", "And", "Xor", "Xnor", "Or", "Land", "Lor", "Cond", "Assign", "Always", "AlwaysFF", "AlwaysComb", "AlwaysLatch", "SensList", "Sens", "Substitution", "BlockingSubstitution", "NonblockingSubstitution", "IfStatement", "Block", "Initial", "Plus", "Output", "Partselect" ] self.CONST_DICTIONARY_GEN = [ "IntConst", "FloatConst", "StringConst", "Identifier" ] self.ast, _ = parse([verilog_file]) else: #generate dfg self.dfg_graph_generator = PyGraphGenerator( top_module, terms, binddict, resolved_terms, resolved_binddict, constlist, f'{self.output_directory}seperate_modules.pdf')
def get_ast(design, version, verilog_path=None): rtl_path = get_rtl_path(design, version) + "/" incl_dirs = [ rtl_path + inc_dir for inc_dir in config.designs[design]["include_dirs"] ] if verilog_path == None: vfiles = get_vfile(design, version) else: vfiles = [verilog_path] # Uncomment to dump preprocessed verilog file pre = VerilogPreprocessor(vfiles, "preprocess.out", incl_dirs, []) pre.preprocess() ast, direct = parse(vfiles, preprocess_include=incl_dirs) return ast
def __init__(self, verilog_file_path): if not os.path.isfile(verilog_file_path): raise ValueError(verilog_file_path + ' is not a valid file') self.ast_root, self.directives = parse([verilog_file_path], preprocess_include=[], preprocess_define=[]) self.codegen = CustomizedASTCodeGenerator() definitions = self.ast_root.description.definitions self.module = None for definition in definitions: if isinstance(definition, ast.ModuleDef): if self.module is None: self.module = definition else: raise ValueError( verilog_file_path + ' has more than one module defined within it') if self.module is None: raise ValueError(verilog_file_path + ' has no module defined within it')
def locateModules(top_hdl_path): if (not os.path.isfile(top_hdl_path)): print(f'[locateModules] no file found for {top_hdl_path}') return None top_mod_ast, directives = parse([top_hdl_path]) all_modules = [] # traverse the rtl and apply a function def dfs(node, func): func(node) for c in node.children(): dfs(c, func) def getValidModule(node): if (type(node) is ast.Instance and 'fifo' not in node.module and 'start_for' not in node.module): all_modules.append(node.module) dfs(top_mod_ast, getValidModule) return all_modules
def FromVerilog(source, func): parser = VerilogParser() ast = parser.parse(source) #ast.show() v = ModuleVisitor() v.visit(ast) if func == DefineCircuit: # only allow a single verilog module assert len(v.nodes) == 1 modules = [] for node in v.nodes: name, args = ParseVerilogModule(node) circuit = func(name, *args) if func == DefineCircuit: # inline source circuit.verilogFile = source EndDefine() modules.append(circuit) return modules
def main(): INFO = "Verilog code parser" VERSION = pyverilog.utils.version.VERSION USAGE = "Usage: python example_parser.py file ..." def showVersion(): print(INFO) print(VERSION) print(USAGE) sys.exit() optparser = OptionParser() optparser.add_option("-v","--version",action="store_true",dest="showversion", default=False,help="Show the version") optparser.add_option("-I","--include",dest="include",action="append", default=[],help="Include path") optparser.add_option("-D",dest="define",action="append", default=[],help="Macro Definition") (options, args) = optparser.parse_args() filelist = args if options.showversion: showVersion() for f in filelist: if not os.path.exists(f): raise IOError("file not found: " + f) if len(filelist) == 0: showVersion() ast, directives = parse(filelist, preprocess_include=options.include, preprocess_define=options.define) ast.show() for lineno, directive in directives: print('Line %d : %s' % (lineno, directive))
def test(): veriloggen.reset() test_modules = from_verilog_branchpredunit.mkMips() code = ''.join([ m.to_verilog() for m in test_modules.values() if not m.used ]) from pyverilog.vparser.parser import parse from pyverilog.ast_code_generator.codegen import ASTCodeGenerator import sys import tempfile # encoding: 'utf-8' ? encode = sys.getdefaultencoding() tmp = tempfile.NamedTemporaryFile() tmp.write(expected_verilog.encode(encode)) tmp.read() filename = tmp.name print(filename) expected_ast, _ = parse([ filename ]) codegen = ASTCodeGenerator() expected_code = codegen.visit(expected_ast) assert(expected_code == code)
def main(): INFO = "Verilog code parser" VERSION = pyverilog.utils.version.VERSION USAGE = "Usage: python example_parser.py file ..." sys.setrecursionlimit(50000) def showVersion(): print(INFO) print(VERSION) print(USAGE) sys.exit() optparser = OptionParser() optparser.add_option("-v", "--version", action="store_true", dest="showversion", default=False, help="Show the version") optparser.add_option("-I", "--include", dest="include", action="append", default=[], help="Include path") optparser.add_option("-D", dest="define", action="append", default=[], help="Macro Definition") (options, args) = optparser.parse_args() filelist = args if options.showversion: showVersion() for f in filelist: if not os.path.exists(f): raise IOError("file not found: " + f) if len(filelist) == 0: showVersion() ast, directives = parse(filelist, preprocess_include=options.include, preprocess_define=options.define) pi = [] po = [] conn = {} mod = {} calc_primaries(ast, pi, po) calc_fan_recursive(ast, conn, '') descriptors = [] create_buffer(conn, pi, descriptors, mod) recursive(ast, conn, pi, po, descriptors, mod) update_index(descriptors, mod) update_level(descriptors) for var in descriptors: var.show()
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO) elif args.log_level == 'warning': logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.WARNING) elif args.log_level == 'error': logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.ERROR) elif args.log_level == 'critical': logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.CRITICAL) ### Parse the input file logging.info('Parsing file input file: %s' % args.infile) ast, directives = vparser.parse([args.infile]) ### Walk the AST and replace DesignCompiler constructs with RTL logging.info('Performing AST replacements.') (gtech, synth, generics) = ast_walk_and_swap_inplace(ast) total = gtech + synth + generics if total == 0: logging.info('No GTECH, SYNTHETIC, or GENERICS instances found!') else: logging.info('Total Number of Replacements = %d' % total) logging.info("\t GTECH swap Count: %d (%d%%)" % (gtech, (gtech / total) * 100)) logging.info("\t SYNTHETIC swap Count: %d (%d%%)" % (synth, (synth / total) * 100)) logging.info("\t GENERICS swap Count: %d (%d%%)" %
def loadVerilog(file:str): INFO = "Verilog code parser" VERSION = pyverilog.__version__ USAGE = "Usage: python example_parser.py file ..." def showVersion(): print(INFO) print(VERSION) print(USAGE) sys.exit() ''' optparser = OptionParser() optparser.add_option("-v", "--version", action="store_true", dest="showversion", default=False, help="Show the version") optparser.add_option("-I", "--include", dest="include", action="append", default=[], help="Include path") optparser.add_option("-D", dest="define", action="append", default=[], help="Macro Definition") (options, args) = optparser.parse_args() ''' ''' filelist = args if options.showversion: showVersion() for f in filelist: if not os.path.exists(f): raise IOError("file not found: " + f) if len(filelist) == 0: showVersion() ''' filelist = [file] print('dupa') ast, directives = parse(filelist) #preprocess_include=options.include, #preprocess_define=options.define) #print(ast.show()) #for lineno, directive in directives: #print('Line %d : %s' % (lineno, directive)) indent = 1 def show(self, buf = sys.stdout, offset=0, attrnames=False, showlineno=True): lead = f'[{offset}] ' buf.write(lead + self.__class__.__name__ + ': ') if self.attr_names: if attrnames: nvlist = [(n, getattr(self, n)) for n in self.attr_names] attrstr = ', '.join('%s=%s' % (n, v) for (n, v) in nvlist) else: vlist = [getattr(self, n) for n in self.attr_names] attrstr = ', '.join('%s' % v for v in vlist) buf.write(attrstr) if showlineno: buf.write(' (at %s)' % self.lineno) buf.write('\n') for c in self.children(): show(c, buf, offset + indent, attrnames, showlineno) def loadModules(astObj, mDict, buf = sys.stdout, offset=0, attrnames=False, showlineno=True): oName = astObj.__class__.__name__ if oName == 'ModuleDef': mDict[astObj.name] = astObj if offset == 2: buf.write(f'[loadModules] {astObj.__class__.__name__} \n') for c in astObj.children(): loadModules(c, mDict, buf, offset + indent, attrnames, showlineno) def loadPortArg(ast,mDict,parent): print(f'loading portArg:{ast.name}') def loadPortArgs(ast,mDict,parent): cName = ast.__class__.__name__ if cName == 'Identifier': ind = len(mDict['_ports']) mDict['_ports'][ind]={} mDict['_ports'][ind]['ident']=ast.name mDict['_ports'][ind]['identWInd']=ast.name if cName == 'IntConst': ind = len(mDict['_ports'])-1 mDict['_ports'][ind]['index']=ast.value mDict['_ports'][ind]['identWInd']+=f'[{ast.value}]' for c in ast.children(): loadPortArgs(c,mDict,parent) def loadInstance(ast,mDict,parent): print(f'loading instance:{ast.name} module:{ast.module}') result = None tmodule = ast.module tname = ast.name if tmodule in ['xor','or','and','not','nand','nor']: if tname == 'CN4bgate': print('debher') pPorts = mDict['_ports'] mDict['_ports']={} loadPortArgs(ast,mDict,parent) lp = len(mDict['_ports']) if lp >3: #multiport version gname = su.toUpper(tmodule)+'4' else: #2inp gname = su.toUpper(tmodule) gate = parent.modAdd(tname, impl = f'local:/{gname}' ) for k in mDict['_ports']: dv = mDict['_ports'][k] dvWind = dv['identWInd'] if k==0: #output mDict['_outputs'][dvWind]=gate.nod('Y') else: aa = ord('A') ii = k-1 cg = chr(aa+ii) tn = gate.nod(cg) mDict['_inputs'][dvWind]=tn if dvWind in mDict['_outputs']: sn = mDict['_outputs'][dvWind] if tn == None: print('got a prob') sn.connect(tn) #for k in mDict['_ports'] = pPorts elif tmodule in ['buf']: pPorts = mDict['_ports'] mDict['_ports']={} loadPortArgs(ast,mDict,parent) lp = len(mDict['_ports']) if lp == 2: for k in mDict['_ports']: dv = mDict['_ports'][k] dvIdent = dv['ident'] dvWind = dv['identWInd'] if k==0: #output sName = dvIdent else: #input sIdent = dvIdent sIdentWI = dvWind sIndex = dv['index'] mMap = parent.mod('sigMap'+sIdent) nO=mMap.ioAdd(sName, ioType = IoType.OUTPUT ) mMap.setSigFormula(sName,f'=IS[{sIndex}]') mDict['_outputs'][sName]=nO else: assert False, f'[loadInstance] Unhandled ports number for buffer:{lp}' mDict['_ports'] = pPorts elif tmodule in mDict: #module mt = parent.modAdd(tname) pInps = mDict['_inputs'] pOuts = mDict['_outputs'] pOutsF = mDict['_outputsF'] loadModule(mDict[tmodule],mDict,mt) mDict['_inputs'] = pInps mDict['_outputs'] = pOuts mDict['_outputsF'] = pOutsF for n in mt.nodes().values(): if n.ioType() in [IoType.INPUT,IoType.DYNAMIC]: mDict['_inputs'][n.name()]=n if n.ioType() in [IoType.OUTPUT,IoType.DYNAMIC]: mDict['_outputs'][n.name()]=n pass else: assert False, f'[loadInstance] Unhandled module name:{tmodule}' return result def loadInstances(ast,mDict,parent): cName = ast.__class__.__name__ if cName == 'Instance': loadInstance(ast,mDict,parent) for c in ast.children(): loadInstances(c,mDict,parent) def loadOutputs(ast,mDict,parent): cName = ast.__class__.__name__ if cName == 'Decl': ind = len(mDict['_outputsF'])-1 if ind>-1: mDict['_outputsF'][ind]['ended']=True if cName == 'Output': ind = len(mDict['_outputsF']) mDict['_outputsF'][ind]={} mDict['_outputsF'][ind]['ended']=False mDict['_outputsF'][ind]['name']=ast.name if cName == 'IntConst': ind = len(mDict['_outputsF'])-1 if ind>-1 and not mDict['_outputsF'][ind]['ended']: if 'from' not in mDict['_outputsF'][ind]: mDict['_outputsF'][ind]['from'] = ast.value else: mDict['_outputsF'][ind]['to'] = ast.value for c in ast.children(): loadOutputs(c,mDict,parent) def loadInputs(ast,mDict,parent): cName = ast.__class__.__name__ if cName == 'Decl': ind = len(mDict['_inputs'])-1 if ind>-1: mDict['_inputs'][ind]['ended']=True if cName == 'Input': ind = len(mDict['_inputs']) mDict['_inputs'][ind]={} mDict['_inputs'][ind]['ended']=False mDict['_inputs'][ind]['name']=ast.name if cName == 'IntConst': ind = len(mDict['_inputs'])-1 if ind>-1 and not mDict['_inputs'][ind]['ended']: if 'from' not in mDict['_inputs'][ind]: mDict['_inputs'][ind]['from'] = ast.value else: mDict['_inputs'][ind]['to'] = ast.value for c in ast.children(): loadInputs(c,mDict,parent) def processOutputs(mDict,parent): for k in mDict['_outputsF']: idef = mDict['_outputsF'][k] nOutName = idef['name'] if nOutName == 'CN4b': print('trace') if 'from' in idef and idef['from']!='0': sz = int(idef['from'])-int(idef['to'])+1 nOut = parent.ioAdd(nOutName, ioType = IoType.OUTPUT, size = sz ) mDict['_outputs'][nOutName]=nOut mapMod = parent.modAdd('sigMap'+nOutName) os1 = mapMod.ioAdd('OS',ioType=IoType.OUTPUT,size=sz) os1.connect(nOut) sformula ='=0' for i in range(0,sz,1): nN = nOutName+f'{i}' nNO = nOutName+f'[{i}]' nn0 = mapMod.ioAdd(nN, ioType = IoType.INPUT ) if nNO == 'F[0]': print('trace') if nNO in mDict['_outputs']: ns = mDict['_outputs'][nNO] ns.connect(nn0) else: # not mapped ? or defined as from to without pass #mapMod.setSigFormula(nN,f'= OS[{i}]') #mDict['_outputs'][nN]=nn0 sformula += f'+({nN}.value()<<{i})' mapMod.setSigFormula('OS',sformula) else: nOut = parent.ioAdd(nOutName, ioType = IoType.OUTPUT ) if nOutName in mDict['_outputs']: ns = mDict['_outputs'][nOutName] ns.connect(nOut) else: #not used? pass def processInputs(mDict,parent): for k in mDict['_inputs']: idef = mDict['_inputs'][k] nInpName = idef['name'] if 'from' in idef: sz = int(idef['from'])-int(idef['to'])+1 nInp = parent.ioAdd(nInpName, ioType = IoType.INPUT, size = sz ) mDict['_outputs'][nInpName]=nInp mapMod = parent.modAdd('sigMap'+nInpName) is1 = mapMod.ioAdd('IS',ioType=IoType.INPUT,size=sz) nInp.connect(is1) for i in range(0,sz,1): nN = nInpName+f'[{i}]' nn0 = mapMod.ioAdd(nN, ioType = IoType.OUTPUT ) mapMod.setSigFormula(nN,f'= IS[{i}]') mDict['_outputs'][nN]=nn0 else: nInp = parent.ioAdd(nInpName, ioType = IoType.INPUT ) mDict['_outputs'][nInpName]=nInp def loadModule(astMod, mDict,parent): print(f'loading module {astMod.name}') mDict['_inputs']={} mDict['_outputs']={} loadInputs(astMod,mDict,parent) # now we'll build temporary graph modules for input singnal mapping processInputs(mDict,parent) #mc = parent.modAdd(astMod.name) loadInstances(astMod,mDict,parent) mDict['_outputsF']={} loadOutputs(astMod,mDict,parent) processOutputs(mDict,parent) #show(astMod,attrnames=True) show(ast) mDict = {} loadModules(ast, mDict) print('dir(mDict.keys()):') for k in mDict: print(f'K:{k}') parentv = modvAdd('Summodule') parent = parentv.module() k = 'Summodule' mDict['_ports']=None #mDict['_sigs']=None loadModule(mDict[k],mDict,parent) parentv = modvAdd('CLAmodule') parent = parentv.module() k= 'CLAmodule' mDict['_ports']=None loadModule(mDict[k],mDict,parent) parentv = modvAdd('Dmodule') parent = parentv.module() k= 'Dmodule' mDict['_ports']=None loadModule(mDict[k],mDict,parent) parentv = modvAdd('Emodule') parent = parentv.module() k= 'Emodule' mDict['_ports']=None loadModule(mDict[k],mDict,parent) parentv = modvAdd('TopLevel74181') parent = parentv.module() k= 'TopLevel74181' mDict['_ports']=None loadModule(mDict[k],mDict,parent)
def verilog_reader(verilog_file,include_line_number,start_keywords): lex_dict = defaultdict(list) parse_dict = defaultdict(list) veri_parse_line_no_arr = [] nospace_line_arr = [] line_array_dict = defaultdict(list) start_line_dict = dict.fromkeys(list(start_keywords.keys()),0)# Initializing # Parsing Verilog # ============================================================================== output_buf = 'preprocess.out' output_buf = StringIO() ast, directives = parse(verilog_file, preprocess_include=options.include, preprocess_define=options.define) ast.show(buf=output_buf) parser_result = output_buf.getvalue() lex = preprocess(verilog_file, include=options.include, define=options.define) lex_result = dump_tokens(lex) # Parsing Verilog Lines # ============================================================================== for line in parser_result.splitlines(): nospace_line = re.sub(r'\s','',line) veri_parse_line_no = int((re.findall(r'\(at(\d+)\)',nospace_line))[0]) - include_line_number #250 is line numbers of cmsdk_mcu_defs.v and 55 is line numbers of cmsdk_ahb_memory_defs.v for destination veri_parse_line_no_arr.append(veri_parse_line_no) nospace_line_arr.append(nospace_line) veri_parse_left_subject = (nospace_line.split(':'))[0] veri_parse_right_subject = (re.findall(r'(\S+)\(at\d+\)',(nospace_line.split(':'))[-1])) if veri_parse_right_subject != []: veri_parse_right_subject = veri_parse_right_subject[0] for task in start_keywords: start_left_keyword = start_keywords[task][0] start_line_offset = start_keywords[task][1] # start_keywords[task][1] is line offset: is 1 for source with Moduledef keyword start_right_flag = start_keywords[task][2] # start_keywords[task][2] determines whether should we consider veri_parse_src_right_subject as we do for source with options.module_name for Instantiation keyword start_right_keyword = start_keywords[task][3] array_line_keyword = start_keywords[task][4] if not start_right_flag: if veri_parse_left_subject == start_left_keyword: start_line = veri_parse_line_no + start_line_offset start_line_dict[task] = start_line else: if (veri_parse_left_subject == start_left_keyword) and (veri_parse_right_subject == start_right_keyword): start_line = veri_parse_line_no + start_line_offset start_line_dict[task] = start_line if veri_parse_left_subject == array_line_keyword: line_array_dict[task].append(veri_parse_line_no) parse_dict[veri_parse_line_no].append([veri_parse_left_subject, veri_parse_right_subject]) for line in lex_result.splitlines(): veri_lex_line_no = int((re.findall(r'\S+\s\S+\s(\d+)',line))[0]) - include_line_number #250 is line numbers of cmsdk_mcu_defs.v and 55 is line numbers of cmsdk_ahb_memory_defs.v veri_lex_subject = (re.findall(r'\S+\s(\S+)\s\d+',line))[0] lex_dict[veri_lex_line_no].append(veri_lex_subject) # values = np.array(veri_parse_line_no_arr) # desired_index = (np.where(values==96))[0] # print(np.array(nospace_line_arr)[desired_index]) return start_line_dict, parse_dict, line_array_dict, lex_dict
import pyverilog.vparser.ast as vast from pyverilog.vparser.parser import parse from pyverilog.ast_code_generator.codegen import ASTCodeGenerator rtl = "test.v" ast, _ = parse([rtl]) # get the root node of the tree (Description) desc = ast.description # get the ModuleDef node definition = desc.definitions[0] # get the portlist # loop over all items with type InstanceList # print the cell ports and their corresponding arguments newrtl = [] inputlist = [] outputlist = [] clkgateArgs = [ vast.PortArg("GCLK", vast.Identifier("__clockgate_output_gclk_")), vast.PortArg("GATE", vast.Identifier("EN")), vast.PortArg("CLK", vast.Identifier("CLK")) ] clkgate_cell = vast.Instance("sky130_fd_sc_hd__dlclkp", "__clockgate_cell__", tuple(clkgateArgs), tuple()) clockgate_output_gclk = vast.Wire('__clockgate_output_gclk_') k = 0 insertedbefore = 0 newrtl.append(clockgate_output_gclk) for itemDeclaration in definition.items:
def parseDesignHeader(verilog_file): global padFrameHeaderDefinition global padFrameHeader global topModuleDeclarations global topModuleBody module_header = design_json["name"] + " core_inst(\n" wiresDeclarations = "" ast, x = parse([verilog_file]) # output = StringIO() out = StringIO() ast.show(buf=out) rlst = out.getvalue() # print(rlst) startString = "ModuleDef: " + design_json["name"] startPoint = rlst.find(startString) startPoint = rlst.find("Portlist:", startPoint) declIdx = rlst.find("Decl:", startPoint) instanceListIdx = rlst.find("InstanceList:", startPoint) moduleDefIdx = rlst.find("ModuleDef:", startPoint) if declIdx == -1: declIdx = 0x0FFFFFFF if instanceListIdx == -1: instanceListIdx = 0x0FFFFFFF if moduleDefIdx == -1: moduleDefIdx = 0x0FFFFFFF endIdx = min(declIdx, instanceListIdx, moduleDefIdx) if endIdx != 0x0FFFFFFF: rlst = rlst[:endIdx] portList = rlst[startPoint:].split("Ioport:") # print(portList) # print(portList) for port in portList[1:]: port_split = port.split("\n") for idx in range(len(port_split)): line = port_split[idx] if line.find("Input") != -1: signalName = getSignalName(line) signalSize = extractSizeFromVerilog(port_split, idx) module_header += "." + signalName + "(" + signalName + "),\n" wiresDeclarations += "wire " + signalSize + " " + signalName + ";\n" padFrameHeader += "." + signalName + "(" + signalName + "),\n" padFrameHeaderDefinition += ("output " + signalSize + " " + signalName + ",\n") break elif line.find("Output") != -1: signalName = getSignalName(line) signalSize = extractSizeFromVerilog(port_split, idx) module_header += "." + signalName + "(" + signalName + "),\n" wiresDeclarations += "wire " + signalSize + " " + signalName + ";\n" padFrameHeader += "." + signalName + "(" + signalName + "),\n" padFrameHeaderDefinition += ("input " + signalSize + " " + signalName + ",\n") break elif line.find("Inout") != -1: signalName = getSignalName(line).strip() signalSize = extractSizeFromVerilog(port_split, idx) module_header += "." + signalName + "(" + signalName + "),\n" wiresDeclarations += "wire " + signalSize + " " + signalName + ";\n" padFrameHeader += "." + signalName + "(" + signalName + "),\n" padFrameHeaderDefinition += ("inout " + signalSize + " " + signalName + ",\n") break module_header = module_header[:-2] + ");\n" topModuleDeclarations += wiresDeclarations topModuleBody += module_header
def main(): INFO = "Verilog identifier renamer" USAGE = "Usage: python3 amnesia.py file ..." keeplist = ["clk", "reset", "inData", "outData"] def showUsage(): print(INFO) print(USAGE) sys.exit() optparser = OptionParser() optparser.add_option("-I", "--include", dest="include", action="append", default=[], help="Include path") optparser.add_option("-D", dest="define", action="append", default=[], help="Macro Definition") optparser.add_option("-x", dest="exclude", action="append", default=keeplist, help="Identifiers to exclude from obfuscation") (options, args) = optparser.parse_args() filelist = args for f in filelist: if not os.path.exists(f): raise IOError("file not found: " + f) if len(filelist) == 0: showUsage() ast, directives = parse(filelist, preprocess_include=options.include, preprocess_define=options.define) #ast.show() # getIdentifiers is a list of all identifiers, including repeats. # ths i:i thing changes it on the fly into a dictionary, # as a way of doing "sort | uniq," basically. ids = {i: i for i in getIdentifiers(ast)} # now build our from:to mapping for all of those identifiers. for orig_id in ids: if orig_id in options.exclude: ids[orig_id] = orig_id else: ids[orig_id] = stringGarbage(32) ## PyVerilog comes with a function called "replaceIdentifiers" that should ## do this, but it doesn't get everything. Ours will chomp on anything ## what has a name. AST_traverse_rename_identifiers(ast, ids) codegen = ASTCodeGenerator() rslt = codegen.visit(ast) ## AST back to Verilog print(rslt)
def main(): ast, directives = parser.parse(sys.argv[1:]) ast.show() for lineno, directive in directives: print('Line %d : %s' % (lineno, directive)) circuits = {} native_circuits = {} native_defines = [] all_intrinsics = set() other_modules = {m.name: m for m in ast.description.definitions} for module_def in ast.description.definitions: native_sim_file = None for item in module_def.items: if isinstance(item, Decl): for param in item.list: if isinstance(param, Parameter): if param.name == 'native_sim': native_sim_file = param.value.var.value if native_sim_file: sim_file, _, module = native_sim_file.partition(':') with open(sim_file, 'r') as f: natives = json.load(f)['circuits'] for native_mod in natives: if native_mod['name'] == module: native_circuits[module_def.name] = native_mod break else: raise ValueError('cannot find native module') def filter_ports(cls): res = [] for port in module_def.portlist.ports: if isinstance(port.first, cls): if port.first.width: w = int(port.first.width.msb.value) - int( port.first.width.lsb.value) + 1 else: w = 1 res.append((port.first.name, w)) return res inputs = filter_ports(Input) outputs = filter_ports(Output) native_defines.append((module_def.name, inputs, outputs)) else: name, circuit, req_intrinsics = compile_module( module_def, other_modules) circuits[name] = circuit all_intrinsics.update(req_intrinsics) processed_intrinsics = set() while all_intrinsics: intrinsic = all_intrinsics.pop() processed_intrinsics.add(intrinsic) name, circuit, others = generate_intrinsic(intrinsic) circuits[name] = circuit all_intrinsics.update(others.difference(processed_intrinsics)) print(all_intrinsics, processed_intrinsics) # with open('circuitsim/intrinsics.sim', 'r') as f: # native_circuits = json.load(f)['circuits'] # # native_defines = [ # ('Memory', [('Address', 16), ('In', 32), ('Clock', 1), ('Write', 1)], [('Out', 32)]) # ] # for entry, _, _ in native_defines: # if entry in circuits: # circuits.pop(entry) ir_lowering.compile_circuits(circuits, filename='circuitsim/verilog.sim', native_circuits=list( native_circuits.values()), defines=native_defines)
def run(src_fn, fout, module=None, top='top', iclks=None, verbose=False): ast, directives = parse([src_fn]) def get_top_module(ast, module=None): # Only one module? if len(ast.children()) == 1 and len( ast.children()[0].definitions) == 1: ret = ast.children()[0].definitions[0] if module: assert ret.name == module return ret else: if not module: raise ValueError("Multiple modules and module not given") for child in ast.children(): for m in child.definitions: if m.name == module: return m else: raise ValueError("Failed to find given module name") m = get_top_module(ast, module) dut = m.name assert type(m) == pyverilog.vparser.ast.ModuleDef if iclks is None: iclks = find_iclks(m) dinn, doutn = calc_port_width(m, iclks) fout.write('''\ /* * Generated by harness_gen.py * From: %s */ module %s(input wire clk, input wire stb, input wire di, output wire do); localparam integer DIN_N = %u; localparam integer DOUT_N = %u; reg [DIN_N-1:0] din; wire [DOUT_N-1:0] dout; reg [DIN_N-1:0] din_shr; reg [DOUT_N-1:0] dout_shr; always @(posedge clk) begin din_shr <= {din_shr, di}; dout_shr <= {dout_shr, din_shr[DIN_N-1]}; if (stb) begin din <= din_shr; dout_shr <= dout; end end assign do = dout_shr[DOUT_N-1]; ''' % (os.path.basename(src_fn), top, dinn, doutn)) for port in m.portlist.ports: c0 = port_child(port) dini = 0 douti = 0 fout.write(' %s dut(\n' % (dut, )) for porti, port in enumerate(m.portlist.ports): c0 = port_child(port) def get_to(): nonlocal dini nonlocal douti if c0.width: widthn = int(c0.width.msb.value) - int(c0.width.lsb.value) + 1 else: widthn = 1 # Connect to clock net, not general I/O if c0.name in iclks: return 'clk' elif type(c0) is pyverilog.vparser.ast.Input: if c0.width: slice_ = '%u:%u' % (dini + widthn - 1, dini) else: slice_ = dini dini += widthn assert dini <= dinn return 'din[%s]' % slice_ elif type(c0) is pyverilog.vparser.ast.Output: if c0.width: slice_ = '%u:%u' % (douti + widthn - 1, douti) else: slice_ = douti douti += widthn assert douti <= doutn return 'dout[%s]' % slice_ else: assert 0 comma = ',' if porti < len(m.portlist.ports) - 1 else '' fout.write(' .%s(%s)%s\n' % (c0.name, get_to(), comma)) fout.write(' );\n') fout.write('endmodule\n')
def get_instances(flist, vim_buf, inst_name=None): """Get instance information from files in filelist. Args: :param tuple flist: verilog file list. :param list vim_buf: vim buffer :param str inst_name: instance name. Returns: instance dict with parameters and ports. """ # parse verilog files try: ast, __ = parse(flist) except ParseError as pe: print(pe) return None # precimpiled regexp patterns re_pat_cmt = re.compile(r'^\s*//') re_pat_prespace = re.compile(r'^(\s*)') re_pat_semicolon = re.compile(r';') re_pat_port_type = re.compile(r'//([WP]?)([IO]+)') # Find the max and min line number for module port list port_line_nums = [int(p.lineno) for p in ast.children()[0].children()[0].portlist.ports] max_modport_ln = max(port_line_nums) if port_line_nums else 0 min_modport_ln = min(port_line_nums) if port_line_nums else 0 # Iterate all instances # Source->Description->ModuleDef->InstanceList->Instance inst_dict = {} for mod_def in ast.children()[0].children()[0].children(): if not isinstance(mod_def, InstanceList): continue # instances = [x for x in mod_def.children() if isinstance(x, Instance)] for i in mod_def.instances: # params = [x for x in i.children() if isinstance(x, ParamArg)] # ports = [x for x in i.children() if isinstance(x, PortArg)] # get parameter list param_dict = {p.paramname: str(p.argname) for p in i.parameterlist} # get port list port_dict = {} for p in i.portlist: childen = tuple(map(str, p.argname.children())) instp_name = childen[0] if childen else str(p.argname) slice_expr = f"[{':'.join(childen[1:])}]" if childen else '' line_num = int(p.lineno) # get port type: WI/O, PI/O, or I/O mat = re_pat_port_type.search(vim_buf[line_num-1]) port_type = mat.group(1) if mat else '' direction = mat.group(2) if mat else '' port_dict.update({str(p.portname): dict(instp=instp_name, slice=slice_expr, type=port_type, dir=direction)}) port_ln = [int(p.lineno) for p in i.portlist] max_port_ln = max(port_ln) if port_ln else (i.lineno + 1) min_port_ln = min(port_ln) if port_ln else (i.lineno + 1) # print(f'max={max_port_ln}, min={min_port_ln}') # validate vai-autoinst directive. # vai-autoinst directive should be between the start line and the min port line valid_vai_inst = False re_pat_inst = re.compile(rf'{i.name}\s*\(\s*/\*\s*{directives["AI"]}\s*\*/') # minus 1 because vim buffer index starts from 1 for line in vim_buf[(i.lineno-1):(min_port_ln-1)]: if re_pat_cmt.search(line): continue if re_pat_inst.search(line): valid_vai_inst = True # stop if current instance doesn't have vai-autoinst directive if not valid_vai_inst: continue # find the end line number. end_ln = max_port_ln # minus 1 because vim buffer index starts from 1 for idx, line in enumerate(vim_buf[(max_port_ln-1):]): if re_pat_cmt.search(line): continue if re_pat_semicolon.search(line): end_ln += idx break # get the indent mat = re_pat_prespace.search(vim_buf[i.lineno - 1]) indent = len(mat.group(1)) if mat else 0 inst_dict.update({i.name: { 'parent_port_ln': (min_modport_ln, max_modport_ln), 'mod': i.module, 'begin_ln': i.lineno, 'end_ln': end_ln, 'indent': indent, 'param': param_dict, 'port': port_dict }}) return inst_dict if inst_name is None else inst_dict.get(inst_name, None)
def getTargetComponentList(targetFile, include, define): # Takes verilog file name, splits it to use it for the top module name def getTargetFileName(verilogFile): name = verilogFile.split('.') # Additional Information for Systemverilog Files if 'sv' in name[1]: print( "This program may not work correct if the target file is a " "Systemverilog file (recognized by ending)!") return name[0] # Preperations for pyverilog parsing tmp_fileList = [] tmp_fileList.append(targetFile) targetFileName = getTargetFileName(targetFile) ast, directives = parse( tmp_fileList, preprocess_include=include, preprocess_define=define) if verbose: ast.show() # Code container, which will be filled with all the necessary data for # the faulty code componentData = codeComponents() topModuleInputs = [] topModuleOutputs = [] topModuleWires = [] # AST Data Mining Loop for i in range(0, ast.description.definitions[0].items.__len__()): # "Decl" part stands for the top module, so it contains inputs, # outputs and wires of the top module if "Decl" in str(ast.description.definitions[0].items[i]): # If inputs are found... for j in range(0, ast.description.definitions[0].items[i].list.__len__()): if "Input" in str(ast.description.definitions[0].items[i].list): inputName = ast.description.definitions[0].items[i].list[j].name inputPortDirection = "Input" # To catch if input is a vector if ast.description.definitions[0].items[i].list[j].width is not None: inputWidthMSB = ast.description.definitions[0].items[i].list[j].width.msb.value inputWidthLSB = ast.description.definitions[0].items[i].list[j].width.lsb.value if verbose: print( "Decl: TargetModule-Input: " + inputName + "[" + inputWidthMSB + ":" + inputWidthLSB + "]") topModuleInputs.append((inputPortDirection, '!top-port', inputName + "[" + inputWidthMSB + ":" + inputWidthLSB + "]", "vector")) else: if verbose: print("Decl: TargetModule-Input: " + inputName) topModuleInputs.append((inputPortDirection, '!top-port', inputName, "singular")) # If outputs are found... elif "Output" in str(ast.description.definitions[0].items[i].list): outputName = ast.description.definitions[0].items[i].list[j].name outputPortDirection = "Output" # To catch if output is a vector if ast.description.definitions[0].items[i].list[j].width is not None: outputWidthMSB = ast.description.definitions[0].items[i].list[j].width.msb.value outputWidthLSB = ast.description.definitions[0].items[i].list[j].width.lsb.value if verbose: print( "Decl: TargetModule-Output: " + outputName + "[" + outputWidthMSB + ":" + outputWidthLSB + "]") topModuleOutputs.append((outputPortDirection, '!top-port', outputName + "[" + outputWidthMSB + ":" + outputWidthLSB + "]", "vector")) else: if verbose: print("Decl: TargetModule-Input: " + outputName) topModuleOutputs.append((outputPortDirection, '!top-port', outputName, "singular")) # If wires are found elif ("Wire" or "WireArray") in str(ast.description.definitions[0].items[i].list): wireName = ast.description.definitions[0].items[i].list[j].name # To catch if wire is a vector if ast.description.definitions[0].items[i].list[j].width is not None: wireWidthMSB = ast.description.definitions[0].items[i].list[j].width.msb.value wireWidthLSB = ast.description.definitions[0].items[i].list[j].width.lsb.value topModuleWires.append((wireName + "[" + wireWidthMSB + ":" + wireWidthLSB + "]", "vector")) else: topModuleWires.append((wireName, "singular")) else: print("Unknown pyverilog ast decl object: %s" % (str(ast.description.definitions[0].items[i]))) sys.exit(2) # If the next list position is not a Decl the data gets stored in the codeComponent-object # This is necessary or else the "last" data part would be lost if "InstanceList" in str(ast.description.definitions[0].items[(i + 1)]): componentData.addComponent((str(ast.description.definitions[0].name), "topmodule"), targetFileName, topModuleOutputs + topModuleInputs, topModuleWires) # The "InstanceList" contains all the declared modules of the top module elif "InstanceList" in str(ast.description.definitions[0].items[i]): if verbose: print("InstanceList") moduleType = (ast.description.definitions[0].items[i].instances[0].module, "gate") moduleName = ast.description.definitions[0].items[i].instances[0].name modulePorts = [] if verbose: print("Instance: Type: %s, Name: %s" % (moduleType, moduleName)) for m in range(0, ast.description.definitions[0].items[i].instances[0].portlist.__len__()): modulePortName = ast.description.definitions[0].items[i].instances[0].portlist[m].portname # If it is a pointer port, special preperations are needed to save it adequate if "Pointer" in str(ast.description.definitions[0].items[i].instances[0].portlist[m].argname): modulePortArgName = ast.description.definitions[0].items[i].instances[0].portlist[ m].argname.var.name modulePortArgPointer = ast.description.definitions[0].items[i].instances[0].portlist[ m].argname.ptr.value modulePortArg = modulePortArgName + "[" + modulePortArgPointer + "]" portType = "pointer" # If it is a normal port... else: modulePortArg = ast.description.definitions[0].items[i].instances[0].portlist[m].argname.name portType = "singular" modulePorts.append((None, modulePortName, modulePortArg, portType)) componentData.addComponent(moduleType, moduleName, modulePorts, None) else: print("getTargetComponentList: Unknown pyverilog ast object: %s" % ( str(ast.description.definitions[0].items[i]))) # sys.exit(2) return componentData
def getReferenceComponentList(targetModuleComponents, gateLibraryFile): # This function will store all the used gates in a file to be able to # find out about the direction of the ports of the gates """Searching for gate names and returns them as a list""" def getGateNames(targetModuleComponents): foundGates = [] for i in range(0, targetModuleComponents.getModuleListLength()): if verbose: print(targetModuleComponents.getModuleTypeOnIndex(i)) if (targetModuleComponents.getModuleTypeOnIndex(i)[0] not in foundGates) and ( targetModuleComponents.getModuleTypeOnIndex(i)[1] != "topmodule"): foundGates.append(targetModuleComponents.getModuleTypeOnIndex(i)[0]) return foundGates # Checking which gates are needed from the gateLibraryFile/which gates appear in the targetFile relevantGates = getGateNames(targetModuleComponents) def getMinimumGateCode(gate, gateLibraryFile): codeLines = [] workFile = open(gateLibraryFile, 'r') continueRead = False skipLines = False whiteList = ('module', 'endmodule', 'input', 'output') for num, line in enumerate(workFile, 1): if ("module " + gate) in line: if verbose: print(gate) print('found at line:', num) continueRead = True # Ignore specify/endspecify in the library file if continueRead: if any(s in line for s in whiteList): skipLines = False else: skipLines = True if continueRead and not skipLines: codeLines.append(line) if "endmodule" in line: continueRead = False workFile.close() return codeLines def getGateCode(gate, gateLibraryFile): codeLines = [] workFile = open(gateLibraryFile, 'r') continueRead = False for num, line in enumerate(workFile, 1): if ("module " + gate) in line: if verbose: print(gate) print('found at line:', num) continueRead = True if continueRead: codeLines.append(line) if "endmodule" in line: continueRead = False workFile.close() return codeLines # Temporary file to store date, will be deleted afterwards tmp_fileName = "___tmp_" + str(random.randint(a=0, b=999)) tmp_gateFile = open(tmp_fileName, "w+") global CREATE_SIM_GATE_LIBRARY # Additional file creation for gates if CREATE_SIM_GATE_LIBRARY: simGateLibraryName = targetModuleComponents.moduleList[0].type[0] + '_simGateLibrary.v' # Hardcoded topModule name simGateLibraryFile = open(simGateLibraryName, 'w+') # This loop writes the used gates into file which gets parsed by pyverilog for gatename in relevantGates: if verbose: print(gatename) gateMinimumCode = getMinimumGateCode(gatename, gateLibraryFile) if CREATE_SIM_GATE_LIBRARY: simGateCode = getGateCode(gatename, gateLibraryFile) for line in range(0, len(gateMinimumCode)): if verbose: print(gateMinimumCode[line]) tmp_gateFile.write(gateMinimumCode[line]) tmp_gateFile.write("\n") # Writing additional gate code file if CREATE_SIM_GATE_LIBRARY: for line in range(0, len(simGateCode)): if verbose: print(simGateCode[line]) simGateLibraryFile.write(simGateCode[line]) simGateLibraryFile.write('\n') tmp_gateFile.close() # Closing additional gate code file if CREATE_SIM_GATE_LIBRARY: simGateLibraryFile.close() fileList = [tmp_fileName] # Parsing by Pyverilog ast, directives = parse(fileList) # Deleting tmp file os.remove(tmp_fileName) # Creating a new object, to store gate data libraryData = codeComponents() # Transfering gate data into new object libraryData for i in range(0, ast.description.definitions.__len__()): if "ModuleDef" in str(ast.description.definitions[i]): gateType = (ast.description.definitions[i].name, 'gate') gatePorts = [] for j in range(0, ast.description.definitions[i].items.__len__()): for k in range(0, ast.description.definitions[i].items[j].list.__len__()): if "Output" in str(ast.description.definitions[i].items[j].list[k]): gatePortDirection = "Output" gatePortName = ast.description.definitions[i].items[j].list[k].name gatePortArg = None elif "Input" in str(ast.description.definitions[i].items[j].list[k]): gatePortDirection = "Input" gatePortName = ast.description.definitions[i].items[j].list[k].name gatePortArg = None else: print("Unknown port configuration found in gate library: ", str(str(ast.description.definitions[i].items[j].list[k]))) sys.exit(3) gatePorts.append((gatePortDirection, gatePortName, gatePortArg)) libraryData.addComponent(gateType, "Gate", gatePorts, None) # Transfering Data Back return libraryData