Skip to content

Commit

Permalink
Added unit testing of compile_project method of simulator interfaces.
Browse files Browse the repository at this point in the history
  • Loading branch information
kraigher committed Mar 11, 2016
1 parent ab3b616 commit b65b5d4
Show file tree
Hide file tree
Showing 8 changed files with 636 additions and 39 deletions.
45 changes: 34 additions & 11 deletions vunit/activehdl_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,18 @@ class ActiveHDLInterface(SimulatorInterface):
name = "activehdl"
supports_gui_flag = True
package_users_depend_on_bodies = True
compile_options = [
"activehdl.vcom_flags",
"activehdl.vlog_flags",
]

@classmethod
def from_args(cls, output_path, args):
"""
Create new instance from command line arguments object
"""
return cls(join(output_path, "library.cfg"),
return cls(prefix=cls._find_prefix(),
library_cfg=join(output_path, "library.cfg"),
gui=args.gui)

@classmethod
Expand All @@ -51,10 +56,10 @@ def is_available(cls):
"""
return cls._find_prefix() is not None

def __init__(self, library_cfg="library.cfg", gui=False):
def __init__(self, prefix, library_cfg="library.cfg", gui=False):
self._vhdl_standard = None
self._library_cfg = abspath(library_cfg)
self._prefix = self._find_prefix()
self._prefix = prefix
self._gui = gui
self._create_library_cfg()
self._libraries = {}
Expand All @@ -74,29 +79,47 @@ def compile_project(self, project, vhdl_standard):

def compile_source_file_command(self, source_file):
"""
Returns the command to compile a single source file
Returns the command to compile a single source_file
"""
if source_file.file_type == 'vhdl':
return self.compile_vhdl_file_command(source_file.name, source_file.library.name)
return self.compile_vhdl_file_command(source_file)
elif source_file.file_type == 'verilog':
return self.compile_verilog_file_command(source_file)

LOGGER.error("Unknown file type: %s", source_file.file_type)
raise CompileError

def compile_vhdl_file_command(self, source_file_name, library_name):
def compile_vhdl_file_command(self, source_file):
"""
Returns the command to compile a vhdl file
Returns the command to compile a VHDL file
"""
return [join(self._prefix, 'vcom'), '-dbg', '-quiet', '-j', dirname(self._library_cfg),
'-' + self._vhdl_standard, '-work', library_name, source_file_name]
return ([join(self._prefix, 'vcom'), '-dbg', '-quiet', '-j', dirname(self._library_cfg)] +
source_file.compile_options.get("activehdl.vcom_flags", []) +
['-' + self._vhdl_standard, '-work', source_file.library.name, source_file.name])

def compile_verilog_file_command(self, source_file):
"""
Returns the command to compile a Verilog file
"""
args = [join(self._prefix, 'vlog'), '-quiet', '-sv2k12', '-lc', self._library_cfg]
args += source_file.compile_options.get("activehdl.vlog_flags", [])
args += ['-work', source_file.library.name, source_file.name]
for library in self._libraries.values():
args += ["-l", library.name]
for include_dir in source_file.include_dirs:
args += ["+incdir+%s" % include_dir]
for key, value in source_file.defines.items():
args += ["+define+%s=%s" % (key, value)]
return args

def create_library(self, library_name, path, mapped_libraries=None):
"""
Create and map a library_name to path
"""
mapped_libraries = mapped_libraries if mapped_libraries is not None else {}

if not file_exists(dirname(path)):
os.makedirs(dirname(path))
if not file_exists(dirname(abspath(path))):
os.makedirs(dirname(abspath(path)))

if not file_exists(path):
proc = Process([join(self._prefix, 'vlib'), library_name, path], cwd=dirname(self._library_cfg))
Expand Down
7 changes: 4 additions & 3 deletions vunit/ghdl_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ def from_args(cls,
Create instance from args namespace
"""
return cls(gtkwave=args.gtkwave,
gtkwave_args=args.gtkwave_args)
gtkwave_args=args.gtkwave_args,
backend=cls.determine_backend())

