def parse_verilog(text): '''Parse a text buffer of Verilog code Args: text (str): Source code to parse Returns: List of parsed objects. ''' lex = MiniLexer(verilog_tokens) name = None kind = None saved_type = None mode = 'input' ptype = 'wire' metacomments = [] parameters = [] param_items = [] generics = [] ports = collections.OrderedDict() sections = [] port_param_index = 0 last_item = None array_range_start_pos = 0 objects = [] for pos, action, groups in lex.run(text): logging.debug("##VPARSE: lex yields pos " + str(pos) + " action:" + str(action)) if action == 'metacomment': if last_item is None: metacomments.append(groups[0]) else: last_item.desc = groups[0] if action == 'section_meta': sections.append((port_param_index, groups[0])) elif action == 'module': kind = 'module' name = groups[0] generics = [] ports = collections.OrderedDict() param_items = [] sections = [] port_param_index = 0 elif action == 'parameter_start': net_type, vec_range = groups new_ptype = '' if net_type is not None: new_ptype += net_type if vec_range is not None: new_ptype += ' ' + vec_range ptype = new_ptype elif action == 'param_item': generics.append(VerilogParameter(groups[0], 'in', ptype)) elif action == 'module_port_start': new_mode, net_type, signed, vec_range = groups new_ptype = '' if net_type is not None: new_ptype += net_type if signed is not None: new_ptype += ' ' + signed if vec_range is not None: new_ptype += ' ' + vec_range # Complete pending items for i in param_items: ports[i] = VerilogParameter(i, mode, ptype) param_items = [] if len(ports) > 0: last_item = next(reversed(ports)) # Start with new mode mode = new_mode ptype = new_ptype elif action == 'port_param': ident = groups[0] param_items.append(ident) port_param_index += 1 elif action == 'end_module': # Finish any pending ports for i in param_items: ports[i] = VerilogParameter(i, mode, ptype) vobj = VerilogModule(name, ports.values(), generics, dict(sections), metacomments) objects.append(vobj) last_item = None metacomments = [] return objects
(r'\s*(input|inout|output)\s*(reg|supply0|supply1|tri|triand|trior|tri0|tri1|wire|wand|wor)?\s*(signed)?\s*(\[[^]]+\])?', 'module_port_start'), (r'\s*(\w+)\s*,?', 'port_param'), (r'\s*\`(\w+)\s*,?', None, '#pop'), (r'\s*//\s*(external)\s*?(single-cycle|strobe|we-strobe|plus-we)?.*?\n', 'port_annotation'), (r'[);]', None, '#pop'), (r'//#\s*{{(.*)}}\n', 'section_meta'), (r'//.*\n', None), ], 'block_comment': [ (r'\*/', 'end_comment', '#pop'), ], } VerilogLexer = MiniLexer(verilog_tokens) class VerilogObject(object): '''Base class for parsed Verilog objects''' def __init__(self, name, desc=None): self.name = name self.kind = 'unknown' self.desc = desc class VerilogParameter(object): '''Parameter and port to a module''' def __init__(self, name, mode=None,
(r'/\*', 'block_comment', 'block_comment'), ], 'array_range': [ (r'\(', 'open_paren', 'nested_parens'), (r'\)', 'array_range_end', '#pop'), ], 'nested_parens': [ (r'\(', 'open_paren', 'nested_parens'), (r'\)', 'close_paren', '#pop'), ], 'block_comment': [ (r'\*/', 'end_comment', '#pop'), ], } VhdlLexer = MiniLexer(vhdl_tokens, flags=re.MULTILINE | re.IGNORECASE) class VhdlObject(object): '''Base class for parsed VHDL objects Args: name (str): Name of the object desc (str): Description from object metacomments ''' def __init__(self, name, desc=None): self.name = name self.kind = 'unknown' self.desc = desc