예제 #1
0
class HdlParser:
    reserved = [
        'CHIP', 'IN', 'OUT', 'PARTS', 'BUILTIN', 'CLOCKED'
    ]   
    
    tokens = [
        'COMMA', 'NAME', 'COMMENT1', 'COMMENT2', 'SEMICOLON', 'OCURLEYBRACKET', 
        'CCURLEYBRACKET', 'COLON', 'OBRACKET', 'CBRACKET', 'EQUALS', 'BIT_WIDTH'
     ] + reserved

    #literals = ['=']

    t_ignore = " \t"
    t_COMMA = r','
    t_COLON = r':'
    t_SEMICOLON = r';'
    t_OCURLEYBRACKET = r'{'
    t_CCURLEYBRACKET = r'}'
    t_OBRACKET = r'\('
    t_CBRACKET = r'\)'
    t_EQUALS = r'='
    t_BIT_WIDTH = r'\[(.*?)\]'

    def __init__(self):
        self.logger  = Logger()
        self.hdlChip = HdlChip()
        self.lexer   = lex.lex(module=self)
        self.parser  = yacc.yacc(module=self)      
        return

    def t_NAME(self, t):
        r'[a-zA-Z_][a-zA-Z_0-9_]*'
        if t.value in self.reserved:
            t.type = t.value
        return t

    def t_error(self, t):
        print(f"Illegal character {t.value[0]!r}")
        t.lexer.skip(1)

    def t_newline(self, t):
        r'\n+'
        t.lexer.lineno += len(t.value)

    def t_COMMENT1(self, t):
        r'(/\*(.|\n)*?\*/\n)'
        t.lexer.lineno += len(t.value.split("\n")) - 1
        #return t
        pass

    def t_COMMENT2(self, t):
        r'(//.*?(\n|$))'
        t.lexer.lineno += 1
        #return t
        pass

# statement-list:

    def p_program(self, p):
        '''program : chip
                   | empty
                   '''
        p[0] = p[1]
        return

    # The empty production
    def p_empty(self, p):
        'empty :'
        p[0] = None #Node("EMPTY", [])
        return

    def p_statement(self, p):
        '''statement : in_list
                     | out_list
                     | clocked_list
                     | parts
                     '''
        p[0] = p[1]
        return

    def p_partparam(self, p):
        '''partparam : pin EQUALS pin'''
        p[0] = HdlConnection(p[1], p[3])
        return

    def p_partparamlist(self, p):
        '''partparamlist : partparamlist COMMA partparam
                         | partparam'''

        if len(p) > 2:
            p[0] = p[1]
            p[0].append(p[3])
        else:
            p[0] = [p[1]]
        return

    def p_part(self, p):
        '''part : NAME OBRACKET partparamlist CBRACKET SEMICOLON'''
        hdlChipPart = HdlChipPart(p[1], p.lineno(1))
        for part in p[3]:
            hdlChipPart.AddConnection(part)

        p[0] = hdlChipPart
        return

    def p_partlist(self, p):
        '''partlist : partlist part
                    | part'''        

        if len(p) > 2:
            p[0] = p[1]
            p[0].append(p[2])
        else:
            p[0] = [p[1]]
        return

    def p_parts(self, p):
        '''parts : PARTS COLON partlist'''
        for part in p[3]:
            self.hdlChip.AddPart(part)
        return

    def p_statement_list(self, p):
        '''statement_list : statement_list statement
                          | statement'''        
        
        if len(p) > 2:
            p[0] = p[1]
            p[0].append(p[2])
        else:
            p[0] = [p[1]]
        return

    def p_chip(self, p):
        '''chip : CHIP NAME OCURLEYBRACKET statement_list CCURLEYBRACKET'''
        self.hdlChip.SetChipName(p[2])
        return

    def p_pin(self, p):
        '''pin : NAME BIT_WIDTH
               | NAME'''
        pinName     = p[1]
        pinBitWidth = None
        if len(p) > 2:
            pinBitWidth = p[2]

        if pinBitWidth:
            p[0] = HdlPin(pinName, bitWidthString=pinBitWidth)
        else:
            p[0] = HdlPin(pinName)
        return

    def p_pinlist(self, p):
        '''pinlist : pinlist COMMA pin
                   | pin'''

        if len(p) > 2:
            p[0] = p[1]
            p[0].append(p[3])
        else:
            p[0] = [p[1]]
        return

    def p_in_list(self, p):
        '''in_list : IN pinlist SEMICOLON'''
        self.hdlChip.AddInputPins(p[2])
        return

    def p_clocked_list(self, p):
        '''clocked_list : CLOCKED pinlist SEMICOLON'''
        self.hdlChip.AddClockedPins(p[2])
        return

    def p_out_list(self, p):
        '''out_list : OUT pinlist SEMICOLON'''
        self.hdlChip.AddOutputPins(p[2])
        return

    # def p_comment1(self, p):
    #     "comment1 : COMMENT1"
    #     pass

    # def p_comment2(self, p):
    #     "comment2 : COMMENT2"
    #     pass

    def p_error(self, p):
        if p:
            error_msg = "syntax error '%s' at %d" % (p.value, p.lineno)
        else:
            error_msg = "syntax error at end of file"

        self.logger.Error(error_msg)
        return

    ##########################################################################
    def Parse(self, fileContent):
        self.lexer.input(fileContent)

        # for token in self.lexer:
        #     print(token)

        self.parser.parse(fileContent, tracking=True)
        self.hdlChip.DumpChipDetails()
        return self.hdlChip
