Esempio n. 1
0
def lookup_function(view, funcname):
    fi = None
    filelist = view.window().lookup_symbol_in_index(funcname)
    # print('Files for {0} = {1}'.format(funcname,filelist))
    if filelist:
        # Check if function is defined in current file first
        fname = view.file_name()
        flist_norm = [sublimeutil.normalize_fname(f[0]) for f in filelist]
        if fname in flist_norm:
            _, _, rowcol = filelist[flist_norm.index(fname)]
            with open(fname, 'r') as f:
                flines = str(f.read())
            flines = verilogutil.clean_comment(flines)
            fi = verilogutil.parse_function(flines, funcname)
        if fi:
            fi['fname'] = (fname, rowcol[0], rowcol[1])
        # Consider first file with a valid function definition to be the correct one
        else:
            for f in filelist:
                fname, display_fname, rowcol = f
                fname_ = sublimeutil.normalize_fname(fname)
                with open(fname_, 'r') as f:
                    flines = str(f.read())
                flines = verilogutil.clean_comment(flines)
                fi = verilogutil.parse_function(flines, funcname)
                if fi:
                    # rowcols = [x for fn,_,x in filelist if fn==fname_]
                    fi['fname'] = (fname_, rowcol[0], rowcol[1])
                    break
    return fi
Esempio n. 2
0
 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")
Esempio n. 3
0
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
Esempio n. 4
0
 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")