import logging import os import subprocess import warnings from pyvivado import task, config logger = logging.getLogger(__name__) class VivadoTask(task.Task): ''' A python wrapper to keep track of a spawned Vivado process. ''' # How to log different kinds of Vivado messages. MESSAGE_MAPPING = { 'DEBUG': logger.debug, 'INFO': logger.debug, 'WARNING': logger.warning, 'CRITICAL WARNING': logger.error, 'ERROR': logger.error, 'FATAL_ERROR': logger.error, # This is a hack to get 'assert's in the HDL with severity 'Failure' # to log an error message. 'Failure': logger.error, } DEFAULT_FAILURE_MESSAGE_TYPES = ( 'CRITICAL_WARNING', 'ERROR', 'FATAL_ERROR', 'Failure') @classmethod def create(cls, collection, command_text, description=None): ''' Create the files necessary for the Vivado process. Args: collection: A TasksCollection in which the task is to be added. command_text: The TCL command we will execute. description: A description of this task. ''' # Generate the TCL script that this Vivado process will run. command_template_fn = os.path.join(config.tcldir, 'vivado_task.tcl.t') with open(command_template_fn, 'r') as f: command_template = f.read() command = command_template.format( tcl_directory=config.tcldir, command=command_text ) # Make parent directory absolute logger.debug('Creating a new VivadoTask in directory {}'.format( collection.directory)) logger.debug('Command is {}'.format(command_text)) t = super().create(collection=collection, description=description) # Create the command file. command_fn = os.path.join(t.directory, 'command.tcl') with open(command_fn, 'w') as f: f.write(command) return t def __init__(self, directory): super().__init__(directory=directory) def run(self): ''' Spawn the process that will run the vivado process. ''' cwd = os.getcwd() os.chdir(self.directory) stdout_fn = 'stdout.txt' stderr_fn = 'stderr.txt' command_fn = 'command.tcl' if os.name == 'nt': commands = [config.vivado, '-log', stdout_fn, '-mode', 'batch', '-source', command_fn] logger.debug('running vivado task in directory {}'.format(self.directory)) logger.debug('command is {}'.format(' '.join(commands))) self.process = subprocess.Popen( commands, # So that process stays alive when terminal is closed # in Windows. # Commented out because doesn't seem to be working now. creationflags=subprocess.CREATE_NEW_CONSOLE, ) logger.debug('started process') else: commands = [config.vivado, '-mode', 'batch', '-source', command_fn] self.launch_unix_subprocess( commands, stdout_fn=stdout_fn, stderr_fn=stderr_fn) os.chdir(cwd)