예제 #2
0
class HdlToVerilogParamMapper():
    def __init__(self, chipName, partName, lineNo, toPort : VerilogPort, fromPort : VerilogPort):
        self.chipName       = chipName
        self.partName       = partName 
        self.lineNo         = lineNo
        self.toPort         = toPort
        self.fromPort       = fromPort
        self.logger         = Logger()
        self.hdlConnections = [] #type: list[HdlConnection]
        self.mappedParams   = H2VMappedParamsList()
        return

    ##########################################################################
    def AddHdlConnection(self, connection : HdlConnection):
        self.hdlConnections.append(connection)
        return

    ##########################################################################
    def DoMapping(self):
        pin1, pin2   = self.hdlConnections[0].GetPins()
        pin1BitWidth = pin1.GetPinBitWidth()

        self.logger.Info("Start: Chip: %s, part: %s (line %d), pin: %s" % (self.chipName, self.partName, self.lineNo, pin1.pinName))
        for connection in self.hdlConnections:
            pin1, pin2 = connection.GetPins() # type: HdlPin, HdlPin

            self.logger.Info("Mapping: %s" % (connection.GetPinStr()))

            # Note: Cases todo..
            # all bits   <-- input all bits (different bit length)

            pin1BitIndex, pin1StartBitOfBus, pin1EndBitOfBus, pin1ConnectionWidth, pin1ConnectionType = connection.GetPin1Params()
            pin2BitIndex, pin2StartBitOfBus, pin2EndBitOfBus, pin2ConnectionWidth, pin2ConnectionType = connection.GetPin2Params()

            paramFullName = self._MakeParamFullName(pin2.pinName,
                                                    pin2BitIndex,
                                                    pin2StartBitOfBus,
                                                    pin2EndBitOfBus,
                                                    pin2ConnectionWidth,
                                                    True if pin1.pinType == HdlPinTypes.Input else False)

            # Cases:
            # all bits   <-- input all bits (same bit length)
            # all bits   <-- input single bit
            # all bits   <-- input bit range
            # all bits   <-- internal all bits
            if pin1ConnectionType == HdlConnectionTypes.AllBits:
                if pin1BitWidth != pin2ConnectionWidth:
                    self.logger.Error("Mapping all input bits of '%s' to '%s' but bit sizes differ. (Pin size: %d, connection size: %d)" %
                                        (pin1.pinName, pin2.pinName, pin1BitWidth, pin2ConnectionWidth))
                self.mappedParams.AddItem(0, pin1BitWidth - 1, pin1BitWidth, paramFullName)

            # Cases:
            # bit range  <-- input single bit
            elif (pin1ConnectionType == HdlConnectionTypes.BitRange and 
                  pin2ConnectionType == HdlConnectionTypes.SingleBit):
                for hdlBitNumber in range(connection.pin1StartBitOfBus, connection.pin1EndBitOfBus):
                    self.mappedParams.AddItem(hdlBitNumber, hdlBitNumber, pin1BitWidth, paramFullName)

            # Cases:
            # bit range  <-- input all bits
            # bit range  <-- internal all bits
            elif (pin1ConnectionType == HdlConnectionTypes.BitRange and 
                  pin2ConnectionType == HdlConnectionTypes.AllBits):
                self.mappedParams.AddItem(pin1StartBitOfBus, pin1EndBitOfBus, pin1BitWidth, paramFullName)

            # Cases:
            # bit range  <-- input bit range
            elif (pin1ConnectionType == HdlConnectionTypes.BitRange and 
                  pin2ConnectionType == HdlConnectionTypes.BitRange):
                self.mappedParams.AddItem(pin1StartBitOfBus, pin1EndBitOfBus, pin1BitWidth, paramFullName)

            # Cases:
            # single bit <-- input all bits     
            # single bit <-- input single bit 
            # single bit <-- internal all bits
            else:
                self.mappedParams.AddItem(connection.pin1BitIndex, connection.pin1BitIndex, pin1BitWidth, paramFullName)

        self.mappedParams.CompleteMapping(pin1, pin2, pin1BitWidth)
        
        self.logger.Info("End: Mapping chip: %s, part:%s (line %d), pin: %s" % (self.chipName, self.partName, self.lineNo, pin1.pinName))
        return

    ##########################################################################
    def GetMappedParams(self):
        return self.mappedParams
    
    ##########################################################################
    def _MakeParamFullName(self, pinName, pinBitIndex, pinStartBitOfBus, pinEndBitOfBus, pinConnectionWidth, isInputPin):
        paramName  = pinName
        paramExtra = ""

        # If the pin is an Input then swap false to 1'b0
        if isInputPin and pinName == 'false':
            paramName = ("%d'b%s" % (pinConnectionWidth, '0'.join(['0' * pinConnectionWidth])))

        # If the pin is an Input then swap true to 1'b1
        if isInputPin and pinName == 'true':
            paramName = ("%d'b%s" % (pinConnectionWidth, '1'.join(['1' * pinConnectionWidth])))

        if pinBitIndex != commonDefs.NO_BIT_VALUE:
            paramExtra += "[" + str(pinBitIndex) + "]"
        elif pinStartBitOfBus != commonDefs.NO_BIT_VALUE:
            paramExtra += "[" + str(pinEndBitOfBus) + ":"  + str(pinStartBitOfBus) +  "]"

        return ("%s%s" % (paramName, paramExtra))
