Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add vivado vlog support #100

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
builder = xvhdl
builder = xsim

target_dir = .build
vhdl basic_library basic_library/very_common_pkg.vhd
Expand All @@ -7,5 +7,5 @@ vhdl basic_library basic_library/clock_divider.vhd
vhdl another_library another_library/foo.vhd
vhdl basic_library basic_library/package_with_functions.vhd
vhdl basic_library basic_library/clk_en_generator.vhd
vhdl basic_library basic_library/two_entities_one_file.vhd
vhdl basic_library basic_library/use_entity_a_and_b.vhd
vhdl basic_library basic_library/two_entities_one_file.vhd
vhdl basic_library basic_library/use_entity_a_and_b.vhd
14 changes: 7 additions & 7 deletions hdl_checker/builder_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
from .builders.fallback import Fallback
from .builders.ghdl import GHDL
from .builders.msim import MSim
from .builders.xvhdl import XVHDL
from .builders.xsim import XSIM

from hdl_checker.parser_utils import findRtlSourcesByPath
from hdl_checker.parsers.elements.identifier import Identifier
Expand All @@ -56,7 +56,7 @@

_logger = logging.getLogger(__name__)

AnyValidBuilder = Union[MSim, XVHDL, GHDL]
AnyValidBuilder = Union[MSim, XSIM, GHDL]
AnyBuilder = Union[AnyValidBuilder, Fallback]


