def run(self,edit): if len(self.view.sel())==0 : return; r = self.view.sel()[0] scope = self.view.scope_name(r.a) if 'meta.module.inst' not in scope: return # Select whole module instantiation r = sublimeutil.expand_to_scope(self.view,'meta.module.inst',r) txt = verilogutil.clean_comment(self.view.substr(r)) #Extract existing binding bl = re.findall(r'(?s)\.(\w+)\s*\(\s*(.*?)\s*\)',txt,flags=re.MULTILINE) # if '.*' in txt: # Parse module definition mname = re.findall(r'\w+',txt)[0] filelist = self.view.window().lookup_symbol_in_index(mname) if not filelist: return for f in filelist: fname = sublimeutil.normalize_fname(f[0]) mi = verilogutil.parse_module_file(fname,mname,no_inst=True) if mi: break if not mi: return dot_star = '' b0 = [x[0] for x in bl] for p in mi['port']: if p['name'] not in b0: dot_star += '.' + p['name']+'('+p['name']+'),\n' # select the .* and replace it (exclude the two last character which are ',\n') if dot_star != '' : r_tmp = self.view.find(r'\.\*',r.a) self.view.replace(edit,r_tmp,dot_star[:-2]) else : # case where .* was superfluous (all bindings were manual) : remove .* including the potential , r_tmp = self.view.find(r'\.\*\s*(,)?',r.a) self.view.erase(edit,r_tmp) else: # Find beginning of the binding and insert the .* r_begin = self.view.find(r'(\w+|\))\b\s*\w+\s*\(',r.a) if r.contains(r_begin): cnt = 0 # erase all binding where port and signal have same name for b in bl: if b[0]==b[1]: cnt = cnt + 1 r_tmp = self.view.find(r'\.'+b[0]+r'\s*\(\s*' + b[0] + r'\s*\)\s*(,)?',r.a) if r.contains(r_tmp): self.view.erase(edit,r_tmp) r_tmp = self.view.full_line(r_tmp.a) m = re.search(r'^\s*(\/\/.*)?$',self.view.substr(r_tmp)) if m: self.view.erase(edit,r_tmp) # Insert .* only if something was removed. Add , if not all binding were removed if cnt > 0: if cnt==len(bl): self.view.insert(edit,r_begin.b,'.*') else : self.view.insert(edit,r_begin.b,'.*,') self.view.run_command("verilog_align")
def type_info_on_hier(view, varname, txt=None, region=None): va = varname.split('.') ti = None scope = '' if not txt and region: txt = view.substr(sublime.Region(0, view.line(region).b)) for i in range(0, len(va)): v = va[i].split('[')[0] # retrieve name without array part # Get type definition: first iteration is done inside current file if i == 0: if region: scope = view.scope_name(region.a) ti = {'type': None} # If in a function body: check for a definition in the fubction first if 'meta.function.body' in scope: r_func = sublimeutil.expand_to_scope(view, 'meta.function.body', region) ti = type_info(view, view.substr(r_func), varname) # Check in the whole text if not ti['type']: ti = type_info(view, txt, v) #if not found check for a definition in base class if this is an extended class if not ti['type'] and region: bti = type_info_from_base(view, region, ti['name']) if bti: ti = bti elif ti and ti['type']: if ti['type'] == 'module': ti = lookup_module(view, ti['name']) elif ti['type'] == 'clocking': for p in ti['port']: if p['name'] == v: # Suppose we got here through a lookup (TBC if it is always the case) if fname: ti = ti = type_info_file(view, fname, v) else: ti = p['name'] ti['decl'] = '{} logic {}'.format(ti['type'], v) break else: # not found ti = None elif ti['type'] != 'class': # print ('[type_info_on_hier] Looking for type {}'.format(ti)) ti = lookup_type(view, ti['type']) if ti and ti['type']: if ti['tag'] == 'typedef': bti = lookup_type(view, ti['type']) if bti: ti = bti # Lookup for the variable inside the type defined if not ti: return None if ti['type'] == 'struct': m = re.search(r'\{(.*)\}', ti['decl']) til = verilogutil.get_all_type_info(m.groups()[0]) ti = None for e in til: if e['name'] == v: ti = e break elif 'fname' in ti: fname = ti['fname'][0] ti = type_info_file(view, fname, v) if ti['type'] in ['function', 'task']: with open(fname) as f: flines = verilogutil.clean_comment(f.read()) ti = verilogutil.parse_function(flines, v) # print ('[type_info_on_hier] => type info of {0} = {1}'.format(v,ti)) return ti
def run(self, edit): if len(self.view.sel()) == 0: return r = self.view.sel()[0] scope = self.view.scope_name(r.a) if 'meta.module.inst' not in scope: return # Select whole module instantiation r = sublimeutil.expand_to_scope(self.view, 'meta.module.inst', r) if self.view.classify(r.a) & sublime.CLASS_LINE_START == 0: r.a = self.view.find_by_class(r.a, False, sublime.CLASS_LINE_START) # print(self.view.substr(r)) txt = verilogutil.clean_comment(self.view.substr(r)) # Parse module definition mname = re.findall(r'\w+', txt)[0] filelist = self.view.window().lookup_symbol_in_index(mname) if not filelist: return for f in filelist: fname = sublimeutil.normalize_fname(f[0]) mi = verilogutil.parse_module_file(fname, mname, no_inst=True) if mi: break if not mi: sublime.status_message( 'Unable to retrieve module information for ' + mname) return settings = self.view.settings() mpl = [x['name'] for x in mi['port']] mpal = [x['name'] for x in mi['param']] #Extract existing binding bl = re.findall(r'(?s)\.(\w+)\s*\(\s*(.*?)\s*\)\s*(,|\))', txt, flags=re.MULTILINE) # Handle case of binding by position (TODO: support parameter as well ...) if not bl: m = re.search( r'(?s)(#\s*\((?P<params>.*?)\)\s*)?\s*\w+\s*\((?P<ports>.*?)\)\s*;', txt, flags=re.MULTILINE) pl = m.group('ports') if pl: pa = pl.split(',') bt = '' for i, p in enumerate(pa): if i >= len(mpl): break bl.append((mpl[i], p.strip())) bt += '.{portName}({sigName}),\n'.format( portName=bl[-1][0], sigName=bl[-1][1]) # Replace connection by position by connection by name r_tmp = self.view.find(pl, r.a, sublime.LITERAL) if r.contains(r_tmp): self.view.replace(edit, r_tmp, bt) # Update region r = sublimeutil.expand_to_scope(self.view, 'meta.module.inst', r) ipl = [x[0] for x in bl] # Check for added port apl = [x for x in mpl if x not in ipl] if apl: (decl, ac, wc) = VerilogDoModuleInstCommand.get_connect( self, self.view, settings, mi) last_char = self.view.substr(sublime.Region(r.a, r.b - 2)).strip(' \t')[-1] b = '\n' if last_char != '\n' else '' for p in apl: b += "." + p + "(" if p in ac.keys(): b += ac[p] else: b += p b += ")," if p in wc.keys(): b += " // TODO: Check connection ! " + wc[p] b += "\n" # Add binding at the end of the instantiation self.view.insert(edit, r.b - 2, b) # Check for deleted port dpl = [x for x in ipl if x not in mpl and x not in mpal] for p in dpl: r_tmp = self.view.find(r'(?s)\.' + p + r'\s*\(.*?\)\s*(,|\)\s*;)', r.a) if r.contains(r_tmp): s = self.view.substr(r_tmp) if s[-1] == ';': s_tmp = s[:-1].strip()[:-1] r_tmp.b -= (len(s) - len(s_tmp)) self.view.erase(edit, r_tmp) r_tmp = self.view.full_line(r_tmp.a) # cleanup comment m = re.search(r'^\s*(\/\/.*)?$', self.view.substr(r_tmp)) if m: self.view.erase(edit, r_tmp) # Print status # print('[reconnect] Module Port list = ' + str(mpl)) # print('[reconnect] Instance Port list = ' + str(ipl)) # print('[reconnect] => Removed Port list = ' + str(dpl)) # print('[reconnect] => Added Port list = ' + str(apl)) s = '' if dpl: s += "Removed %d ports: %s\n" % (len(dpl), str(dpl)) if apl: s += "Added %d ports: %s\n" % (len(apl), str(apl)) decl_clean = '' ac_clean = {} for p in apl: if p in ac: ac_clean[p] = ac[p] m = re.search(r'^.*\b' + p + r'\b.*;', decl, re.MULTILINE) if m: decl_clean += m.group(0) + '\n' for p in ipl: if p in wc: wc.pop(p) nb_decl = len(decl_clean.splitlines()) if decl_clean: r_start = VerilogDoModuleInstCommand.get_region_decl( self, self.view, settings, r.a) self.view.insert(edit, r_start, '\n' + decl_clean) s += 'Adding ' + str(nb_decl) + ' signal(s) declaration(s)\n' if len(ac_clean) > 0: s += 'Non-perfect name match for ' + str( len(ac_clean)) + ' port(s) : ' + str(ac_clean) + '\n' if len(wc) > 0: s += 'Found ' + str( len(wc)) + ' mismatch(es) for port(s): ' + str( [x for x in wc.keys()]) + '\n' if s: sublimeutil.print_to_panel(s, 'SystemVerilog') # Realign self.view.run_command("verilog_align")