def check(self, input, ast):
     for node in thinutils.constructs_iter(ast):
         k = iirs.Get_Kind(node)
         if k not in [
                 iirs.Iir_Kind.Architecture_Body,
                 iirs.Iir_Kind.Block_Statement,
                 iirs.Iir_Kind.Entity_Declaration,
                 iirs.Iir_Kind.Generate_Statement_Body,
                 iirs.Iir_Kind.Process_Statement,
                 iirs.Iir_Kind.Sensitized_Process_Statement,
                 iirs.Iir_Kind.Procedure_Body, iirs.Iir_Kind.Function_Body
         ]:
             continue
         beg_loc = elocations.Get_Begin_Location(node)
         end_loc = elocations.Get_End_Location(node)
         if beg_loc == thin.No_Location or end_loc == thin.No_Location:
             continue
         beg_file, beg_line, beg_col = Location_To_File_Line_Col(beg_loc)
         end_file, end_line, end_col = Location_To_File_Line_Col(end_loc)
         if end_col != beg_col:
             self.error(
                 Location.from_location(end_loc),
                 "'begin' and 'end' must be aligned on the same column")
         if k in iirs.Iir_Kinds.Subprogram_Body:
             if iirs.Get_Declaration_Chain(node) != thin.Null_Iir:
                 is_loc = elocations.Get_Is_Location(node)
                 is_file, is_ln, is_col = Location_To_File_Line_Col(is_loc)
                 if is_col != beg_col:
                     self.error(
                         Location.from_location(is_loc),
                         "'is' and 'begin' must be on the same column")
Example #2
0
 def check_name(self, node, name):
     orig_name = name
     if len(name) > 2 and name[-2] == '_' and name[-1] in 'oib':
         name = name[:-2]
     if name.endswith('_n'):
         name = name[:-2]
     if name.endswith('_a'):
         name = name[:-2]
     while True:
         if name.endswith('_p'):
             name = name[:-2]
         elif name.endswith('_d'):
             name = name[:-2]
         elif (len(name) > 3 and name[-3] == '_' and name[-2] == 'd'
               and name[-1].isdigit()):
             name = name[:-3]
         else:
             break
     if name.endswith('_n'):
         self.error(
             Location.from_node(node),
             "'_n' suffix of signal '{}' is too early".format(orig_name))
     if name.endswith('_a'):
         self.error(
             Location.from_node(node),
             "'_a' suffix of signal '{}' is too early".format(orig_name))
Example #3
0
 def check_assocs(self, n, inters, assocs):
     if assocs == thin.Null_Iir:
         # Also cover the case of no interfaces
         return
     inter = inters
     for assoc in thinutils.chain_iter(assocs):
         if iirs.Get_Kind(assoc) \
            == iirs.Iir_Kind.Association_Element_By_Individual:
             continue
         formal = iirs.Get_Formal(assoc)
         if formal == thin.Null_Iir:
             self.error(
                 Location.from_node(assoc),
                 "association by position for {}".format(
                     nodeutils.get_identifier_str(inter)))
             # Should the tool report all errors ?
             return
         assoc_inter = thin.Iirs_Utils.Get_Interface_Of_Formal(formal)
         while assoc_inter != inter:
             if inter == thin.Null_Iir:
                 self.error(
                     Location.from_node(assoc),
                     "incorrect association order for {}".format(
                         nodeutils.get_identifier_str(assoc_inter)))
                 return
             inter = iirs.Get_Chain(inter)
         if iirs.Get_Whole_Association_Flag(assoc):
             inter = iirs.Get_Chain(inter)
