Source code for pyIPCMI.Simulator.VivadoSimulator

# EMACS settings: -*-	tab-width: 2; indent-tabs-mode: t; python-indent-offset: 2 -*-
# vim: tabstop=2:shiftwidth=2:noexpandtab
# kate: tab-width 2; replace-tabs off; indent-width 2;
#
# ==============================================================================
# Authors:          Patrick Lehmann
#                   Martin Zabel
#
# Python Module:    Xilinx Vivado simulator.
#
# License:
# ==============================================================================
# Copyright 2017-2018 Patrick Lehmann - Bötzingen, Germany
# Copyright 2007-2016 Technische Universität Dresden - Germany
#                     Chair of VLSI-Design, Diagnostics and Architecture
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
#
# load dependencies
from pathlib                    import Path

from pyIPCMI.Base.Executable            import DryRunException
from pyIPCMI.Base.Logging               import Severity
from pyIPCMI.Base.Project               import ToolChain, Tool
from pyIPCMI.ToolChain.Xilinx           import XilinxProjectExportMixIn
from pyIPCMI.ToolChain.Xilinx.Vivado    import Vivado, VivadoException
from pyIPCMI.Simulator                  import VHDL_TESTBENCH_LIBRARY_NAME, SimulatorException, SkipableSimulatorException, SimulationSteps, Simulator as BaseSimulator


__api__ = [
	'Simulator'
]
__all__ = __api__


[docs]class Simulator(BaseSimulator, XilinxProjectExportMixIn): TOOL_CHAIN = ToolChain.Xilinx_Vivado TOOL = Tool.Xilinx_xSim def __init__(self, host, dryRun, simulationSteps): super().__init__(host, dryRun, simulationSteps) XilinxProjectExportMixIn.__init__(self) vivadoFilesDirectoryName = host.Config['CONFIG.DirectoryNames']['VivadoSimulatorFiles'] self.Directories.Working = host.Directories.Temp / vivadoFilesDirectoryName self.Directories.PreCompiled = host.Directories.PreCompiled / vivadoFilesDirectoryName self._PrepareSimulationEnvironment() self._PrepareSimulator()
[docs] def _PrepareSimulator(self): # create the Vivado executable factory self.LogVerbose("Preparing Vivado simulator.") vivadoSection = self.Host.Config['INSTALL.Xilinx.Vivado'] version = vivadoSection['Version'] installationDirectory = Path(vivadoSection['InstallationDirectory']) binaryPath = Path(vivadoSection['BinaryDirectory']) self._toolChain = Vivado(self.Host.Platform, self.DryRun, binaryPath, version, logger=self.Logger) self._toolChain.PreparseEnvironment(installationDirectory)
[docs] def _RunElaboration(self, testbench): xelabLogFilePath = self.Directories.Working / (testbench.ModuleName + ".xelab.log") prjFilePath = self.Directories.Working / (testbench.ModuleName + ".prj") self._WriteXilinxProjectFile(prjFilePath, "xSim", self._vhdlVersion) # create a VivadoLinker instance xelab = self._toolChain.GetElaborator() xelab.Parameters[xelab.SwitchTimeResolution] = "1fs" # set minimum time precision to 1 fs xelab.Parameters[xelab.SwitchMultiThreading] = "off" if self.Logger.LogLevel is Severity.Debug else "auto" # disable multithreading support in debug mode xelab.Parameters[xelab.FlagRangeCheck] = True xelab.Parameters[xelab.SwitchOptimization] = "0" if self.Logger.LogLevel is Severity.Debug else "2" # set to "0" to disable optimization xelab.Parameters[xelab.SwitchDebug] = "typical" xelab.Parameters[xelab.SwitchSnapshot] = testbench.ModuleName xelab.Parameters[xelab.SwitchVerbose] = "1" if self.Logger.LogLevel is Severity.Debug else "0" # set to "1" for detailed messages xelab.Parameters[xelab.SwitchProjectFile] = str(prjFilePath) xelab.Parameters[xelab.SwitchLogFile] = str(xelabLogFilePath) xelab.Parameters[xelab.ArgTopLevel] = "{0}.{1}".format(VHDL_TESTBENCH_LIBRARY_NAME, testbench.ModuleName) try: xelab.Link() except DryRunException: pass except VivadoException as ex: raise SimulatorException("Error while analysing '{0!s}'.".format(prjFilePath)) from ex if xelab.HasErrors: raise SkipableSimulatorException("Error while analysing '{0!s}'.".format(prjFilePath))
[docs] def _RunSimulation(self, testbench): xSimLogFilePath = self.Directories.Working / (testbench.ModuleName + ".xSim.log") tclBatchFilePath = self.Host.Directories.Root / self.Host.Config[testbench.ConfigSectionName]['xSimBatchScript'] tclGUIFilePath = self.Host.Directories.Root / self.Host.Config[testbench.ConfigSectionName]['xSimGUIScript'] wcfgFilePath = self.Host.Directories.Root / self.Host.Config[testbench.ConfigSectionName]['xSimWaveformConfigFile'] # create a VivadoSimulator instance xSim = self._toolChain.GetSimulator() xSim.Parameters[xSim.SwitchLogFile] = str(xSimLogFilePath) if (SimulationSteps.ShowWaveform not in self._simulationSteps): xSim.Parameters[xSim.SwitchTclBatchFile] = tclBatchFilePath.as_posix() else: xSim.Parameters[xSim.SwitchTclBatchFile] = tclGUIFilePath.as_posix() xSim.Parameters[xSim.FlagGuiMode] = True # if xSim save file exists, load it's settings if wcfgFilePath.exists(): self.LogDebug("Found waveform config file: '{0!s}'".format(wcfgFilePath)) xSim.Parameters[xSim.SwitchWaveformFile] = str(wcfgFilePath) else: self.LogDebug("Didn't find waveform config file: '{0!s}'".format(wcfgFilePath)) xSim.Parameters[xSim.SwitchSnapshot] = testbench.ModuleName try: testbench.Result = xSim.Simulate() except DryRunException: pass except VivadoException as ex: raise SimulatorException("Error while simulating '{0}.{1}'.".format(VHDL_TESTBENCH_LIBRARY_NAME, testbench.ModuleName)) from ex if xSim.HasErrors: raise SkipableSimulatorException("Error while simulating '{0}.{1}'.".format(VHDL_TESTBENCH_LIBRARY_NAME, testbench.ModuleName))