@classmethod
def is_available(cls):
Expand All @@ -67,7 +68,7 @@ def is_available(cls):
"""
return len(cls.find_executable('ghdl')) != 0

def __init__(self, gtkwave=None, gtkwave_args=""):
def __init__(self, gtkwave=None, gtkwave_args="", backend="llvm"):
self._libraries = {}
self._vhdl_standard = None

Expand All @@ -76,7 +77,7 @@ def __init__(self, gtkwave=None, gtkwave_args=""):

self._gtkwave = gtkwave
self._gtkwave_args = gtkwave_args
self._backend = self.determine_backend()
self._backend = backend

@staticmethod
def determine_backend():
Expand Down
15 changes: 6 additions & 9 deletions vunit/modelsim_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ def from_args(cls, output_path, args):
"""
persistent = not (args.new_vsim or args.gui)

return cls(join(output_path, "modelsim.ini"),
return cls(prefix=cls._find_prefix(),
modelsim_ini=join(output_path, "modelsim.ini"),
persistent=persistent,
coverage=args.coverage,
gui_mode="load" if args.gui else None)
Expand All @@ -104,7 +105,7 @@ def is_available(cls):
"""
return cls._find_prefix() is not None

def __init__(self, modelsim_ini="modelsim.ini", persistent=False, gui_mode=None, coverage=None):
def __init__(self, prefix, modelsim_ini="modelsim.ini", persistent=False, gui_mode=None, coverage=None):
self._vhdl_standard = None
self._modelsim_ini = abspath(modelsim_ini)

Expand All @@ -117,11 +118,7 @@ def __init__(self, modelsim_ini="modelsim.ini", persistent=False, gui_mode=None,
self._vsim_processes = {}
self._lock = threading.Lock()
self._transcript_id = 0
self._prefix = self._find_prefix()

if self._prefix is None:
raise RuntimeError("Cannot find any ModelSim toolchain.")

self._prefix = prefix
self._libraries = {}

self._persistent = persistent
Expand Down Expand Up @@ -232,8 +229,8 @@ def create_library(self, library_name, path, mapped_libraries=None):
"""
mapped_libraries = mapped_libraries if mapped_libraries is not None else {}

if not file_exists(dirname(path)):
os.makedirs(dirname(path))
if not file_exists(dirname(abspath(path))):
os.makedirs(dirname(abspath(path)))

if not file_exists(path):
proc = Process([join(self._prefix, 'vlib'), '-unix', path])
Expand Down
13 changes: 8 additions & 5 deletions vunit/rivierapro_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ def from_args(cls, output_path, args):
"""
Create new instance from command line arguments object
"""
return cls(join(output_path, "library.cfg"),
return cls(prefix=cls._find_prefix(),
library_cfg=join(output_path, "library.cfg"),
gui=args.gui)

@classmethod
Expand All @@ -61,10 +62,10 @@ def is_available(cls):
"""
return cls._find_prefix() is not None

def __init__(self, library_cfg="library.cfg", gui=False):
def __init__(self, prefix, library_cfg="library.cfg", gui=False):
self._vhdl_standard = None
self._library_cfg = abspath(library_cfg)
self._prefix = self._find_prefix()
self._prefix = prefix
self._gui = gui
self._create_library_cfg()
self._libraries = {}
Expand Down Expand Up @@ -112,6 +113,8 @@ def compile_verilog_file_command(self, source_file):
args += ["-l", library.name]
for include_dir in source_file.include_dirs:
args += ["+incdir+%s" % include_dir]
for key, value in source_file.defines.items():
args += ["+define+%s=%s" % (key, value)]
return args

def create_library(self, library_name, path, mapped_libraries=None):
Expand All @@ -120,8 +123,8 @@ def create_library(self, library_name, path, mapped_libraries=None):
"""
mapped_libraries = mapped_libraries if mapped_libraries is not None else {}

if not file_exists(dirname(path)):
os.makedirs(dirname(path))
if not file_exists(dirname(abspath(path))):
os.makedirs(dirname(abspath(path)))

if not file_exists(path):
proc = Process([join(self._prefix, 'vlib'), library_name, path], cwd=dirname(self._library_cfg))
Expand Down
184 changes: 184 additions & 0 deletions vunit/test/unit/test_activehdl_interface.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Copyright (c) 2016, Lars Asplund [email protected]

"""
Test the ActiveHDL interface
"""


import unittest
from os.path import join, dirname, exists
import os
from shutil import rmtree
from vunit.activehdl_interface import ActiveHDLInterface
from vunit.test.mock_2or3 import mock
from vunit.project import Project
from vunit.ostools import renew_path, write_file


class TestActiveHDLInterface(unittest.TestCase):
"""
Test the ActiveHDL interface
"""

@mock.patch("vunit.simulator_interface.run_command", autospec=True, return_value=True)
@mock.patch("vunit.activehdl_interface.Process", autospec=True)
def test_compile_project_vhdl(self, process, run_command):
library_cfg = join(self.output_path, "library.cfg")
simif = ActiveHDLInterface(prefix="prefix",
library_cfg=library_cfg)
project = Project()
project.add_library("lib", "lib_path")
write_file("file.vhd", "")
project.add_source_file("file.vhd", "lib", file_type="vhdl")
simif.compile_project(project, vhdl_standard="2008")
process.assert_any_call([join("prefix", "vlib"), "lib", "lib_path"], cwd=self.output_path)
process.assert_called_with([join("prefix", "vmap"), "lib", "lib_path"], cwd=self.output_path)
run_command.assert_called_once_with(
[join('prefix', 'vcom'),
'-dbg',
'-quiet',
'-j',
self.output_path,
'-2008',
'-work',
'lib',
'file.vhd'])

@mock.patch("vunit.simulator_interface.run_command", autospec=True, return_value=True)
@mock.patch("vunit.activehdl_interface.Process", autospec=True)
def test_compile_project_vhdl_extra_flags(self, process, run_command):
library_cfg = join(self.output_path, "library.cfg")
simif = ActiveHDLInterface(prefix="prefix",
library_cfg=library_cfg)
project = Project()
project.add_library("lib", "lib_path")
write_file("file.vhd", "")
source_file = project.add_source_file("file.vhd", "lib", file_type="vhdl")
source_file.set_compile_option("activehdl.vcom_flags", ["custom", "flags"])
simif.compile_project(project, vhdl_standard="2008")
process.assert_any_call([join("prefix", "vlib"), "lib", "lib_path"], cwd=self.output_path)
process.assert_called_with([join("prefix", "vmap"), "lib", "lib_path"], cwd=self.output_path)
run_command.assert_called_once_with([join('prefix', 'vcom'),
'-dbg',
'-quiet',
'-j',
self.output_path,
'custom',
'flags',
'-2008',
'-work',
'lib',
'file.vhd'])

@mock.patch("vunit.simulator_interface.run_command", autospec=True, return_value=True)
@mock.patch("vunit.activehdl_interface.Process", autospec=True)
def test_compile_project_verilog(self, process, run_command):
library_cfg = join(self.output_path, "library.cfg")
simif = ActiveHDLInterface(prefix="prefix",
library_cfg=library_cfg)
project = Project()
project.add_library("lib", "lib_path")
write_file("file.v", "")
project.add_source_file("file.v", "lib", file_type="verilog")
simif.compile_project(project, vhdl_standard="2008")
process.assert_any_call([join("prefix", "vlib"), "lib", "lib_path"], cwd=self.output_path)
process.assert_called_with([join("prefix", "vmap"), "lib", "lib_path"], cwd=self.output_path)
run_command.assert_called_once_with([join('prefix', 'vlog'),
'-quiet',
'-sv2k12',
'-lc',
library_cfg,
'-work',
'lib',
'file.v',
'-l', 'lib'])

@mock.patch("vunit.simulator_interface.run_command", autospec=True, return_value=True)
@mock.patch("vunit.activehdl_interface.Process", autospec=True)
def test_compile_project_verilog_extra_flags(self, process, run_command):
library_cfg = join(self.output_path, "library.cfg")
simif = ActiveHDLInterface(prefix="prefix",
library_cfg=library_cfg)
project = Project()
project.add_library("lib", "lib_path")
write_file("file.v", "")
source_file = project.add_source_file("file.v", "lib", file_type="verilog")
source_file.set_compile_option("activehdl.vlog_flags", ["custom", "flags"])
simif.compile_project(project, vhdl_standard="2008")
process.assert_any_call([join("prefix", "vlib"), "lib", "lib_path"], cwd=self.output_path)
process.assert_called_with([join("prefix", "vmap"), "lib", "lib_path"], cwd=self.output_path)
run_command.assert_called_once_with([join('prefix', 'vlog'),
'-quiet',
'-sv2k12',
'-lc',
library_cfg,
'custom',
'flags',
'-work',
'lib',
'file.v',
'-l', 'lib'])

@mock.patch("vunit.simulator_interface.run_command", autospec=True, return_value=True)
@mock.patch("vunit.activehdl_interface.Process", autospec=True)
def test_compile_project_verilog_include(self, process, run_command):
library_cfg = join(self.output_path, "library.cfg")
simif = ActiveHDLInterface(prefix="prefix",
library_cfg=library_cfg)
project = Project()
project.add_library("lib", "lib_path")
write_file("file.v", "")
project.add_source_file("file.v", "lib", file_type="verilog", include_dirs=["include"])
simif.compile_project(project, vhdl_standard="2008")
process.assert_any_call([join("prefix", "vlib"), "lib", "lib_path"], cwd=self.output_path)
process.assert_called_with([join("prefix", "vmap"), "lib", "lib_path"], cwd=self.output_path)
run_command.assert_called_once_with([join('prefix', 'vlog'),
'-quiet',
'-sv2k12',
'-lc',
library_cfg,
'-work',
'lib',
'file.v',
'-l', 'lib',
'+incdir+include'])

@mock.patch("vunit.simulator_interface.run_command", autospec=True, return_value=True)
@mock.patch("vunit.activehdl_interface.Process", autospec=True)
def test_compile_project_verilog_define(self, process, run_command):
library_cfg = join(self.output_path, "library.cfg")
simif = ActiveHDLInterface(prefix="prefix",
library_cfg=library_cfg)
project = Project()
project.add_library("lib", "lib_path")
write_file("file.v", "")
project.add_source_file("file.v", "lib", file_type="verilog", defines={"defname": "defval"})
simif.compile_project(project, vhdl_standard="2008")
process.assert_any_call([join("prefix", "vlib"), "lib", "lib_path"], cwd=self.output_path)
process.assert_called_with([join("prefix", "vmap"), "lib", "lib_path"], cwd=self.output_path)
run_command.assert_called_once_with([join('prefix', 'vlog'),
'-quiet',
'-sv2k12',
'-lc',
library_cfg,
'-work',
'lib',
'file.v',
'-l', 'lib',
'+define+defname=defval'])

def setUp(self):
self.output_path = join(dirname(__file__), "test_activehdl_out")
renew_path(self.output_path)
self.project = Project()
self.cwd = os.getcwd()
os.chdir(self.output_path)

def tearDown(self):
os.chdir(self.cwd)
if exists(self.output_path):
rmtree(self.output_path)
Loading

0 comments on commit b65b5d4

Please sign in to comment.