class TstParser:
    reserved = [
        'set', 'output', 'list', 'eval', 'load', 'compare', 'to', 'file',
        'tick', 'tock'
    ]

    tokens = [
        'NAME', 'NUMBER', 'COMMA', 'DOT', 'DASH', 'COMMENT1', 'COMMENT2',
        'SEMICOLON', 'PERCENT'
    ] + reserved

    #literals = ['%']

    t_ignore = " \t"
    t_COMMA = r','
    t_DOT = r'\.'
    t_DASH = r'-'
    t_SEMICOLON = r';'
    t_PERCENT = r'%'

    def __init__(self):
        self.logger = Logger()
        self.lexer = lex.lex(module=self)
        self.parser = yacc.yacc(module=self)
        self.tstScript = TstScript()
        return

    def t_NAME(self, t):
        r'[a-zA-Z_][a-zA-Z_0-9_]*'
        if t.value in self.reserved:
            t.type = t.value
        return t

    def t_NUMBER(self, t):
        r'\d+'
        t.value = int(t.value)
        return t

    def t_error(self, t):
        print(f"Illegal character {t.value[0]!r}")
        t.lexer.skip(1)

    def t_newline(self, t):
        r'\n+'
        t.lexer.lineno += len(t.value)

    def t_COMMENT1(self, t):
        r'(/\*(.|\n)*?\*/\n)'
        t.lexer.lineno += len(t.value.split("\n")) - 1
        #return t
        pass

    def t_COMMENT2(self, t):
        r'(//.*?(\n|$))'
        t.lexer.lineno += 1
        #return t
        pass