Example #4
0
 def check(self, input, dsgn):
     if self._standard_ids is None:
         self._standard_ids = self.gather_identifiers(
             thin.Standard_Package.value)
     pkgs = nodeutils.extract_packages_from_context_clause(dsgn)
     for pkg in pkgs:
         lib = iirs.Get_Library(
             iirs.Get_Design_File(iirs.Get_Design_Unit(pkg)))
         if iirs.Get_Identifier(lib) == std_names.Name.Ieee \
            and pkg not in self._ieee_pkgs:
             self._ieee_pkgs.append(pkg)
             self._ieee_ids = self._ieee_ids.union(
                 self.gather_identifiers(pkg))
     lu = iirs.Get_Library_Unit(dsgn)
     for d in thinutils.declarations_iter(lu):
         id = iirs.Get_Identifier(d)
         if id in self._standard_ids:
             self.error(
                 Location.from_node(d),
                 "declaration of {} uses a standard name".format(
                     nodeutils.get_identifier_str(d)))
         if id in self._ieee_ids:
             self.error(
                 Location.from_node(d),
                 "declaration of {} uses an ieee name".format(
                     nodeutils.get_identifier_str(d)))
Example #5
0
 def check(self, input, ast):
     assert iirs.Get_Kind(ast) == iirs.Iir_Kind.Design_File
     units = thinutils.chain_to_list(iirs.Get_First_Design_Unit(ast))
     pattern = ''
     letter = {iirs.Iir_Kind.Entity_Declaration: 'E',
               iirs.Iir_Kind.Architecture_Body: 'A',
               iirs.Iir_Kind.Configuration_Declaration: 'C',
               iirs.Iir_Kind.Package_Declaration: 'P',
               iirs.Iir_Kind.Package_Body: 'B'}
     pattern = ''.join([letter[iirs.Get_Kind(iirs.Get_Library_Unit(u))]
                        for u in units])
     if pattern not in self.patterns:
         self.error(Location(input.filename),
                    "sequence of units not allowed")
     if len(units) <= 1:
         # Always ok to have one unit. Zero unit is not allowed by vhdl.
         return
     first = iirs.Get_Library_Unit(units[0])
     if iirs.Get_Kind(first) == iirs.Iir_Kind.Entity_Declaration:
         self.check_entity(units)
     elif iirs.Get_Kind(first) == iirs.Iir_Kind.Package_Declaration:
         self.check_package(units)
     else:
         self.error(Location.from_node(first),
                    "first unit must be either an entity or a package")
Example #6
0
 def check_entity(self, units):
     ent = iirs.Get_Library_Unit(units[0])
     assert iirs.Get_Kind(ent) == iirs.Iir_Kind.Entity_Declaration
     arch = iirs.Get_Library_Unit(units[1])
     if iirs.Get_Kind(arch) != iirs.Iir_Kind.Architecture_Body:
         self.error(Location.from_node(arch),
                    "second unit of a file must be an architecture")
         return
     arch_ent = iirs.Get_Entity_Name(arch)
     if iirs.Get_Kind(arch_ent) != iirs.Iir_Kind.Simple_Name:
         # Strictly speaking, a selected name is allowed.
         self.error(Location.from_node(arch_ent),
                    "weird entity name in architecture")
         return
     if iirs.Get_Identifier(arch_ent) != iirs.Get_Identifier(ent):
         self.error(Location.from_node(arch_ent),
                    "unrelated architecture after entity")
         return
     if len(units) == 2:
         return
     conf = iirs.Get_Library_Unit(units[2])
     if iirs.Get_Kind(conf) != iirs.Iir_Kind.Configuration_Declaration:
         self.error(Location.from_node(arch),
                    "third unit must be a configuration")
     # TODO: check it is related to the architecture
     if len(units) > 3:
         self.error(Location.from_node(units[3]),
                    "too many units in a file")
 def extract_use(self, n):
     if iirs.Get_Use_Clause_Chain(n):
         self.error(Location.from_node(n),
                    "there must be an one package per use")
     name = iirs.Get_Selected_Name(n)
     if iirs.Get_Kind(name) != iirs.Iir_Kind.Selected_By_All_Name:
         self.error(Location.from_node(n),
                    "missing .all after package name")
         return []
     prefix = iirs.Get_Prefix(name)
     if iirs.Get_Kind(prefix) != iirs.Iir_Kind.Selected_Name:
         self.error(Location.from_node(n),
                    "use-d name must be a selected name")
         return []
     lib_prefix = iirs.Get_Prefix(prefix)
     if iirs.Get_Kind(lib_prefix) != iirs.Iir_Kind.Simple_Name:
         self.error(Location.from_node(n),
                    "use-d prefix name must be a simple name")
         return []
     loc = iirs.Get_Location(n)
     _, ln, _ = utils.Location_To_File_Line_Col(loc)
     return [{'kind': 'use',
              'node': n,
              'name': iirs.Get_Identifier(prefix),
              'library': iirs.Get_Identifier(lib_prefix),
              'line': ln}]