Expand All @@ -66,7 +66,7 @@ class BuilderName(Enum):
"""

msim = MSim.builder_name
xvhdl = XVHDL.builder_name
xsim = XSIM.builder_name
ghdl = GHDL.builder_name
fallback = Fallback.builder_name

Expand All @@ -77,8 +77,8 @@ def getBuilderByName(name):
# builder attribute
if name == "msim":
builder = MSim
elif name == "xvhdl":
builder = XVHDL
elif name == "xsim":
builder = XSIM
elif name == "ghdl":
builder = GHDL
else:
Expand Down Expand Up @@ -201,7 +201,7 @@ def _getSourcesFromVUnitModule(vunit_module):
return list(vunit_project.get_source_files())


__all__ = ["MSim", "XVHDL", "GHDL", "Fallback"]
__all__ = ["MSim", "XSIM", "GHDL", "Fallback"]

# This holds the builders in order of preference
AVAILABLE_BUILDERS = MSim, XVHDL, GHDL, Fallback
AVAILABLE_BUILDERS = MSim, XSIM, GHDL, Fallback
52 changes: 33 additions & 19 deletions hdl_checker/builders/xvhdl.py → hdl_checker/builders/xsim.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,31 @@
#
# You should have received a copy of the GNU General Public License
# along with HDL Checker. If not, see <http://www.gnu.org/licenses/>.
"Xilinx xhvdl builder implementation"
"Xilinx Simulator builder implementation"

import os.path as p
import re
import shutil
import tempfile
from typing import Iterable, Mapping, Optional

from .base_builder import BaseBuilder

from hdl_checker.exceptions import SanityCheckError
from hdl_checker.diagnostics import BuilderDiag, DiagType
from hdl_checker.parsers.elements.identifier import Identifier
from hdl_checker.path import Path
from hdl_checker.types import BuildFlags, FileType
from hdl_checker.utils import runShellCommand

from .base_builder import BaseBuilder

_ITER_REBUILD_UNITS = re.compile(
r"ERROR:\s*\[[^\]]*\]\s*"
r"'?.*/(?P<library_name>\w+)/(?P<unit_name>\w+)\.vdb'?"
r"\s+needs to be re-saved.*",
flags=re.I,
).finditer

# XVHDL specific class properties
# XSIM specific class properties
_STDOUT_MESSAGE_SCANNER = re.compile(
r"^(?P<severity>[EW])\w+:\s*"
r"\[(?P<error_code>[^\]]+)\]\s*"
Expand All @@ -50,13 +51,12 @@
)


class XVHDL(BaseBuilder):
"""Builder implementation of the xvhdl compiler"""
class XSIM(BaseBuilder):
"""Builder implementation of the xvhdl and xvlog compiler"""

# Implementation of abstract class properties
builder_name = "xvhdl"
# TODO: Add xvlog support
file_types = {FileType.vhdl}
builder_name = "xsim"
file_types = {FileType.vhdl, FileType.verilog, FileType.systemverilog}

def _shouldIgnoreLine(self, line):
# type: (str) -> bool
Expand All @@ -75,10 +75,11 @@ def _shouldIgnoreLine(self, line):
def __init__(self, *args, **kwargs):
# type: (...) -> None
self._version = ""
super(XVHDL, self).__init__(*args, **kwargs)
self._xvhdlini = p.join(self._work_folder, ".xvhdl.init")
super().__init__(*args, **kwargs)
self._xsimini = p.join(self._work_folder, ".xsim.init")
# Create the ini file
open(self._xvhdlini, "w").close()
with open(self._xsimini, "w", encoding="utf8"):
pass

def _makeRecords(self, line):
# type: (str) -> Iterable[BuilderDiag]
Expand All @@ -105,7 +106,7 @@ def _makeRecords(self, line):
)

def _parseBuiltinLibraries(self):
"(Not used by XVHDL)"
"(Not used by XSIM)"
return (
Identifier(x, case_sensitive=False)
for x in (
Expand All @@ -124,9 +125,12 @@ def _checkEnvironment(self):
stdout = runShellCommand(
["xvhdl", "--nolog", "--version"], cwd=self._work_folder
)
self._version = re.findall(r"^Vivado Simulator\s+([\d\.]+)", stdout[0])[0]
versionParsed = re.findall(r"^Vivado Simulator\s+v?([\d\.]+)", stdout[0])
if len(versionParsed) < 1:
raise SanityCheckError(self.builder_name, "Could not parse Vivado version string")
self._version = versionParsed[0]
self._logger.info(
"xvhdl version string: '%s'. " "Version number is '%s'",
"xvhdl version string: '%s'. Version number is '%s'",
stdout[:-1],
self._version,
)
Expand All @@ -136,6 +140,7 @@ def isAvailable():
try:
temp_dir = tempfile.mkdtemp()
runShellCommand(["xvhdl", "--nolog", "--version"], cwd=temp_dir)
runShellCommand(["xvlog", "--nolog", "--version"], cwd=temp_dir)
return True
except OSError:
return False
Expand All @@ -144,27 +149,36 @@ def isAvailable():

def _createLibrary(self, library):
# type: (Identifier) -> None
with open(self._xvhdlini, mode="w") as fd:
with open(self._xsimini, mode="w", encoding="utf8") as fd:
content = "\n".join(
[
"%s=%s" % (x, p.join(self._work_folder, x.name))
f"{x}=%s" % p.join(self._work_folder, x.name)
for x in self._added_libraries
]
)
fd.write(content)

def _buildSource(self, path, library, flags=None):
# type: (Path, Identifier, Optional[BuildFlags]) -> Iterable[str]
xsim_cmd = None
filetype = FileType.fromPath(path)
if filetype == FileType.vhdl:
xsim_cmd = "xvhdl"
if filetype in (FileType.verilog, FileType.systemverilog):
xsim_cmd = "xvlog"
assert xsim_cmd is not None
cmd = [
"xvhdl",
xsim_cmd,
"--nolog",
"--verbose",
"0",
"--initfile",
self._xvhdlini,
self._xsimini,
"--work",
library.name,
]
if filetype == FileType.systemverilog:
cmd += ["-sv"]
cmd += [str(x) for x in (flags or [])]
cmd += [path.name]
return runShellCommand(cmd, cwd=self._work_folder)
Expand Down
4 changes: 2 additions & 2 deletions hdl_checker/serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from hdl_checker.builders.fallback import Fallback
from hdl_checker.builders.ghdl import GHDL
from hdl_checker.builders.msim import MSim
from hdl_checker.builders.xvhdl import XVHDL
from hdl_checker.builders.xsim import XSIM
from hdl_checker.database import Database
from hdl_checker.parsers.elements.dependency_spec import (
IncludedPath,
Expand Down Expand Up @@ -60,7 +60,7 @@
"VerilogDesignUnit": VerilogDesignUnit,
"VhdlIdentifier": VhdlIdentifier,
"VhdlParser": VhdlParser,
"XVHDL": XVHDL,
"XSIM": XSIM,
}


Expand Down
8 changes: 4 additions & 4 deletions hdl_checker/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ def getBuilderByName(name):
"Returns the builder class given a string name"
from hdl_checker.builders.msim import MSim
from hdl_checker.builders.ghdl import GHDL
from hdl_checker.builders.xvhdl import XVHDL
from hdl_checker.builders.xsim import XSIM
from hdl_checker.builders.fallback import Fallback

# Check if the builder selected is implemented and create the
Expand All @@ -276,8 +276,8 @@ def getBuilderByName(name):
return MockBuilder
if name == "msim":
return MSim
if name == "xvhdl":
return XVHDL
if name == "xsim":
return XSIM
if name == "ghdl":
return GHDL

Expand Down Expand Up @@ -391,7 +391,7 @@ def writeListToFile(filename, _list): # pragma: no cover
TEST_ENVS = {
"ghdl": os.environ["GHDL_PATH"],
"msim": os.environ["MODELSIM_PATH"],
"xvhdl": os.environ["XSIM_PATH"],
"xsim": os.environ["XSIM_PATH"],
"fallback": None,
}
else:
Expand Down
6 changes: 3 additions & 3 deletions hdl_checker/tests/test_builder_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
from hdl_checker.builders.fallback import Fallback
from hdl_checker.builders.ghdl import GHDL
from hdl_checker.builders.msim import MSim
from hdl_checker.builders.xvhdl import XVHDL
from hdl_checker.builders.xsim import XSIM
from hdl_checker.path import Path
from hdl_checker.types import FileType

Expand All @@ -55,7 +55,7 @@ def _path(*args):
class TestBuilderUtils(TestCase):
def test_getBuilderByName(self):
self.assertEqual(getBuilderByName("msim"), MSim)
self.assertEqual(getBuilderByName("xvhdl"), XVHDL)
self.assertEqual(getBuilderByName("xsim"), XSIM)
self.assertEqual(getBuilderByName("ghdl"), GHDL)
self.assertEqual(getBuilderByName("other"), Fallback)

Expand Down Expand Up @@ -214,7 +214,7 @@ def test_VhdlAndSystemverilogOnlyBuilder(
]

builder = MagicMock()
builder.builder_name = "xvhdl"
builder.builder_name = "xsim"
builder.file_types = {FileType.vhdl, FileType.systemverilog}

self.assertTrue(foundVunit(), "Need VUnit for this test")
Expand Down
20 changes: 10 additions & 10 deletions hdl_checker/tests/test_builders.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
from hdl_checker.builder_utils import (
AVAILABLE_BUILDERS,
GHDL,
XVHDL,
XSIM,
AnyBuilder,
Fallback,
MSim,
Expand Down Expand Up @@ -71,7 +71,7 @@
TEST_TEMP_PATH = getTestTempPath(__name__)
SOURCES_PATH = p.join(TEST_TEMP_PATH, "test_builders")

BUILDER_CLASS_MAP = {"msim": MSim, "xvhdl": XVHDL, "ghdl": GHDL, "fallback": Fallback}
BUILDER_CLASS_MAP = {"msim": MSim, "xsim": XSIM, "ghdl": GHDL, "fallback": Fallback}


class _SourceMock(SourceMock):
Expand Down Expand Up @@ -369,10 +369,10 @@ def test_ParseGhdlResult(self, path):
("some_file_on_same_level.vhd",),
]
)
def test_ParseXvhdlResult(self, path):
def test_ParseXsimResult(self, path):
# type: (...) -> Any
if not isinstance(self.builder, XVHDL):
raise unittest2.SkipTest("XVHDL only test")
if not isinstance(self.builder, XSIM):
raise unittest2.SkipTest("XSIM only test")

self.assertEqual(
list(
Expand Down Expand Up @@ -517,8 +517,8 @@ def test_CatchAKnownError(self):
),
}
]
elif self.builder_name == "xvhdl":
# XVHDL reports different errors depending on the version
elif self.builder_name == "xsim":
# XSIM reports different errors depending on the version
expected = [
{
BuilderDiag(
Expand Down Expand Up @@ -603,10 +603,10 @@ def test_GhdlRecompileMsg(self):
list(self.builder._searchForRebuilds(Path("foo.vhd"), line)),
)

def test_XvhdlRecompileMsg0(self):
def test_XsimRecompileMsg0(self):
# type: (...) -> Any
if not isinstance(self.builder, XVHDL):
raise unittest2.SkipTest("XVHDL only test")
if not isinstance(self.builder, XSIM):
raise unittest2.SkipTest("XSIM only test")

line = (
"ERROR: [VRFC 10-113] {} needs to be re-saved since std.standard "
Expand Down
4 changes: 2 additions & 2 deletions hdl_checker/tests/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
from hdl_checker.builders.fallback import Fallback
from hdl_checker.builders.ghdl import GHDL
from hdl_checker.builders.msim import MSim
from hdl_checker.builders.xvhdl import XVHDL
from hdl_checker.builders.xsim import XSIM
from hdl_checker.utils import _getLatestReleaseVersion, onNewReleaseFound, readFile

_logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -97,7 +97,7 @@ class TestBuilderUtils(unittest2.TestCase):
def test_getBuilderByName(self):
self.assertEqual(getBuilderByName(BuilderName.msim.value), MSim)
self.assertEqual(getBuilderByName(BuilderName.ghdl.value), GHDL)
self.assertEqual(getBuilderByName(BuilderName.xvhdl.value), XVHDL)
self.assertEqual(getBuilderByName(BuilderName.xsim.value), XSIM)
self.assertEqual(getBuilderByName("foo"), Fallback)


Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ setenv =

# install pytest in the virtualenv where commands will be executed
deps =
coverage==4.1
coverage==4.4.1
mock==2.0.0
nose2-cov==1.0a4
nose2==0.9.1
Expand Down