# statement-list:

    def p_test(self, p):
        '''test  : statement_list
                 | empty
                 '''
        p[0] = p[1]
        return

    # The empty production
    def p_empty(self, p):
        'empty :'
        p[0] = None  #Node("EMPTY", [])
        return

    def p_statement_list(self, p):
        '''statement_list : statement_list statement
                          | statement'''

        if len(p) > 2:
            p[0] = p[1]
            p[0].append(p[2])
        else:
            p[0] = [p[1]]
        return

    def p_statement(self, p):
        '''statement : set_sequence 
                     | output_statement
                     | load_statement
                     | compare_statement
                     '''
        p[0] = p[1]
        #print("Statement: " + str(p[1]))
        return

    def p_load_statement(self, p):
        '''load_statement : load NAME DOT NAME COMMA'''
        self.tstScript.testHdlModule = p[2]
        return

    def p_compare_statement(self, p):
        '''compare_statement : compare DASH to NAME DOT NAME COMMA
                             | compare DASH to NAME DASH NAME DOT NAME COMMA'''
        if len(p) > 8:
            self.tstScript.compareFile = ("%s-%s.%s" % (p[4], p[6], p[8]))
        else:
            self.tstScript.compareFile = ("%s.%s" % (p[4], p[6]))
        return

    def p_eval_statement(self, p):
        '''eval_statement : eval COMMA'''
        p[0] = TstSetSequence(TstSetSequenceTypes.eval, None)
        return

    def p_tock_statement(self, p):
        '''tock_statement : tock COMMA'''
        p[0] = TstSetSequence(TstSetSequenceTypes.tock, None)
        return

    def p_tick_statement(self, p):
        '''tick_statement : tick COMMA'''
        p[0] = TstSetSequence(TstSetSequenceTypes.tick, None)
        return

    def p_set_sequence(self, p):
        '''set_sequence : set_statement
                        | tick_statement 
                        | tock_statement
                        | eval_statement
                        | output COMMA
                        | output SEMICOLON
                        '''
        if type(p[1]) == str:
            p[1] = TstSetSequence(TstSetSequenceTypes.output, None)

        #print("set_sequence: %s, len = %d" % (p[1], len(p)))
        self.tstScript.AddSetSequence(p[1])
        return

    def p_set_statement(self, p):
        '''set_statement : set NAME NUMBER COMMA
                         | set NAME DASH NUMBER COMMA
                         | set NAME PERCENT NAME COMMA
                         | set NAME PERCENT NAME SEMICOLON  
                         | set load NUMBER COMMA
                         | set load DASH NUMBER COMMA
                         | set load PERCENT NAME COMMA
                         | set load PERCENT NAME SEMICOLON 
                         '''
        pinValue = ""
        pinName = p[2]
        if len(p) > 5:
            pinValue += ("%s%s" % (p[3], p[4]))
        else:
            pinValue += str(p[3])

        p[0] = TstSetSequence(TstSetSequenceTypes.set,
                              TstSetOperation(pinName, pinValue))
        #print("set_statement: %s = %s" % (pinName, pinValue))
        return

    def p_output_statement(self, p):
        '''output_statement : output_file
                            | output_list
                            '''
        p[0] = p[1]
        #print("set_statement: " + str(p[3]))
        return

    def p_output_file(self, p):
        '''output_file : output DASH file NAME DOT NAME COMMA
                       | output DASH file NAME DASH NAME DOT NAME COMMA'''
        if len(p) > 8:
            self.tstScript.outputFile = ("%s-%s.%s" % (p[4], p[6], p[8]))
        else:
            self.tstScript.outputFile = ("%s.%s" % (p[4], p[6]))
        return

    def p_output_list(self, p):
        '''output_list : output DASH list output_param_list SEMICOLON'''
        self.tstScript.SetOutputFormatList(p[4])
        #print("output_list: " + str(p[4]))
        return

    def p_output_param_list(self, p):
        '''output_param_list : output_param_list output_param
                             | output_param    
                             '''

        if len(p) > 2:
            p[0] = p[1]
            p[0].append(p[2])
        else:
            p[0] = [p[1]]
        return

    def p_output_param(self, p):
        # a%B1.16.1
        '''output_param : NAME PERCENT NAME DOT NUMBER DOT NUMBER
                        | load PERCENT NAME DOT NUMBER DOT NUMBER
                        '''
        #p[0] = ("%s%s%s%s%s%s%s" % (p[1], p[2], p[3], p[4], p[5], p[6], p[7]))
        p[0] = TstOutputParam(p[1], p[3], p[5], p[7])
        return

    def p_error(self, p):
        if p:
            error_msg = "syntax error '%s' at %d" % (p.value, p.lineno)
        else:
            error_msg = "syntax error at end of file"

        self.logger.Error(error_msg)
        return

    ##########################################################################
    def GetSequenceType(self, typeName):
        sequenceType = TstSetSequenceTypes.eval
        for seqType in TstSetSequenceTypes:
            if typeName.casefold() == str(seqType).casefold():
                sequenceType = seqType
        return sequenceType

    ##########################################################################
    def Parse(self, fileContent, testName):
        self.lexer.input(fileContent)

        # for token in self.lexer:
        #     print(token)

        self.tstScript.testName = testName
        self.parser.parse(fileContent)
        self.tstScript.DumpTestDetails()
        return self.tstScript