Example #8
0
 def check_register(self, proc, clk, rst):
     slist = iirs.Get_Sensitivity_List(proc)
     if not self.in_sensitivity(slist, clk):
         self.error(Location.from_node(proc),
                    "clock not in sensitivity list")
     if thin.Lists.Get_Nbr_Elements(slist) != 1:
         self.error(Location.from_node(proc),
                    "too many signals in sensitivity list")
Example #9
0
 def check(self, input, node):
     k = iirs.Get_Kind(node)
     if k == iirs.Iir_Kind.Group_Declaration:
         self.error(Location.from_node(node),
                    "group declaration not allowed")
     elif k == iirs.Iir_Kind.Group_Template_Declaration:
         self.error(Location.from_node(node),
                    "group template declaration not allowed")
Example #10
0
 def check(self, input, node):
     if nodeutils.is_generic(node):
         s = nodeutils.get_identifier_str(node)
         if not s.startswith("g_"):
             self.error(Location.from_node(node),
                        "generic '{0}' must start with 'g_'".format(s))
         if not s[2:].isupper():
             self.error(
                 Location.from_node(node),
                 "generic '{0}' must be in upper case after 'g_'".format(s))
 def check_entity(self, ent):
     decl = iirs.Get_Declaration_Chain(ent)
     if decl != thin.Null_Iir:
         self.error(Location.from_node(decl),
                    "declaration not allowed in entity")
     first_stmt = iirs.Get_Concurrent_Statement_Chain(ent)
     for s in thinutils.chain_iter(first_stmt):
         k = iirs.Get_Kind(s)
         if k != iirs.Iir_Kind.Concurrent_Assertion_Statement:
             self.error(Location.from_node(s),
                        "concurrent statement not allowed in entity")
Example #12
0
 def check(self, input, node):
     if nodeutils.is_port(node):
         mode = iirs.Get_Mode(node)
         if mode == iirs.Iir_Mode.Buffer_Mode:
             self.error(
                 Location.from_node(node),
                 "buffer port '{0}' not allowed".format(
                     nodeutils.get_identifier_str(node)))
         elif mode == iirs.Iir_Mode.Linkage_Mode:
             self.error(
                 Location.from_node(node),
                 "linkage port '{0}' not allowed".format(
                     nodeutils.get_identifier_str(node)))
Example #13
0
 def check(self, input, node):
     if iirs.Get_Kind(node) == iirs.Iir_Kind.Block_Statement:
         hdr = iirs.Get_Block_Header(node)
         if hdr != thin.Null_Iir:
             if iirs.Get_Generic_Chain(hdr) != thin.Null_Iir:
                 self.error(Location.from_node(node),
                            "block cannot declare generics")
             if iirs.Get_Port_Chain(hdr) != thin.Null_Iir:
                 self.error(Location.from_node(node),
                            "block cannot declare ports")
         if iirs.Get_Guard_Decl(node) != thin.Null_Iir:
             self.error(Location.from_node(node),
                        "block cannot have an implicit GUARD signal")
Example #14
0
 def check_predicate(self, p, node, s):
     """Test predicate :param p: on string :param s:.  The predicate shall
      return an error message in case of error or None if the name is
      correct."""
     res = p(s)
     if isinstance(res, str):
         self.error(Location.from_node(node), res)
         return True
     elif res is None or res:
         return False
     else:
         self.error(Location.from_node(node),
                    "incorrect name '{}'".format(s))
         return True
