class GitSCM(Executable, ToolMixIn): def __init__(self, toolchain: ToolMixIn): ToolMixIn.__init__(self, toolchain._platform, toolchain._dryrun, toolchain._binaryDirectoryPath, toolchain._version, toolchain._logger) if (self._platform == "Windows"): executablePath = self._binaryDirectoryPath / "git.exe" elif (self._platform == "Linux"): executablePath = self._binaryDirectoryPath / "git" elif (self._platform == "Darwin"): executablePath = self._binaryDirectoryPath / "git" else: raise PlatformNotSupportedException(self._platform) super().__init__(self._platform, self._dryrun, executablePath, logger=self._logger) self.Parameters[self.Executable] = executablePath def Clear(self): for param in self.Parameters: if (param is not self.Executable): self.Parameters[param] = None class Executable(metaclass=ExecutableArgument): pass class Switch_Version(metaclass=LongFlagArgument): _name = "version" Parameters = CommandLineArgumentList(Executable, Switch_Version)
class GitConfig(GitSCM): def Clear(self): super().Clear() for param in self.ConfigParameters: # if isinstance(param, ExecutableArgument): # print("{0}".format(param.Value)) # elif isinstance(param, NamedCommandLineArgument): # print("{0}".format(param.Name)) if (param is not self.Command): # print(" clearing: {0} = {1} to None".format(param.Name, param.Value)) self.ConfigParameters[param] = None class Command(metaclass=CommandArgument): _name = "config" class SwitchUnset(metaclass=LongFlagArgument): _name = "unset" class SwitchRemoveSection(metaclass=LongFlagArgument): _name = "remove-section" class ValueFilterClean(metaclass=ValuedFlagArgument): _name = "clean" _pattern = "filter.{1}.{0}" class ValueFilterSmudge(metaclass=ValuedFlagArgument): _name = "smudge" _pattern = "filter.{1}.{0}" class ValueFilterParameters(metaclass=StringArgument): pass ConfigParameters = CommandLineArgumentList(Command, SwitchUnset, SwitchRemoveSection, ValueFilterClean, ValueFilterSmudge, ValueFilterParameters) def Execute(self): parameterList = self.Parameters.ToArgumentList() parameterList += self.ConfigParameters.ToArgumentList() self.LogVerbose("command: {0}".format(" ".join(parameterList))) if (self._dryrun): self.LogDryRun("Start process: {0}".format( " ".join(parameterList))) return try: self.StartProcess(parameterList) except Exception as ex: raise GitException("Failed to launch Git.") from ex # FIXME: Replace GetReader with a shorter call to e.g. GetLine and/or GetLines output = "" for line in self.GetReader(): output += line return output
class GitRevParse(GitSCM): def Clear(self): super().Clear() for param in self.RevParseParameters: # if isinstance(param, ExecutableArgument): # print("{0}".format(param.Value)) # elif isinstance(param, NamedCommandLineArgument): # print("{0}".format(param.Name)) if (param is not self.Command): # print(" clearing: {0} = {1} to None".format(param.Name, param.Value)) self.RevParseParameters[param] = None class Command(metaclass=CommandArgument): _name = "rev-parse" class SwitchInsideWorkingTree(metaclass=LongFlagArgument): _name = "is-inside-work-tree" class SwitchShowTopLevel(metaclass=LongFlagArgument): _name = "show-toplevel" class SwitchGitDir(metaclass=LongFlagArgument): _name = "git-dir" RevParseParameters = CommandLineArgumentList(Command, SwitchInsideWorkingTree, SwitchShowTopLevel, SwitchGitDir) def Execute(self): parameterList = self.Parameters.ToArgumentList() parameterList += self.RevParseParameters.ToArgumentList() self.LogVerbose("command: {0}".format(" ".join(parameterList))) if (self._dryrun): self.LogDryRun("Start process: {0}".format( " ".join(parameterList))) return try: self.StartProcess(parameterList) except Exception as ex: raise GitException("Failed to launch Git.") from ex # FIXME: Replace GetReader with a shorter call to e.g. GetLine and/or GetLines output = "" for line in self.GetReader(): output += line return output
class GitDescribe(GitSCM): def Clear(self): super().Clear() for param in self.DescribeParameters: # if isinstance(param, ExecutableArgument): # print("{0}".format(param.Value)) # elif isinstance(param, NamedCommandLineArgument): # print("{0}".format(param.Name)) if (param is not self.Command): # print(" clearing: {0} = {1} to None".format(param.Name, param.Value)) self.DescribeParameters[param] = None class Command(metaclass=CommandArgument): _name = "describe" class SwitchAbbrev(metaclass=LongValuedFlagArgument): _name = "abbrev" class SwitchTags(metaclass=LongTupleArgument): _name = "tags" DescribeParameters = CommandLineArgumentList(Command, SwitchAbbrev, SwitchTags) def Execute(self): parameterList = self.Parameters.ToArgumentList() parameterList += self.DescribeParameters.ToArgumentList() self.LogVerbose("command: {0}".format(" ".join(parameterList))) if (self._dryrun): self.LogDryRun("Start process: {0}".format( " ".join(parameterList))) return try: self.StartProcess(parameterList) except Exception as ex: raise GitException("Failed to launch Git.") from ex # FIXME: Replace GetReader with a shorter call to e.g. GetLine and/or GetLines output = "" for line in self.GetReader(): output += line return output
class TclShell(Executable, ToolMixIn): def __init__(self, toolchain : ToolMixIn): ToolMixIn.__init__( self, toolchain._platform, toolchain._dryrun, toolchain._binaryDirectoryPath, toolchain._version, toolchain._logger) if (self._platform == "Windows") : executablePath = self._binaryDirectoryPath / "quartus_sh.exe" elif (self._platform == "Linux") : executablePath = self._binaryDirectoryPath / "quartus_sh" else : raise PlatformNotSupportedException(self._platform) super().__init__(self._platform, self._dryrun, executablePath, logger=self._logger) self.Parameters[self.Executable] = executablePath class Executable(metaclass=ExecutableArgument): pass class SwitchShell(metaclass=ShortFlagArgument): _name = "s" Parameters = CommandLineArgumentList( Executable, SwitchShell )
class CoreGenerator(Executable, ToolMixIn): def __init__(self, toolchain: ToolMixIn): ToolMixIn.__init__(self, toolchain._platform, toolchain._dryrun, toolchain._binaryDirectoryPath, toolchain._version, toolchain._logger) if (self._platform == "Windows"): executablePath = self._binaryDirectoryPath / "coregen.exe" elif (self._platform == "Linux"): executablePath = self._binaryDirectoryPath / "coregen" else: raise PlatformNotSupportedException(self._platform) super().__init__(self._platform, self._dryrun, executablePath, logger=self._logger) self.Parameters[self.Executable] = executablePath self._hasOutput = False self._hasWarnings = False self._hasErrors = False @property def HasWarnings(self): return self._hasWarnings @property def HasErrors(self): return self._hasErrors class Executable(metaclass=ExecutableArgument): pass class FlagRegenerate(metaclass=ShortFlagArgument): _name = "r" class SwitchProjectFile(metaclass=ShortTupleArgument): _name = "p" class SwitchBatchFile(metaclass=ShortTupleArgument): _name = "b" Parameters = CommandLineArgumentList(Executable, FlagRegenerate, SwitchProjectFile, SwitchBatchFile) def Generate(self): parameterList = self.Parameters.ToArgumentList() self.LogVerbose("command: {0}".format(" ".join(parameterList))) if (self._dryrun): self.LogDryRun("Start process: {0}".format( " ".join(parameterList))) return try: self.StartProcess(parameterList) except Exception as ex: raise ISEException("Failed to launch corgen.") from ex self._hasOutput = False self._hasWarnings = False self._hasErrors = False try: iterator = iter(CoreGeneratorFilter(self.GetReader())) line = next(iterator) self._hasOutput = True self.LogNormal(" coregen messages for '{0}'".format( self.Parameters[self.SwitchProjectFile])) self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent * 2))) while True: self._hasWarnings |= (line.Severity is Severity.Warning) self._hasErrors |= (line.Severity is Severity.Error) line.IndentBy(self.Logger.BaseIndent + 1) self.Log(line) line = next(iterator) except StopIteration: pass finally: if self._hasOutput: self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent * 2)))
class ISESimulator(Executable): def __init__(self, platform, dryrun, executablePath, logger=None): super().__init__(platform, dryrun, executablePath, logger=logger) self.Parameters[self.Executable] = executablePath self._hasOutput = False self._hasWarnings = False self._hasErrors = False @property def HasWarnings(self): return self._hasWarnings @property def HasErrors(self): return self._hasErrors class Executable(metaclass=ExecutableArgument): pass class SwitchLogFile(metaclass=ShortTupleArgument): _name = "log" class FlagGuiMode(metaclass=ShortFlagArgument): _name = "gui" class SwitchTclBatchFile(metaclass=ShortTupleArgument): _name = "tclbatch" class SwitchWaveformFile(metaclass=ShortTupleArgument): _name = "view" Parameters = CommandLineArgumentList(Executable, SwitchLogFile, FlagGuiMode, SwitchTclBatchFile, SwitchWaveformFile) def Simulate(self): parameterList = self.Parameters.ToArgumentList() self.LogVerbose("command: {0}".format(" ".join(parameterList))) if (self._dryrun): self.LogDryRun("Start process: {0}".format( " ".join(parameterList))) return try: self.StartProcess(parameterList) except Exception as ex: raise ISEException("Failed to launch isim.") from ex self._hasOutput = False self._hasWarnings = False self._hasErrors = False simulationResult = CallByRefParam(SimulationResult.Error) try: iterator = iter( PoCSimulationResultFilter(SimulatorFilter(self.GetReader()), simulationResult)) line = next(iterator) self._hasOutput = True self.LogNormal(" isim messages for '{0}'".format( self.Parameters[self.Executable])) self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent * 2))) while True: self._hasWarnings |= (line.Severity is Severity.Warning) self._hasErrors |= (line.Severity is Severity.Error) line.IndentBy(self.Logger.BaseIndent + 1) self.Log(line) line = next(iterator) except StopIteration: pass finally: if self._hasOutput: self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent * 2))) return simulationResult.value
class Fuse(Executable, ToolMixIn): def __init__(self, toolchain: ToolMixIn): ToolMixIn.__init__(self, toolchain._platform, toolchain._dryrun, toolchain._binaryDirectoryPath, toolchain._version, toolchain._logger) if (self._platform == "Windows"): executablePath = self._binaryDirectoryPath / "fuse.exe" elif (self._platform == "Linux"): executablePath = self._binaryDirectoryPath / "fuse" else: raise PlatformNotSupportedException(self._platform) super().__init__(self._platform, self._dryrun, executablePath, logger=self._logger) self.Parameters[self.Executable] = executablePath self._hasOutput = False self._hasWarnings = False self._hasErrors = False @property def HasWarnings(self): return self._hasWarnings @property def HasErrors(self): return self._hasErrors class Executable(metaclass=ExecutableArgument): pass class FlagIncremental(metaclass=ShortFlagArgument): _name = "incremental" # FlagIncremental = ShortFlagArgument(_name="incremntal") class FlagRangeCheck(metaclass=ShortFlagArgument): _name = "rangecheck" class SwitchMultiThreading(metaclass=ShortTupleArgument): _name = "mt" class SwitchTimeResolution(metaclass=ShortTupleArgument): _name = "timeprecision_vhdl" class SwitchProjectFile(metaclass=ShortTupleArgument): _name = "prj" class SwitchOutputFile(metaclass=ShortTupleArgument): _name = "o" class ArgTopLevel(metaclass=StringArgument): pass Parameters = CommandLineArgumentList(Executable, FlagIncremental, FlagRangeCheck, SwitchMultiThreading, SwitchTimeResolution, SwitchProjectFile, SwitchOutputFile, ArgTopLevel) def Link(self): parameterList = self.Parameters.ToArgumentList() self.LogVerbose("command: {0}".format(" ".join(parameterList))) if (self._dryrun): self.LogDryRun("Start process: {0}".format( " ".join(parameterList))) return try: self.StartProcess(parameterList) except Exception as ex: raise ISEException("Failed to launch fuse.") from ex self._hasOutput = False self._hasWarnings = False self._hasErrors = False try: iterator = iter(FuseFilter(self.GetReader())) line = next(iterator) self._hasOutput = True self.LogNormal(" fuse messages for '{0}'".format( self.Parameters[self.SwitchProjectFile])) self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent * 2))) while True: self._hasWarnings |= (line.Severity is Severity.Warning) self._hasErrors |= (line.Severity is Severity.Error) line.IndentBy(self.Logger.BaseIndent + 1) self.Log(line) line = next(iterator) except StopIteration: pass finally: if self._hasOutput: self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent * 2)))
class Map(Executable, ToolMixIn): def __init__(self, toolchain : ToolMixIn): ToolMixIn.__init__( self, toolchain._platform, toolchain._dryrun, toolchain._binaryDirectoryPath, toolchain._version, toolchain._logger) if (self._platform == "Windows") : executablePath = self._binaryDirectoryPath / "quartus_map.exe" elif (self._platform == "Linux") : executablePath = self._binaryDirectoryPath / "quartus_map" else : raise PlatformNotSupportedException(self._platform) Executable.__init__(self, self._platform, self._dryrun, executablePath, logger=self._logger) self.Parameters[self.Executable] = executablePath self._hasOutput = False self._hasWarnings = False self._hasErrors = False @property def HasWarnings(self): return self._hasWarnings @property def HasErrors(self): return self._hasErrors class Executable(metaclass=ExecutableArgument) : pass class ArgProjectName(metaclass=StringArgument): pass class SwitchArgumentFile(metaclass=ShortValuedFlagArgument): _name = "f" class SwitchDeviceFamily(metaclass=LongValuedFlagArgument) : _name = "family" class SwitchDevicePart(metaclass=LongValuedFlagArgument) : _name = "part" Parameters = CommandLineArgumentList( Executable, ArgProjectName, SwitchArgumentFile, SwitchDeviceFamily, SwitchDevicePart ) def Compile(self) : parameterList = self.Parameters.ToArgumentList() self.LogVerbose("command: {0}".format(" ".join(parameterList))) if (self._dryrun): self.LogDryRun("Start process: {0}".format(" ".join(parameterList))) return try: self.StartProcess(parameterList) except Exception as ex: raise QuartusException("Failed to launch quartus_map.") from ex self._hasOutput = False self._hasWarnings = False self._hasErrors = False try: iterator = iter(MapFilter(self.GetReader())) line = next(iterator) self._hasOutput = True self.LogNormal(" quartus_map messages for '{0}'".format(self.Parameters[self.SwitchArgumentFile])) self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent*2))) while True: self._hasWarnings |= (line.Severity is Severity.Warning) self._hasErrors |= (line.Severity is Severity.Error) line.IndentBy(self.Logger.BaseIndent + 1) self.Log(line) line = next(iterator) except StopIteration: pass finally: if self._hasOutput: self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent*2)))
class GHDL(Executable, ToolMixIn): def __init__(self, platform, dryrun, binaryDirectoryPath, version, backend, logger=None): ToolMixIn.__init__(self, platform, dryrun, binaryDirectoryPath, version, logger=logger) if (platform == "Windows"): executablePath = binaryDirectoryPath / "ghdl.exe" elif (platform == "Linux"): executablePath = binaryDirectoryPath / "ghdl" elif (platform == "Darwin"): executablePath = binaryDirectoryPath / "ghdl" else: raise PlatformNotSupportedException(platform) super().__init__(platform, dryrun, executablePath, logger=logger) self.Executable = executablePath #self.Parameters[self.Executable] = executablePath if (platform == "Windows"): if (backend not in ["llvm", "mcode"]): raise GHDLException("GHDL for Windows does not support backend '{0}'.".format(backend)) elif (platform == "Linux"): if (backend not in ["gcc", "llvm", "mcode"]): raise GHDLException("GHDL for Linux does not support backend '{0}'.".format(backend)) elif (platform == "Darwin"): if (backend not in ["gcc", "llvm", "mcode"]): raise GHDLException("GHDL for OS X does not support backend '{0}'.".format(backend)) self._binaryDirectoryPath = binaryDirectoryPath self._backend = backend self._version = version self._hasOutput = False self._hasWarnings = False self._hasErrors = False @property def BinaryDirectoryPath(self): return self._binaryDirectoryPath @property def Backend(self): return self._backend @property def Version(self): return self._version @property def HasWarnings(self): return self._hasWarnings @property def HasErrors(self): return self._hasErrors def deco(Arg): def getter(_): return Arg.Value def setter(_, value): Arg.Value = value return property(getter, setter) Executable = deco(ExecutableArgument("Executable", (), {})) #class Executable(metaclass=ExecutableArgument): # pass class CmdAnalyze(metaclass=ShortFlagArgument): _name = "a" class CmdElaborate(metaclass=ShortFlagArgument): _name = "e" class CmdRun(metaclass=ShortFlagArgument): _name = "r" class FlagVerbose(metaclass=ShortFlagArgument): _name = "v" class FlagExplicit(metaclass=ShortFlagArgument): _name = "fexplicit" class FlagRelaxedRules(metaclass=ShortFlagArgument): _name = "frelaxed-rules" class FlagWarnBinding(metaclass=LongFlagArgument): _name = "warn-binding" class FlagNoVitalChecks(metaclass=LongFlagArgument): _name = "no-vital-checks" class FlagMultiByteComments(metaclass=LongFlagArgument): _name = "mb-comments" class FlagSynBinding(metaclass=LongFlagArgument): _name = "syn-binding" class FlagPSL(metaclass=ShortFlagArgument): _name = "fpsl" class SwitchCompilerOption(metaclass=ValuedFlagListArgument): _pattern = "-{0},{1}" _name = "Wc" class SwitchAssemblerOption(metaclass=ValuedFlagListArgument): _pattern = "-{0},{1}" _name = "Wa" class SwitchLinkerOption(metaclass=ValuedFlagListArgument): _pattern = "-{0},{1}" _name = "Wl" class SwitchIEEEFlavor(metaclass=LongValuedFlagArgument): _name = "ieee" class SwitchVHDLVersion(metaclass=LongValuedFlagArgument): _name = "std" class SwitchVHDLLibrary(metaclass=LongValuedFlagArgument): _name = "work" class ArgListLibraryReferences(metaclass=ValuedFlagListArgument): _pattern = "-{0}{1}" _name = "P" class ArgSourceFile(metaclass=PathArgument): pass class ArgTopLevel(metaclass=StringArgument): pass Parameters = CommandLineArgumentList( #Executable, CmdAnalyze, CmdElaborate, CmdRun, FlagVerbose, FlagExplicit, FlagRelaxedRules, FlagWarnBinding, FlagNoVitalChecks, FlagMultiByteComments, FlagSynBinding, FlagPSL, SwitchCompilerOption, SwitchAssemblerOption, SwitchLinkerOption, SwitchIEEEFlavor, SwitchVHDLVersion, SwitchVHDLLibrary, ArgListLibraryReferences, ArgSourceFile, ArgTopLevel ) class SwitchIEEEAsserts(metaclass=LongValuedFlagArgument): _name = "ieee-asserts" class SwitchVCDWaveform(metaclass=LongValuedFlagArgument): _name = "vcd" class SwitchVCDGZWaveform(metaclass=LongValuedFlagArgument): _name = "vcdgz" class SwitchFastWaveform(metaclass=LongValuedFlagArgument): _name = "fst" class SwitchGHDLWaveform(metaclass=LongValuedFlagArgument): _name = "wave" class SwitchWaveformOptionFile(metaclass=LongValuedFlagArgument): _name = "read-wave-opt" # requires GHDL update RunOptions = CommandLineArgumentList( SwitchIEEEAsserts, SwitchVCDWaveform, SwitchVCDGZWaveform, SwitchFastWaveform, SwitchGHDLWaveform, SwitchWaveformOptionFile ) def GetGHDLAnalyze(self): ghdl = GHDLAnalyze(self._platform, self._dryrun, self._binaryDirectoryPath, self._version, self._backend, logger=self._logger) for param in ghdl.Parameters: if (param is not ghdl.Executable): ghdl.Parameters[param] = None ghdl.Parameters[ghdl.CmdAnalyze] = True return ghdl def GetGHDLElaborate(self): ghdl = GHDLElaborate(self._platform, self._dryrun, self._binaryDirectoryPath, self._version, self._backend, logger=self._logger) for param in ghdl.Parameters: if (param is not ghdl.Executable): ghdl.Parameters[param] = None ghdl.Parameters[ghdl.CmdElaborate] = True return ghdl def GetGHDLRun(self): ghdl = GHDLRun(self._platform, self._dryrun, self._binaryDirectoryPath, self._version, self._backend, logger=self._logger) for param in ghdl.Parameters: if (param is not ghdl.Executable): ghdl.Parameters[param] = None ghdl.Parameters[ghdl.CmdRun] = True return ghdl
class XElab(Executable, ToolMixIn): def __init__(self, toolchain: ToolMixIn): ToolMixIn.__init__(self, toolchain._platform, toolchain._dryrun, toolchain._binaryDirectoryPath, toolchain._version, toolchain._logger) if (self._platform == "Windows"): executablePath = self._binaryDirectoryPath / "xelab.bat" elif (self._platform == "Linux"): executablePath = self._binaryDirectoryPath / "xelab" else: raise PlatformNotSupportedException(self._platform) super().__init__(self._platform, self._dryrun, executablePath, logger=self._logger) self.Parameters[self.Executable] = executablePath self._hasOutput = False self._hasWarnings = False self._hasErrors = False @property def HasWarnings(self): return self._hasWarnings @property def HasErrors(self): return self._hasErrors class Executable(metaclass=ExecutableArgument): _value = None class FlagRangeCheck(metaclass=ShortFlagArgument): _name = "rangecheck" _value = None class SwitchMultiThreading(metaclass=ShortTupleArgument): _name = "mt" _value = None class SwitchVerbose(metaclass=ShortTupleArgument): _name = "verbose" _value = None class SwitchDebug(metaclass=ShortTupleArgument): _name = "debug" _value = None # class SwitchVHDL2008(metaclass=ShortFlagArgument): # _name = "vhdl2008" # _value = None class SwitchOptimization(metaclass=ShortValuedFlagArgument): _pattern = "--{0}{1}" _name = "O" _value = None class SwitchTimeResolution(metaclass=ShortTupleArgument): _name = "timeprecision_vhdl" _value = None class SwitchProjectFile(metaclass=ShortTupleArgument): _name = "prj" _value = None class SwitchLogFile(metaclass=ShortTupleArgument): _name = "log" _value = None class SwitchSnapshot(metaclass=ShortTupleArgument): _name = "s" _value = None class ArgTopLevel(metaclass=StringArgument): _value = None Parameters = CommandLineArgumentList( Executable, FlagRangeCheck, SwitchMultiThreading, SwitchTimeResolution, SwitchVerbose, SwitchDebug, # SwitchVHDL2008, SwitchOptimization, SwitchProjectFile, SwitchLogFile, SwitchSnapshot, ArgTopLevel) def Link(self): parameterList = self.Parameters.ToArgumentList() self.LogVerbose("command: {0}".format(" ".join(parameterList))) if (self._dryrun): self.LogDryRun("Start process: {0}".format( " ".join(parameterList))) return try: self.StartProcess(parameterList) except Exception as ex: raise VivadoException("Failed to launch xelab.") from ex self._hasOutput = False self._hasWarnings = False self._hasErrors = False try: iterator = iter(ElaborationFilter(self.GetReader())) line = next(iterator) self._hasOutput = True self.LogNormal(" xelab messages for '{0}'".format( self.Parameters[self.SwitchProjectFile])) self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent * 2))) while True: self._hasWarnings |= (line.Severity is Severity.Warning) self._hasErrors |= (line.Severity is Severity.Error) line.IndentBy(self.Logger.BaseIndent + 1) self.Log(line) line = next(iterator) except StopIteration: pass except VivadoException: raise # except Exception as ex: # raise GHDLException("Error while executing GHDL.") from ex finally: if self._hasOutput: self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent * 2)))
class QuestaSimulator(Executable, ToolMixIn): def __init__(self, toolchain: ToolMixIn): ToolMixIn.__init__(self, toolchain._platform, toolchain._dryrun, toolchain._binaryDirectoryPath, toolchain._version, toolchain._logger) if (self._platform == "Windows"): executablePath = self._binaryDirectoryPath / "vsim.exe" elif (self._platform == "Linux"): executablePath = self._binaryDirectoryPath / "vsim" else: raise PlatformNotSupportedException(self._platform) super().__init__(self._platform, self._dryrun, executablePath, logger=self._logger) self.Parameters[self.Executable] = executablePath self._hasOutput = False self._hasWarnings = False self._hasErrors = False @property def HasWarnings(self): return self._hasWarnings @property def HasErrors(self): return self._hasErrors class Executable(metaclass=ExecutableArgument): _value = None class FlagQuietMode(metaclass=ShortFlagArgument): _name = "quiet" # Do not report 'Loading...' messages" _value = None class FlagBatchMode(metaclass=ShortFlagArgument): _name = "batch" _value = None class FlagGuiMode(metaclass=ShortFlagArgument): _name = "gui" _value = None class SwitchBatchCommand(metaclass=ShortTupleArgument): _name = "do" _value = None class FlagCommandLineMode(metaclass=ShortFlagArgument): _name = "c" _value = None class SwitchModelSimIniFile(metaclass=ShortTupleArgument): _name = "modelsimini" _value = None class FlagOptimization(metaclass=ShortFlagArgument): _name = "vopt" _value = None class FlagReportAsError(metaclass=ShortTupleArgument): _name = "error" _value = None class SwitchTimeResolution(metaclass=ShortTupleArgument): _name = "t" # -t [1|10|100]fs|ps|ns|us|ms|sec Time resolution limit _value = None class ArgLogFile(metaclass=ShortTupleArgument): _name = "l" # what's the difference to -logfile ? _value = None class ArgKeepStdOut(metaclass=ShortFlagArgument): _name = "keepstdout" class ArgVHDLLibraryName(metaclass=ShortTupleArgument): _name = "lib" _value = None class ArgOnFinishMode(metaclass=ShortTupleArgument): _name = "onfinish" _value = None # Customize the kernel shutdown behavior at the end of simulation; Valid modes: ask, stop, exit, final (Default: ask) class SwitchTopLevel(metaclass=StringArgument): _value = None Parameters = CommandLineArgumentList( Executable, FlagQuietMode, FlagBatchMode, FlagGuiMode, SwitchBatchCommand, FlagCommandLineMode, SwitchModelSimIniFile, FlagOptimization, FlagReportAsError, ArgLogFile, ArgKeepStdOut, ArgVHDLLibraryName, SwitchTimeResolution, ArgOnFinishMode, SwitchTopLevel) def Simulate(self): parameterList = self.Parameters.ToArgumentList() self.LogVerbose("command: {0}".format(" ".join(parameterList))) try: self.StartProcess(parameterList) except Exception as ex: raise QuestaSimException("Failed to launch vsim run.") from ex self._hasOutput = False self._hasWarnings = False self._hasErrors = False simulationResult = CallByRefParam(SimulationResult.Error) try: iterator = iter( PoCSimulationResultFilter(QuestaVSimFilter(self.GetReader()), simulationResult)) line = next(iterator) line.IndentBy(self.Logger.BaseIndent + 1) self._hasOutput = True self.LogNormal(" vsim messages for '{0}'".format( self.Parameters[self.SwitchTopLevel])) self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent * 2))) self.Log(line) while True: self._hasWarnings |= (line.Severity is Severity.Warning) self._hasErrors |= (line.Severity is Severity.Error) line = next(iterator) line.IndentBy(self.Logger.BaseIndent + 1) self.Log(line) except PoCSimulationResultNotFoundException: if self.Parameters[self.FlagGuiMode]: simulationResult <<= SimulationResult.GUIRun except StopIteration: pass finally: if self._hasOutput: self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent * 2))) return simulationResult.value
class ActiveHDLVHDLLibraryTool(Executable, ToolMixIn): """Abstraction layer of Active-HDL's VHDL library management tool 'vlib'.""" def __init__(self, toolchain : ToolMixIn): ToolMixIn.__init__( self, toolchain._platform, toolchain._dryrun, toolchain._binaryDirectoryPath, toolchain._version, toolchain._logger) if (self._platform == "Windows"): executablePath = self._binaryDirectoryPath / "vlib.exe" else: raise PlatformNotSupportedException(self._platform) super().__init__(self._platform, self._dryrun, executablePath, logger=self._logger) self._hasOutput = False self._hasWarnings = False self._hasErrors = False self.Parameters[self.Executable] = executablePath @property def HasWarnings(self): return self._hasWarnings @property def HasErrors(self): return self._hasErrors class Executable(metaclass=ExecutableArgument): _value = None # class FlagVerbose(metaclass=FlagArgument): # _name = "-v" # _value = None class SwitchLibraryName(metaclass=StringArgument): _value = None Parameters = CommandLineArgumentList( Executable, # FlagVerbose, SwitchLibraryName ) def CreateLibrary(self): parameterList = self.Parameters.ToArgumentList() self.LogVerbose("command: {0}".format(" ".join(parameterList))) try: self.StartProcess(parameterList) except Exception as ex: raise ActiveHDLException("Failed to launch alib run.") from ex self._hasOutput = False self._hasWarnings = False self._hasErrors = False try: iterator = iter(VHDLLibraryToolFilter(self.GetReader())) line = next(iterator) self._hasOutput = True self.LogNormal(" alib messages for '{0}'".format(self.Parameters[self.SwitchLibraryName])) self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent*2))) while True: self._hasWarnings |= (line.Severity is Severity.Warning) self._hasErrors |= (line.Severity is Severity.Error) line.IndentBy(self.Logger.BaseIndent + 1) self.Log(line) line = next(iterator) except StopIteration: pass finally: if self._hasOutput: self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent*2)))
class Make(Executable): def __init__(self, platform, dryrun, logger=None): if (platform == "Linux"): executablePath = "/usr/bin/make" else: raise PlatformNotSupportedException(platform) super().__init__(platform, dryrun, executablePath, logger=logger) self.Parameters[self.Executable] = executablePath self._hasOutput = False self._hasWarnings = False self._hasErrors = False class Executable(metaclass=ExecutableArgument): pass class SwitchGui(metaclass=ValuedFlagArgument): _name = "GUI" Parameters = CommandLineArgumentList(Executable, SwitchGui) def RunCocotb(self): parameterList = self.Parameters.ToArgumentList() self.LogVerbose("command: {0}".format(" ".join(parameterList))) if (self._dryrun): self.LogDryRun("Start process: {0}".format( " ".join(parameterList))) return try: self.StartProcess(parameterList) except Exception as ex: raise GNUException("Failed to launch Make.") from ex self._hasOutput = False self._hasWarnings = False self._hasErrors = False simulationResult = CallByRefParam(SimulationResult.Error) try: iterator = iter( CocotbSimulationResultFilter( GNUMakeQuestaSimFilter(self.GetReader()), simulationResult)) line = next(iterator) line.IndentBy(self.Logger.BaseIndent + 1) self._hasOutput = True self.LogNormal(" Make messages") self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent * 2))) self.Log(line) while True: self._hasWarnings |= (line.Severity is Severity.Warning) self._hasErrors |= (line.Severity is Severity.Error) line = next(iterator) line.IndentBy(self.Logger.BaseIndent + 1) self.Log(line) except StopIteration: pass finally: if self._hasOutput: self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent * 2))) return simulationResult.value
class Simulator(Executable, ToolMixIn): """Abstraction layer of Active-HDL's VHDL simulator 'vsim'.""" def __init__(self, platform, dryrun, binaryDirectoryPath, version, logger=None): ToolMixIn.__init__(self, platform, dryrun, binaryDirectoryPath, version, logger=logger) if (self._platform == "Windows"): executablePath = binaryDirectoryPath / "vsimsa.exe" # elif (self._platform == "Linux"): executablePath = binaryDirectoryPath / "vsimsa" else: raise PlatformNotSupportedException(self._platform) super().__init__(platform, dryrun, executablePath, logger=logger) self.Parameters[self.Executable] = executablePath class Executable(metaclass=ExecutableArgument): _value = None # class FlagVerbose(metaclass=ShortFlagArgument): # _name = "v" # _value = None # # class FlagOptimization(metaclass=ShortFlagArgument): # _name = "vopt" # _value = None # # class FlagCommandLineMode(metaclass=ShortFlagArgument): # _name = "c" # _value = None # # class SwitchTimeResolution(metaclass=ShortTupleArgument): # _name = "t" # _value = None class SwitchBatchCommand(metaclass=ShortTupleArgument): _name = "do" # class SwitchTopLevel(metaclass=ShortValuedFlagArgument): # _name = "" # _value = None Parameters = CommandLineArgumentList( Executable, # FlagVerbose, # FlagOptimization, # FlagCommandLineMode, # SwitchTimeResolution, SwitchBatchCommand # SwitchTopLevel ) # units = ("fs", "ps", "us", "ms", "sec", "min", "hr") def Simulate(self): parameterList = self.Parameters.ToArgumentList() self.LogVerbose("command: {0}".format(" ".join(parameterList))) self.LogDebug("tcl commands: {0}".format(self.Parameters[self.SwitchBatchCommand])) _indent = " " print(_indent + "vsimsa messages for '{0}.{1}'".format("??????", "??????")) # self.VHDLLibrary, topLevel)) print(_indent + "-" * 80) try: self.StartProcess(parameterList) for line in self.GetReader(): print(_indent + line) except Exception as ex: raise ex # SimulatorException() from ex print(_indent + "-" * 80)
class StandaloneSimulator(Executable, ToolMixIn): """Abstraction layer of Active-HDL's VHDL standalone simulator 'vsimsa'.""" def __init__(self, toolchain : ToolMixIn): ToolMixIn.__init__( self, toolchain._platform, toolchain._dryrun, toolchain._binaryDirectoryPath, toolchain._version, toolchain._logger) if (self._platform == "Windows"): executablePath = self._binaryDirectoryPath / "vsimsa.exe" else: raise PlatformNotSupportedException(self._platform) super().__init__(self._platform, self._dryrun, executablePath, logger=self._logger) self._hasOutput = False self._hasWarnings = False self._hasErrors = False self.Parameters[self.Executable] = executablePath @property def HasWarnings(self): return self._hasWarnings @property def HasErrors(self): return self._hasErrors class Executable(metaclass=ExecutableArgument): _value = None class SwitchBatchCommand(metaclass=ShortTupleArgument): _name = "do" _value = None Parameters = CommandLineArgumentList( Executable, SwitchBatchCommand ) def Simulate(self): parameterList = self.Parameters.ToArgumentList() self.LogVerbose("command: {0}".format(" ".join(parameterList))) self.LogDebug("tcl commands: {0}".format(self.Parameters[self.SwitchBatchCommand])) try: self.StartProcess(parameterList) except Exception as ex: raise ActiveHDLException("Failed to launch vsimsa run.") from ex self._hasOutput = False self._hasWarnings = False self._hasErrors = False simulationResult = CallByRefParam(SimulationResult.Error) try: iterator = iter(PoCSimulationResultFilter(SimulatorFilter(self.GetReader()), simulationResult)) line = next(iterator) self._hasOutput = True self.LogNormal(" vsimsa messages for '{0}.{1}'".format("?????", "?????")) self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent*2))) while True: self._hasWarnings |= (line.Severity is Severity.Warning) self._hasErrors |= (line.Severity is Severity.Error) line.IndentBy(self.Logger.BaseIndent + 1) self.Log(line) line = next(iterator) except StopIteration: pass finally: if self._hasOutput: self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent*2))) return simulationResult.value
class VHDLCompiler(Executable, ToolMixIn): """Abstraction layer of Active-HDL's VHDL compiler 'vcom'.""" def __init__(self, toolchain : ToolMixIn): ToolMixIn.__init__( self, toolchain._platform, toolchain._dryrun, toolchain._binaryDirectoryPath, toolchain._version, toolchain._logger) if (self._platform == "Windows"): executablePath = self._binaryDirectoryPath / "vcom.exe" else: raise PlatformNotSupportedException(self._platform) super().__init__(self._platform, self._dryrun, executablePath, logger=self._logger) self._hasOutput = False self._hasWarnings = False self._hasErrors = False self.Parameters[self.Executable] = executablePath @property def HasWarnings(self): return self._hasWarnings @property def HasErrors(self): return self._hasErrors class Executable(metaclass=ExecutableArgument): _value = None class FlagNoRangeCheck(metaclass=LongFlagArgument): _name = "norangecheck" _value = None class SwitchVHDLVersion(metaclass=ShortValuedFlagArgument): _pattern = "-{1}" _name = "" _value = None class SwitchVHDLLibrary(metaclass=ShortTupleArgument): _name = "work" _value = None class ArgSourceFile(metaclass=PathArgument): _value = None Parameters = CommandLineArgumentList( Executable, FlagNoRangeCheck, SwitchVHDLVersion, SwitchVHDLLibrary, ArgSourceFile ) # -reorder enables automatic file ordering # -O[0 | 1 | 2 | 3] set optimization level # -93 conform to VHDL 1076-1993 # -2002 conform to VHDL 1076-2002 (default) # -2008 conform to VHDL 1076-2008 # -relax allow 32-bit integer literals # -incr switching compiler to fast incremental mode def Compile(self): parameterList = self.Parameters.ToArgumentList() self.LogVerbose("command: {0}".format(" ".join(parameterList))) if (self._dryrun): self.LogDryRun("Start process: {0}".format(" ".join(parameterList))) return try: self.StartProcess(parameterList) except Exception as ex: raise ActiveHDLException("Failed to launch acom run.") from ex self._hasOutput = False self._hasWarnings = False self._hasErrors = False try: iterator = iter(VHDLCompilerFilter(self.GetReader())) line = next(iterator) self._hasOutput = True self.LogNormal(" acom messages for '{0}'".format(self.Parameters[self.ArgSourceFile])) self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent*2))) while True: self._hasWarnings |= (line.Severity is Severity.Warning) self._hasErrors |= (line.Severity is Severity.Error) line.IndentBy(self.Logger.BaseIndent + 1) self.Log(line) line = next(iterator) except StopIteration: pass finally: if self._hasOutput: self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent*2)))
class GTKWave(Executable): def __init__(self, platform, dryrun, binaryDirectoryPath, version, logger=None): if (platform == "Windows"): executablePath = binaryDirectoryPath / "gtkwave.exe" elif (platform == "Linux"): executablePath = binaryDirectoryPath / "gtkwave" elif (platform == "Darwin"): executablePath = binaryDirectoryPath / "gtkwave" else: raise PlatformNotSupportedException(self._platform) super().__init__(platform, dryrun, executablePath, logger=logger) self.Parameters[self.Executable] = executablePath self._binaryDirectoryPath = binaryDirectoryPath self._version = version self._hasOutput = False self._hasWarnings = False self._hasErrors = False @property def BinaryDirectoryPath(self): return self._binaryDirectoryPath @property def Version(self): return self._version class Executable(metaclass=ExecutableArgument): pass class SwitchDumpFile(metaclass=LongValuedFlagArgument): _name = "dump" class SwitchSaveFile(metaclass=LongValuedFlagArgument): _name = "save" Parameters = CommandLineArgumentList(Executable, SwitchDumpFile, SwitchSaveFile) def View(self): parameterList = self.Parameters.ToArgumentList() self.LogVerbose("command: {0}".format(" ".join(parameterList))) if (self._dryrun): self.LogDryRun("Start process: {0}".format( " ".join(parameterList))) return try: self.StartProcess(parameterList) except Exception as ex: raise GTKWaveException("Failed to launch GTKWave run.") from ex self._hasOutput = False self._hasWarnings = False self._hasErrors = False try: iterator = iter(GTKWaveFilter(self.GetReader())) line = next(iterator) line.IndentBy(self.Logger.BaseIndent + 1) self._hasOutput = True self.LogNormal(" GTKWave messages for '{0}'".format( self.Parameters[self.SwitchDumpFile])) self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent * 2))) self.Log(line) while True: self._hasWarnings |= (line.Severity is Severity.Warning) self._hasErrors |= (line.Severity is Severity.Error) line = next(iterator) line.IndentBy(self.Logger.BaseIndent + 1) self.Log(line) except StopIteration: pass finally: if self._hasOutput: self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent * 2)))
class XSim(Executable, ToolMixIn): def __init__(self, toolchain: ToolMixIn): ToolMixIn.__init__(self, toolchain._platform, toolchain._dryrun, toolchain._binaryDirectoryPath, toolchain._version, toolchain._logger) if (self._platform == "Windows"): executablePath = self._binaryDirectoryPath / "xsim.bat" elif (self._platform == "Linux"): executablePath = self._binaryDirectoryPath / "xsim" else: raise PlatformNotSupportedException(self._platform) super().__init__(self._platform, self._dryrun, executablePath, logger=self._logger) self.Parameters[self.Executable] = executablePath self._hasOutput = False self._hasWarnings = False self._hasErrors = False @property def HasWarnings(self): return self._hasWarnings @property def HasErrors(self): return self._hasErrors class Executable(metaclass=ExecutableArgument): _value = None class SwitchLogFile(metaclass=ShortTupleArgument): _name = "-log" _value = None class FlagGuiMode(metaclass=ShortFlagArgument): _name = "-gui" _value = None class SwitchTclBatchFile(metaclass=ShortTupleArgument): _name = "-tclbatch" _value = None class SwitchWaveformFile(metaclass=ShortTupleArgument): _name = "-view" _value = None class SwitchSnapshot(metaclass=StringArgument): _value = None Parameters = CommandLineArgumentList(Executable, SwitchLogFile, FlagGuiMode, SwitchTclBatchFile, SwitchWaveformFile, SwitchSnapshot) def Simulate(self): parameterList = self.Parameters.ToArgumentList() self.LogVerbose("command: {0}".format(" ".join(parameterList))) if (self._dryrun): self.LogDryRun("Start process: {0}".format( " ".join(parameterList))) return try: self.StartProcess(parameterList) except Exception as ex: raise VivadoException("Failed to launch xsim.") from ex self._hasOutput = False self._hasWarnings = False self._hasErrors = False simulationResult = CallByRefParam(SimulationResult.Error) try: iterator = iter( PoCSimulationResultFilter(SimulatorFilter(self.GetReader()), simulationResult)) line = next(iterator) self._hasOutput = True self.LogNormal(" xsim messages for '{0}'".format( self.Parameters[self.SwitchSnapshot])) self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent * 2))) while True: self._hasWarnings |= (line.Severity is Severity.Warning) self._hasErrors |= (line.Severity is Severity.Error) line.IndentBy(self.Logger.BaseIndent + 1) self.Log(line) line = next(iterator) except StopIteration: pass finally: if self._hasOutput: self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent * 2))) return simulationResult.value
class Synth(Executable, ToolMixIn): def __init__(self, toolchain: ToolMixIn): ToolMixIn.__init__(self, toolchain._platform, toolchain._dryrun, toolchain._binaryDirectoryPath, toolchain._version, toolchain._logger) if (self._platform == "Windows"): executablePath = self._binaryDirectoryPath / "synthesis.exe" elif (self._platform == "Linux"): executablePath = self._binaryDirectoryPath / "synthesis" else: raise PlatformNotSupportedException(self._platform) super().__init__(self._platform, self._dryrun, executablePath, logger=self._logger) self.Parameters[self.Executable] = executablePath self._hasOutput = False self._hasWarnings = False self._hasErrors = False @property def HasWarnings(self): return self._hasWarnings @property def HasErrors(self): return self._hasErrors class Executable(metaclass=ExecutableArgument): pass class SwitchProjectFile(metaclass=ShortTupleArgument): _name = "f" _value = None Parameters = CommandLineArgumentList(Executable, SwitchProjectFile) def GetLogFileReader(self, logFile): while True: if logFile.exists(): break time.sleep(5) # FIXME: implement a 'tail -f' functionality with logFile.open('r') as logFileHandle: for line in logFileHandle: yield line[:-1] def Compile(self, logFile): parameterList = self.Parameters.ToArgumentList() self.LogVerbose("command: {0}".format(" ".join(parameterList))) if (self._dryrun): self.LogDryRun("Start process: {0}".format( " ".join(parameterList))) return try: self.StartProcess(parameterList) except Exception as ex: raise LatticeException("Failed to launch LSE.") from ex self._hasOutput = False self._hasWarnings = False self._hasErrors = False try: iterator = iter(CompilerFilter(self.GetReader())) line = next(iterator) self._hasOutput = True self.LogNormal(" LSE messages for '{0}'".format( self.Parameters[self.SwitchProjectFile])) self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent * 2))) while True: self._hasWarnings |= (line.Severity is Severity.Warning) self._hasErrors |= (line.Severity is Severity.Error) line.IndentBy(self.Logger.BaseIndent + 1) self.Log(line) line = next(iterator) except StopIteration: pass finally: if self._hasOutput: self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent * 2)))
class QuestaVHDLCompiler(Executable, ToolMixIn): def __init__(self, toolchain: ToolMixIn): ToolMixIn.__init__(self, toolchain._platform, toolchain._dryrun, toolchain._binaryDirectoryPath, toolchain._version, toolchain._logger) if (self._platform == "Windows"): executablePath = self._binaryDirectoryPath / "vcom.exe" elif (self._platform == "Linux"): executablePath = self._binaryDirectoryPath / "vcom" else: raise PlatformNotSupportedException(self._platform) super().__init__(self._platform, self._dryrun, executablePath, logger=self._logger) self.Parameters[self.Executable] = executablePath self._hasOutput = False self._hasWarnings = False self._hasErrors = False @property def HasWarnings(self): return self._hasWarnings @property def HasErrors(self): return self._hasErrors class Executable(metaclass=ExecutableArgument): _value = None class FlagTime(metaclass=ShortFlagArgument): _name = "time" # Print the compilation wall clock time _value = None class FlagExplicit(metaclass=ShortFlagArgument): _name = "explicit" _value = None class FlagQuietMode(metaclass=ShortFlagArgument): _name = "quiet" # Do not report 'Loading...' messages" _value = None class SwitchModelSimIniFile(metaclass=ShortTupleArgument): _name = "modelsimini" _value = None class FlagRangeCheck(metaclass=ShortFlagArgument): _name = "rangecheck" _value = None class SwitchVHDLVersion(metaclass=StringArgument): _pattern = "-{0}" _value = None class ArgLogFile(metaclass=ShortTupleArgument): _name = "l" # what's the difference to -logfile ? _value = None class SwitchVHDLLibrary(metaclass=ShortTupleArgument): _name = "work" _value = None class ArgSourceFile(metaclass=PathArgument): _value = None Parameters = CommandLineArgumentList(Executable, FlagTime, FlagExplicit, FlagQuietMode, SwitchModelSimIniFile, FlagRangeCheck, SwitchVHDLVersion, ArgLogFile, SwitchVHDLLibrary, ArgSourceFile) def Compile(self): parameterList = self.Parameters.ToArgumentList() self.LogVerbose("command: {0}".format(" ".join(parameterList))) if (self._dryrun): self.LogDryRun("Start process: {0}".format( " ".join(parameterList))) return try: self.StartProcess(parameterList) except Exception as ex: raise QuestaSimException("Failed to launch vcom run.") from ex self._hasOutput = False self._hasWarnings = False self._hasErrors = False try: iterator = iter(QuestaVComFilter(self.GetReader())) line = next(iterator) line.IndentBy(self.Logger.BaseIndent + 1) self._hasOutput = True self.LogNormal(" vcom messages for '{0}'".format( self.Parameters[self.ArgSourceFile])) self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent * 2))) self.Log(line) while True: self._hasWarnings |= (line.Severity is Severity.Warning) self._hasErrors |= (line.Severity is Severity.Error) line = next(iterator) line.IndentBy(self.Logger.BaseIndent + 1) self.Log(line) except StopIteration: pass finally: if self._hasOutput: self.LogNormal(" " + ("-" * (78 - self.Logger.BaseIndent * 2))) def GetTclCommand(self): parameterList = self.Parameters.ToArgumentList() return "vcom " + " ".join(parameterList[1:])