예제 #4
0
class Hdl2verilogMain():
    def __init__(self):
        self.logger = Logger()
        self.fileActions = FileActions()
        self.mapper = HdlToVerilogMapper()
        return

    ##########################################################################
    def Run(self, inputFolder, builtInChipFolder, outputFolder):
        verilogModuleList = VerilogModuleList(builtInChipFolder)
        # Read in the built-in Verilog modules
        verilogFilenames = [
            join(builtInChipFolder, x)
            for x in self.fileActions.GetFilesWithExtInFolder(
                builtInChipFolder, '.v')
        ]
        for verilogFilename in verilogFilenames:
            self.logger.Info("Reading %s .." % (verilogFilename))
            verilogFile = VerilogFile(verilogFilename)
            verilogModule = verilogFile.ParseFile()
            verilogModuleList.AddBuiltInModule(verilogModule)

        hdlChipList = HdlChipList()
        # Read in the built-in HDL chips
        hdlFilenames = [
            join(builtInChipFolder, x)
            for x in self.fileActions.GetFilesWithExtInFolder(
                builtInChipFolder, '.hdl')
        ]
        for hdlFilename in hdlFilenames:
            self.logger.Info("Reading %s .." % (hdlFilename))
            hdlFile = HdlFile(hdlFilename)
            hdlChip = hdlFile.ParseFile()
            hdlChipList.AddBuiltInChip(hdlChip)

        # Read in the input HDL chips to be converted
        hdlFilenames = [
            join(inputFolder, x)
            for x in self.fileActions.GetFilesWithExtInFolder(
                inputFolder, '.hdl')
        ]
        for hdlFilename in hdlFilenames:
            self.logger.Info("Reading %s .." % (hdlFilename))
            hdlFile = HdlFile(hdlFilename)
            hdlChip = hdlFile.ParseFile()
            hdlChipList.AddChip(hdlChip)

        result, builtInChipsUsedList = self.CheckChipDependencies(
            hdlChipList, verilogModuleList)
        if not result:
            return

        hdlChipList.CheckAndAddClockInputs()
        hdlChipList.UpdateAllPinBitWidths()
        hdlChipList.UpdateAllPartConnections()

        # Create the Verilog Modules from input HDL chips
        for hdlChip in hdlChipList.chipList:
            self.mapper.CreateVerilogModule(hdlChip, hdlChipList,
                                            verilogModuleList)

        # Read-in the Tst files and create the Verilog Testbench Modules
        tstsToRun = []
        tstFilenames = self.fileActions.GetFilesWithExtInFolder(
            inputFolder, '.tst')
        for tstFilename in tstFilenames:
            testName, ext = self.fileActions.GetFileNameAndExt(tstFilename)
            self.logger.Info("Reading %s .." % (tstFilename))
            tstFile = TstFile(join(inputFolder, tstFilename))
            tstScript = tstFile.ParseFile(testName)

            tstScript.testChip = hdlChipList.GetChip(tstScript.testHdlModule)
            self.mapper.CreateVerilogModuleTB(tstScript, outputFolder)
            tstsToRun.append(tstScript)

        verilogModuleList.WriteModules(outputFolder)
        verilogModuleList.CopyInternalModules(outputFolder,
                                              builtInChipsUsedList)

        ivlScriptGen = IVerilogScriptGenerator(outputFolder)
        ivlScriptGen.CreateScript(inputFolder, tstsToRun, hdlChipList,
                                  verilogModuleList)
        return

    ##########################################################################
    def CheckChipDependencies(self, hdlChipList, verilogModuleList):
        passed = True
        missingChipList, builtInChipsUsedList, noimplementationChipList = hdlChipList.CheckChipDependencies(
        )

        if len(missingChipList) > 0:
            self.logger.Error(
                "Missing chips detected! Following dependencies were not found in the input folder or built-in chip folder: %s"
                % (missingChipList))
            passed = False

        if len(builtInChipsUsedList) > 0:
            missingBuiltInModuleList = verilogModuleList.CheckModulesInBuiltInList(
                builtInChipsUsedList)

            if len(missingBuiltInModuleList) > 0:
                self.logger.Error(
                    "Missing built-in verilog modules detected! Following expected built-in modules were not found in the built-in chip folder: %s"
                    % (missingBuiltInModuleList))
                passed = False

        if len(noimplementationChipList) > 0:
            self.logger.Error(
                "Some HDL chips are missing implementation! Please check the following HDL chips run and pass tests using the nand2tetris HardwareSimulator : %s"
                % (noimplementationChipList))
            passed = False

        return passed, builtInChipsUsedList