Example #15
0
 def check_package(self, units):
     decl = iirs.Get_Library_Unit(units[0])
     assert iirs.Get_Kind(decl) == iirs.Iir_Kind.Package_Declaration
     bod = iirs.Get_Library_Unit(units[1])
     if iirs.Get_Kind(bod) != iirs.Iir_Kind.Package_Body:
         self.error(Location.from_node(bod),
                    "second unit of a file must be a package body")
         return
     if iirs.Get_Identifier(bod) != iirs.Get_Identifier(decl):
         self.error(Location.from_node(bod),
                    "unrelated package body after package declaration")
         return
     if len(units) > 2:
         self.error(Location.from_node(units[2]),
                    "too many units in a file")
Example #16
0
 def check(self, input, node):
     if iirs.Get_Kind(node) == iirs.Iir_Kind.Use_Clause:
         parent = iirs.Get_Parent(node)
         if iirs.Get_Kind(parent) != iirs.Iir_Kind.Design_Unit:
             self.error(
                 Location.from_node(node),
                 "use clause must be global (placed before the unit)")
Example #17
0
 def report_unused(self, unit):
     for n in thinutils.declarations_iter(unit):
         if n in self._used \
            or nodeutils.is_predefined_node(n):
             # Node is used (or not user defined)
             continue
         k = iirs.Get_Kind(n)
         if k in [iirs.Iir_Kind.Function_Body,
                  iirs.Iir_Kind.Procedure_Body]:
             # Bodies are never referenced.
             continue
         if self.is_second_subprogram(n):
             # Subprogram specification of a body is never referenced.
             continue
         if k in iirs.Iir_Kinds.Interface_Object_Declaration:
             p = iirs.Get_Parent(n)
             if p != thin.Null_Iir \
                and self.is_second_subprogram(p):
                 # Interfaces without parent are from implicit subprograms.
                 # Interfaces of the subprg spec of the body aren't
                 # referenced.
                 continue
         if k in [iirs.Iir_Kind.Anonymous_Type_Declaration]:
             # Anonymous types are never referenced.
             continue
         if k == iirs.Iir_Kind.Iterator_Declaration \
            and thin.Get_Name_Length(iirs.Get_Identifier(n)) == 1:
             # Loop iterator with a very short name (for i in ...)
             # Allow it to be unused.
             continue
         self.error(
             Location.from_node(n),
             "{} is not used".format(
                 nodeutils.get_identifier_str(n)))
    def check_declarations(self, decl):
        decl_col = -1
        colon_col = -1
        subtype_col = -1
        assign_col = -1
        line = -1
        while decl != thin.Null_Iir:
            loc = elocations.Get_Start_Location(decl)
            fe, ln, co = utils.Location_To_File_Line_Col(loc)
            if ln <= line:
                self.error(Location.from_node(decl),
                           "one generic/port per line")
            else:
                if co != decl_col and decl_col >= 0:
                    self.error(Location.from_node(decl),
                               "name is not aligned with previous one")

                # Check alignment of ':'
                colon_loc = elocations.Get_Colon_Location(decl)
                _, ln1, colon_co = utils.Location_To_File_Line_Col(colon_loc)
                if colon_co != colon_col and colon_col >= 0:
                    self.error(Location.from_node(decl),
                               "':' is not aligned with previous one")
                colon_col = colon_co

                # Check alignment of subtype.
                st = iirs.Get_Subtype_Indication(decl)
                if st != thin.Null_Iir:
                    st_loc = thinutils.leftest_location(st)
                    _, ln1, st_co = utils.Location_To_File_Line_Col(st_loc)
                    if st_co != subtype_col and subtype_col >= 0:
                        self.error(Location.from_node(decl),
                                   "subtype is not aligned with previous one")
                    subtype_col = st_co

                # Check alignment of ':='
                assign_loc = elocations.Get_Assign_Location(decl)
                if assign_loc != thin.No_Location:
                    _, ln1, assign_co = \
                        utils.Location_To_File_Line_Col(assign_loc)
                    if assign_co != assign_col and assign_col >= 0:
                        self.error(Location.from_node(decl),
                                   "':=' is not aligned with previous one")
                    assign_col = assign_co
            decl_col = co
            line = ln
            decl = iirs.Get_Chain(decl)
 def check(self, input, node):
     if iirs.Get_Kind(node) == iirs.Iir_Kind.Attribute_Declaration:
         s = nodeutils.get_identifier_str(node)
         if string.lower(s) not in self.allowed:
             self.error(
                 Location.from_node(node),
                 "user attribute declaration for '{0}' not allowed".format(
                     s))
 def extract_library(self, n):
     name = iirs.Get_Identifier(n)
     if iirs.Get_Has_Identifier_List(n):
         self.error(Location.from_node(n),
                    "library must be alone")
     if name == std_names.Name.Std:
         self.error(Location.from_node(n),
                    "do not use library clause for 'std'")
     elif name == std_names.Name.Work:
         self.error(Location.from_node(n),
                    "do not use library clause for 'work'")
     loc = iirs.Get_Location(n)
     _, ln, _ = utils.Location_To_File_Line_Col(loc)
     return [{'kind': 'library',
              'node': n,
              'name': name,
              'line': ln}]
