Example #1
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 #2
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")
Example #3
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 #4
0
def concurrent_stmts_iter(n):
    """Iterator on concurrent statements in n."""
    k = iirs.Get_Kind(n)
    if k == iirs.Iir_Kind.Design_File:
        for n1 in chain_iter(iirs.Get_First_Design_Unit(n)):
            for n2 in concurrent_stmts_iter(n1):
                yield n2
    elif k == iirs.Iir_Kind.Design_Unit:
        for n1 in concurrent_stmts_iter(iirs.Get_Library_Unit(n)):
            yield n1
    elif k == iirs.Iir_Kind.Entity_Declaration \
         or k == iirs.Iir_Kind.Architecture_Body \
         or k == iirs.Iir_Kind.Block_Statement:
        for n1 in chain_iter(iirs.Get_Concurrent_Statement_Chain(n)):
            yield n1
            for n2 in concurrent_stmts_iter(n1):
                yield n2
    elif k == iirs.Iir_Kind.For_Generate_Statement:
        for n1 in concurrent_stmts_iter(iirs.Get_Generate_Statement_Body(n)):
            yield n1
    elif k == iirs.Iir_Kind.If_Generate_Statement:
        while n != Null_Iir:
            for n1 in concurrent_stmts_iter(
                    iirs.Get_Generate_Statement_Body(n)):
                yield n1
            n = iirs.Get_Generate_Else_Clause(n)
    elif k == iirs.Iir_Kind.Case_Generate_Statement:
        alt = iirs.Get_Case_Statement_Alternative_Chain(n)
        for n1 in chain_iter(alt):
            blk = iirs.Get_Associated_Block(n1)
            if blk != Null_Iir:
                for n2 in concurrent_stmts_iter(
                        iirs.Get_Generate_Statement_Body(n)):
                    yield n2
Example #5
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 #6
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)))
Example #7
0
 def check(self, input, unit):
     libunit = iirs.Get_Library_Unit(unit)
     k = iirs.Get_Kind(libunit)
     if k == iirs.Iir_Kind.Architecture_Body:
         self._used = set()
         ent = thin.Iirs_Utils.Get_Entity(libunit)
         self.mark(ent)
         self.mark(libunit)
         self.report_unused(ent)
         self.report_unused(libunit)
     elif k == iirs.Iir_Kind.Package_Body:
         self._used = set()
         self.mark(libunit)
         self.report_unused(libunit)
 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 #9
0
 def check(self, input, ast):
     # Build the list of use'd packages.
     pkgs = []
     for n in thinutils.chain_iter(iirs.Get_Context_Items(ast)):
         if iirs.Get_Kind(n) != iirs.Iir_Kind.Use_Clause:
             continue
         cl = n
         while cl != thin.Null_Iir:
             name = iirs.Get_Selected_Name(cl)
             if iirs.Get_Kind(name) == iirs.Iir_Kind.Selected_By_All_Name:
                 name = iirs.Get_Prefix(name)
             p = iirs.Get_Named_Entity(name)
             if iirs.Get_Kind(p) == iirs.Iir_Kind.Package_Declaration:
                 pkgs.append(p)
             cl = iirs.Get_Use_Clause_Chain(cl)
     # Check dependences
     for du in thinutils.list_iter(iirs.Get_Dependence_List(ast)):
         lu = iirs.Get_Library_Unit(du)
         if iirs.Get_Kind(lu) == iirs.Iir_Kind.Package_Declaration:
             if lu != thin.Standard_Package.value and lu not in pkgs:
                 self.error(
                     Location.from_node(ast),
                     "unit depends on '{}' but not by a use clause".format(
                         nodeutils.get_identifier_str(lu)))