class FileActions:
    def __init__(self):
        self.logger = Logger()

    ##########################################################################
    # IsFile
    ##########################################################################
    def IsFile(self, fileName):
        my_file = Path(fileName)
        return my_file.is_file()

    ##########################################################################
    # IsExecutable
    ##########################################################################
    def IsExecutable(self, fileName):
        return os.access(fileName, os.X_OK)

    ##########################################################################
    # Rename
    ##########################################################################
    def Rename(self, srcFolder, dstFolder):
        os.rename(srcFolder, dstFolder)

    ##########################################################################
    # MoveFolder
    ##########################################################################
    def MoveFolder(self, srcFolder, dstFolder):
        shutil.move(srcFolder, dstFolder)
        # Unlike os calls which are blocking we have to wait until rmtree
        # completes. We do this by waiting until the folder no longer exists.
        while os.path.exists(srcFolder):  # check if it exists
            pass

    @staticmethod
    ##########################################################################
    # GetFileNameAndExt
    ##########################################################################
    def GetFileNameAndExt(fileName):
        return os.path.splitext(fileName)

    ##########################################################################
    # GetAbsoluteFilename
    ##########################################################################
    def GetAbsoluteFilename(self, relativeFilename):
        return os.path.abspath(relativeFilename)

    ##########################################################################
    # CreateFolderIfNeeded
    ##########################################################################
    def CreateFolderIfNeeded(self, folder):
        if not self.DoesFolderExist(folder):
            os.makedirs(folder)

    ##########################################################################
    # DoesFolderExist
    ##########################################################################
    def DoesFolderExist(self, folder):
        return os.path.exists(folder)

    ##########################################################################
    # DoesFileExist
    ##########################################################################
    def DoesFileExist(self, fileName):
        my_file = Path(fileName)
        return my_file.is_file()

    ##########################################################################
    # GetNumFilesInFolder
    ##########################################################################
    def GetNumFilesInFolder(self, folder, ext=None):
        if self.DoesFolderExist(folder) == True:
            files = [f for f in os.scandir(folder) if f.is_file()]
            if ext != None:
                files = [k for k in files if ext in k.name]
            return len(files)
        else:
            return 0

    ##########################################################################
    # DeleteFile
    ##########################################################################
    def DeleteFile(self, fileName):
        if self.DoesFileExist(fileName):
            try:
                my_file = Path(fileName)
                my_file.unlink()
            except Exception as e:
                self.logger.Error(str(e))

    ##########################################################################
    # DeleteFolder
    ##########################################################################
    def DeleteFolder(self, folderName):
        if self.DoesFolderExist(folderName):
            try:
                self.DeleteFilesInFolder(folderName)
                self.RemoveFolder(folderName)
            except Exception as e:
                self.logger.Error(str(e))

    ##########################################################################
    # DeleteFilesInFolder
    ##########################################################################
    def DeleteFilesInFolder(self, folderName):
        if self.DoesFolderExist(folderName) == True:
            for the_file in os.listdir(folderName):
                file_path = os.path.join(folderName, the_file)
                try:
                    if os.path.isfile(file_path):
                        os.unlink(file_path)
                    elif os.path.isdir(file_path):
                        self.RemoveFolder(file_path)
                except Exception as e:
                    self.logger.Error(str(e))

    ##########################################################################
    # RemoveFolder
    ##########################################################################
    def RemoveFolder(self, folderName):
        if self.DoesFolderExist(folderName) == True:
            shutil.rmtree(folderName)
            # Unlike os calls which are blocking we have to wait until rmtree
            # completes. We do this by waiting until the folder no longer exists.
            while os.path.exists(folderName):  # check if it exists
                pass

    ##########################################################################
    # GetFoldersFromEndPath
    ##########################################################################
    def GetFoldersFromEndPath(self, path, numberToRemove):
        name = ""
        head = path
        for i in range(0, numberToRemove):
            head, tail = os.path.split(head)
            name = join(tail, name)

        return name

    ##########################################################################
    # GetFoldersFromEndPathUntil
    ##########################################################################
    def GetFoldersFromEndPathUntil(self, path, nameToStopAt):
        name = ""
        head = path
        tail = ""
        found = True
        while tail != nameToStopAt:
            newhead, tail = os.path.split(head)
            name = join(tail, name)

            if newhead != head:
                head = newhead
            else:
                # This stops an infinite loop if nameToStopAt is not in path
                found = False
                break

        return name[:-1], found

    ##########################################################################
    # CopyFile
    ##########################################################################
    def CopyFile(self, srcFileName, dstFileName):
        copyfile(srcFileName, dstFileName)
        # Unlike os calls which are blocking we have to wait until rmtree
        # completes. We do this by waiting until the folder no longer exists.
        while self.DoesFileExist(dstFileName) != True:  # check if it exists
            pass

    ##########################################################################
    # GetFileDetailsInFolder
    ##########################################################################
    def GetFileDetailsInFolder(self, folder):
        fileDetails = []
        for path, _, files in os.walk(folder):
            for file in files:
                fileDetail = FileDetails(file, path, 0, "", None)

                fileDetail.fileSizeBytes = os.path.getsize(
                    fileDetail.GetAbsoluteFilename())
                fileDetail.md5 = self._md5(fileDetail.GetAbsoluteFilename(),
                                           fileDetail.fileSizeBytes)

                fileDetails.append(fileDetail)

        return fileDetails

    ##########################################################################
    # GetFilesWithExtInFolder
    ##########################################################################
    def GetFilesWithExtInFolder(self, folder, extension):
        files = [f for f in listdir(folder) if os.path.isfile(join(folder, f))]
        files = [k for k in files if extension in k]
        return files

    ##########################################################################
    # GetFileModDate
    ##########################################################################
    def GetFileModDate(self, filename):
        try:
            mtime = os.path.getmtime(filename)
        except OSError:
            # Use 86400 and not 0 so compatible with windows.
            mtime = 86400
        return datetime.fromtimestamp(mtime)

    ##########################################################################
    # IsFileNewerThan
    ##########################################################################
    def IsFileNewerThan(self, filename1, filename2):
        file1 = self.GetFileModDate(filename1)
        file2 = self.GetFileModDate(filename2)
        #print(filename1 + " = " + str(file1))
        #print(filename2 + " = " + str(file2))
        return file1 > file2

    ##########################################################################
    # MakeExecutable
    ##########################################################################
    def MakeExecutable(self, filename):
        st = os.stat(filename)
        os.chmod(filename, st.st_mode | stat.S_IEXEC)
        return

    ##########################################################################
    # Private: _md5
    ##########################################################################
    def _md5(self, fileName, fileSizeBytes):
        hash_md5 = hashlib.md5()
        if fileSizeBytes > 20000000:
            with open(fileName, "rb") as f:
                for chunk in iter(lambda: f.read(4096), b""):
                    hash_md5.update(chunk)
        else:
            with open(fileName, "rb") as f:
                hash_md5 = hashlib.md5(f.read())

        return hash_md5.hexdigest()