Example #21
0
 def check(self, input, node):
     if iirs.Get_Kind(node) == iirs.Iir_Kind.Enumeration_Literal:
         s = nodeutils.get_identifier_str(node)
         if not s.isupper():
             self.error(
                 Location.from_node(node),
                 "enumeration literal '{0}' must be in upper case".format(
                     s))
Example #22
0
 def check(self, input, node):
     k = iirs.Get_Kind(node)
     if k == iirs.Iir_Kind.Signal_Declaration \
        or k == iirs.Iir_Kind.Interface_Signal_Declaration:
         if iirs.Get_Guarded_Signal_Flag(node):
             self.error(
                 Location.from_node(node),
                 "signal '{0}' must not be guarded".format(
                     nodeutils.get_identifier_str(node)))
 def check_clause(self, cl):
     name = iirs.Get_Selected_Name(cl)
     if iirs.Get_Kind(name) == iirs.Iir_Kind.Selected_By_All_Name:
         name = iirs.Get_Prefix(name)
     if iirs.Get_Kind(name) != iirs.Iir_Kind.Selected_Name:
         self.error(Location.from_node(name), "unhandled use clause form")
         return
     lib = iirs.Get_Prefix(name)
     if iirs.Get_Kind(lib) != iirs.Iir_Kind.Simple_Name:
         self.error(Location.from_node(name), "unhandled use clause form")
         return
     if iirs.Get_Identifier(lib) != std_names.Name.Ieee:
         # User package ?
         return
     if iirs.Get_Identifier(name) not in self._allowed_id:
         self.error(
             Location.from_node(name),
             "non-allowed use of IEEE package {}".format(
                 nodeutils.get_identifier_str(name)))
Example #24
0
 def check(self, input, unit):
     for n in thinutils.concurrent_stmts_iter(unit):
         k = iirs.Get_Kind(n)
         if k == iirs.Iir_Kind.Process_Statement:
             self.error(Location.from_node(n),
                        "non-sentized process not allowed in synth unit")
         elif k == iirs.Iir_Kind.Sensitized_Process_Statement:
             self.check_process(n)
         else:
             # Check for non-postponed ?
             pass
Example #25
0
 def check(self, input, ast):
     if 'top' not in input.props:
         return
     unit = iirs.Get_Library_Unit(ast)
     if iirs.Get_Kind(unit) != iirs.Iir_Kind.Entity_Declaration:
         return
     for port in thinutils.chain_iter(iirs.Get_Port_Chain(unit)):
         if not self.check_type(iirs.Get_Type(port)):
             self.error(
                 Location.from_node(port),
                 "type of port '{0}' must be std_logic/_vector".format(
                     nodeutils.get_identifier_str(port)))
 def check(self, input, ast):
     for node in thinutils.concurrent_stmts_iter(ast):
         if iirs.Get_Kind(node) not in iirs.Iir_Kinds.Process_Statement:
             continue
         if iirs.Get_Label(node) != thin.Null_Identifier:
             continue
         loc = iirs.Get_Location(node)
         fil = thin.Location_To_File(loc)
         line = thin.Location_File_To_Line(loc, fil)
         if input.comments.get(line - 1, None) is None:
             self.error(
                 Location.from_node(node),
                 "missing label or comment for process")