Example #10
0
def constructs_iter(n):
    """Iterator on library unit, concurrent statements and declarations
       that appear directly within a declarative part."""
    if n == thin.Null_Iir:
        return
    k = iirs.Get_Kind(n)
    if k == iirs.Iir_Kind.Design_File:
        for n1 in chain_iter(iirs.Get_First_Design_Unit(n)):
            for n2 in constructs_iter(n1):
                yield n2
    elif k == iirs.Iir_Kind.Design_Unit:
        n1 = iirs.Get_Library_Unit(n)
        yield n1
        for n2 in constructs_iter(n1):
            yield n2
    elif k in [
            iirs.Iir_Kind.Entity_Declaration, iirs.Iir_Kind.Architecture_Body,
            iirs.Iir_Kind.Block_Statement,
            iirs.Iir_Kind.Generate_Statement_Body
    ]:
        for n1 in chain_iter(iirs.Get_Declaration_Chain(n)):
            yield n1
            for n2 in constructs_iter(n1):
                yield n2
        for n1 in chain_iter(iirs.Get_Concurrent_Statement_Chain(n)):
            yield n1
            for n2 in constructs_iter(n1):
                yield n2
    elif k in [
            iirs.Iir_Kind.Configuration_Declaration,
            iirs.Iir_Kind.Package_Declaration, iirs.Iir_Kind.Package_Body,
            iirs.Iir_Kind.Function_Body, iirs.Iir_Kind.Procedure_Body,
            iirs.Iir_Kind.Protected_Type_Declaration,
            iirs.Iir_Kind.Protected_Type_Body, iirs.Iir_Kind.Process_Statement,
            iirs.Iir_Kind.Sensitized_Process_Statement
    ]:
        for n1 in chain_iter(iirs.Get_Declaration_Chain(n)):
            yield n1
            for n2 in constructs_iter(n1):
                yield n2
    elif k == iirs.Iir_Kind.For_Generate_Statement:
        n1 = iirs.Get_Generate_Statement_Body(n)
        yield n1
        for n2 in constructs_iter(n1):
            yield n2
    elif k == iirs.Iir_Kind.If_Generate_Statement:
        while n != Null_Iir:
            n1 = iirs.Get_Generate_Statement_Body(n)
            yield n1
            for n2 in constructs_iter(n1):
                yield n2
            n = iirs.Get_Generate_Else_Clause(n)
    elif k == iirs.Iir_Kind.Case_Generate_Statement:
        alt = iirs.Get_Case_Statement_Alternative_Chain(n)
        for n1 in chain_iter(alt):
            blk = iirs.Get_Associated_Block(n1)
            if blk != Null_Iir:
                n2 = iirs.Get_Generate_Statement_Body(blk)
                yield n2
                for n3 in constructs_iter(n2):
                    yield n3
Example #11
0
 def check(self, input, ast):
     assert iirs.Get_Kind(ast) == iirs.Iir_Kind.Design_File
     for u in thinutils.chain_iter(iirs.Get_First_Design_Unit(ast)):
         self.chk_context_clauses(u, 1)
         lib_unit = iirs.Get_Library_Unit(u)
         self.chk_library_unit(lib_unit, 1)
 def check(self, input, ast):
     assert iirs.Get_Kind(ast) == iirs.Iir_Kind.Design_File
     for u in thinutils.chain_iter(iirs.Get_First_Design_Unit(ast)):
         lu = iirs.Get_Library_Unit(u)
         if iirs.Get_Kind(lu) == iirs.Iir_Kind.Entity_Declaration:
             self.check_entity(lu)