예제 #6
0
class VerilogModuleList():
    def __init__(self, builtInChipFolder):
        self.logger = Logger()
        self.moduleList = []  # type: list[VerilogModule]
        self.builtInModuleList = []  # type: list[VerilogModule]
        self.builtInChipFolder = builtInChipFolder
        return

    ##########################################################################
    def AddModule(self, module):
        self.moduleList.append(module)
        return

    ##########################################################################
    def AddBuiltInModule(self, module):
        self.builtInModuleList.append(module)
        return

    ##########################################################################
    def GetFilenamesForModules(self, inputModuleList):
        filenameList = []
        for inputModule in inputModuleList:
            moduleFromList = [
                x for x in self.moduleList if inputModule == x.moduleName
            ]
            moduleFromBuiltInList = [
                x for x in self.builtInModuleList
                if inputModule == x.moduleName
            ]

            if len(moduleFromList) > 0:
                # Generated module was found, so let use that
                filenameList.append(moduleFromList[0].moduleFilename)
            elif len(moduleFromBuiltInList) > 0:
                # Module must be taken from the builtin list
                filenameList.append(moduleFromBuiltInList[0].moduleFilename)
            else:
                self.logger.Error(
                    "Couldn't find module %s in the generated or built-in list"
                    % (inputModule))

        return filenameList

    ##########################################################################
    def CheckModulesInBuiltInList(self, moduleList):
        missingBuiltInModuleList = []
        for module in moduleList:
            result = [
                x for x in self.builtInModuleList if module == x.moduleName
            ]

            if len(result) == 0:
                missingBuiltInModuleList.append(module)

        return missingBuiltInModuleList

    ##########################################################################
    def WriteModules(self, outputFolder):
        verilogModGen = VerilogModuleGenerator(outputFolder)

        for module in self.moduleList:
            verilogModGen.CreateModule(module)

        return

    ##########################################################################
    def CopyInternalModules(self, outputFolder, usedBuiltInModules):
        fileActions = FileActions()

        for moduleName in usedBuiltInModules:
            for verilogModule in self.builtInModuleList:
                if verilogModule.moduleName == moduleName:
                    fileActions.CopyFile(
                        join(self.builtInChipFolder,
                             verilogModule.moduleFilename),
                        join(outputFolder, verilogModule.moduleFilename))
                    break
        return