Example #27
0
 def check(self, input, node):
     if nodeutils.is_port(node):
         s = nodeutils.get_identifier_str(node)
         mode = iirs.Get_Mode(node)
         if mode == iirs.Iir_Mode.Out_Mode:
             if not s.endswith('_o'):
                 self.error(Location.from_node(node),
                            "out port '{0}' must end with '_o'".format(s))
         elif mode == iirs.Iir_Mode.In_Mode:
             if not s.endswith('_i'):
                 self.error(Location.from_node(node),
                            "in port '{0}' must end with '_i'".format(s))
         elif mode == iirs.Iir_Mode.Inout_Mode:
             if not s.endswith('_b'):
                 self.error(Location.from_node(node),
                            "inout port '{0}' must end with '_b'".format(s))
         elif mode == iirs.Iir_Mode.Buffer_Mode:
             self.error(Location.from_node(node),
                        "buffer port '{0}' not allowed".format(s))
         elif mode == iirs.Iir_Mode.Linkage_Mode:
             self.error(Location.from_node(node),
                        "linkage port '{0}' not allowed".format(s))
Example #28
0
 def check_parenthesis(self, expr):
     if expr == thin.Null_Iir:
         # For else clause.
         return
     if iirs.Get_Kind(expr) != iirs.Iir_Kind.Parenthesis_Expression:
         return
     left_loc = iirs.Get_Location(expr)
     right_loc = elocations.Get_Right_Paren_Location(expr)
     fe = thin.Location_To_File(left_loc)
     assert fe == thin.Location_To_File(right_loc)
     left_line = thin.Location_File_To_Line(left_loc, fe)
     right_line = thin.Location_File_To_Line(right_loc, fe)
     if left_line != right_line:
         # Assume that's for grouping
         return
     self.error(Location.from_node(expr),
                "useless parenthesis around expression")
 def check(self, input, ast):
     for du in thinutils.chain_iter(iirs.Get_First_Design_Unit(ast)):
         ent = iirs.Get_Library_Unit(du)
         if iirs.Get_Kind(ent) != iirs.Iir_Kind.Entity_Declaration:
             continue
         gen = iirs.Get_Generic_Chain(ent)
         if gen != thin.Null_Iir:
             self.check_declarations(gen)
         ports = iirs.Get_Port_Chain(ent)
         if ports != thin.Null_Iir:
             self.check_declarations(ports)
             port = ports
             while port != thin.Null_Iir:
                 if not iirs.Get_Has_Mode(port):
                     self.error(Location.from_node(port),
                                "in/out/inout required for port")
                 port = iirs.Get_Chain(port)
Example #30
0
 def check_process(self, proc):
     stmt = iirs.Get_Sequential_Statement_Chain(proc)
     if nodeutils.is_one_stmt(stmt) \
        and iirs.Get_Kind(stmt) == iirs.Iir_Kind.If_Statement:
         (clk, rst) = self.is_register(stmt)
         if clk is not None:
             self.check_register(proc, clk, rst)
             return
     slist = iirs.Get_Sensitivity_List(proc)
     clist = thin.Lists.Create_Iir_List()
     thin.Canon.Extract_Sequential_Statement_Chain_Sensitivity(
         iirs.Get_Sequential_Statement_Chain(proc), clist)
     for el in thinutils.list_iter(clist):
         if not self.in_sensitivity(slist, el):
             self.error(Location.from_node(el),
                        "signal not in sensitivity list")
     thin.Lists.Destroy_Iir_List(clist)