Example #13
0
    def execute(self, files):
        inputs = []
        props = ['synth']
        # First file
        for filename in files:
            if filename.startswith('--'):
                # Handle properties
                if filename == '--import':
                    props = ['import']
                elif filename == '--synth':
                    props = ['synth']
                elif filename == '--top':
                    props = ['synth', 'top']
                elif filename == '--tb':
                    props = ['tb']
                else:
                    fatal("unknown property '{0}'".format(filename))
                continue

            # Read the file
            fid = thin.Get_Identifier(filename.encode('utf-8'))
            fe = thin.Read_Source_File(0, fid)
            if fe == thin.No_Source_File_Entry:
                fatal('cannot open {0}'.format(filename))

            fbuf = thin.Get_File_Buffer(fe)
            flen = thin.Get_File_Length(fe)

            # Not very efficient (it copies the string), but let's use it
            # for now.
            filebuf = ctypes.string_at(fbuf, flen)

            input = RuleInput(filename, fe)
            input.filebuf = filebuf
            input.props = props
            inputs.append(input)

            if 'import' not in input.props:
                self._nbr_files += 1

                # Again, not very efficient (creates the substrings).
                flines = filebuf.splitlines(True)

                loc = Location(filename)
                for r in self._file_rules:
                    r.check(loc, flines)

        # Then tokens
        thin.Scanner.Flag_Comment.value = True
        for input in inputs:
            if 'import' not in input.props:
                thin.Scanner.Set_File(input.fe)
                filebuf = input.filebuf
                while True:
                    thin.Scanner.Scan()
                    tok = thin.Scanner.Current_Token.value
                    loc = TokLocation(input.filename,
                                      thin.Scanner.Get_Current_Line(),
                                      thin.Scanner.Get_Token_Column(),
                                      thin.Scanner.Get_Token_Position(),
                                      thin.Scanner.Get_Position())
                    if tok == tokens.Tok.Comment:
                        input.comments[loc.line] = (loc.start, loc.end)
                    for r in self._lex_rules:
                        r.check(loc, filebuf, tok)
                    if tok == tokens.Tok.Eof:
                        break
                thin.Scanner.Close_File()
        if not (self._syntax_rules or self._syntax_node_rules or
                self._sem_rules or self._sem_node_rules or self._synth_rules):
            return

        # Then syntax
        # The parser doesn't handle comments
        thin.Scanner.Flag_Comment.value = False
        # Keep extra locations
        thin.Flags.Flag_Elocations.value = True
        # Keep all parenthesis
        thin.Parse.Flag_Parse_Parenthesis.value = True
        # Be sure to initialize std and work (and only once).
        # Humm, not very elegant.
        if thin.Get_Libraries_Chain() == thin.Null_Iir:
            thin.analyze_init()
        for input in inputs:
            thin.Scanner.Set_File(input.fe)
            loc = Location(input.filename)
            input.ast = thin.Parse.Parse_Design_File()
            if 'import' not in input.props:
                for r in self._syntax_rules:
                    r.check(input, input.ast)
                if self._syntax_node_rules:
                    for n in thinutils.nodes_iter(input.ast):
                        for r in self._syntax_node_rules:
                            r.check(loc, n)
            thin.Scanner.Close_File()

        # Then semantic
        if self._sem_rules or self._sem_node_rules or self._synth_rules:
            # Reduce Canon
            thin.Canon.Flag_Concurrent_Stmts.value = False
            thin.Canon.Flag_Configurations.value = False
            thin.Canon.Flag_Associations.value = False
            # First add all units in the work library, so that they they are
            # known by the analyzer.
            for input in inputs:
                unit_ast = iirs.Get_First_Design_Unit(input.ast)
                while unit_ast != thin.Null_Iir:
                    # Detach the unit from its design file
                    next_unit_ast = iirs.Get_Chain(unit_ast)
                    iirs.Set_Chain(unit_ast, thin.Null_Iir)
                    # Add
                    thin.Add_Design_Unit_Into_Library(unit_ast, False)
                    input.units_ast.append(unit_ast)
                    unit_ast = next_unit_ast
            # Handle all unit
            for input in inputs:
                if 'import' not in input.props:
                    for unit in input.units_ast:
                        if iirs.Get_Library_Unit(unit) == thin.Null_Iir:
                            # Over-written.
                            # FIXME: remove from the list ?
                            continue
                        # Be sure the unit was analyzed. It could have been
                        # already analyzed if referenced. And a unit cannot be
                        # analyzed twice.
                        if iirs.Get_Date_State(unit) == iirs.Date_State.Parse:
                            thin.Finish_Compilation(unit, False)
                            iirs.Set_Date_State(unit, iirs.Date_State.Analyze)
                        for r in self._sem_rules:
                            r.check(input, unit)
                        for n in thinutils.nodes_iter(unit):
                            for r in self._sem_node_rules:
                                r.check(input, n)

            for input in inputs:
                if 'synth' in input.props:
                    for unit in input.units_ast:
                        if iirs.Get_Library_Unit(unit) == thin.Null_Iir:
                            # Over-written.
                            continue
                        for r in self._synth_rules:
                            r.check(input, unit)