Commit ce11eb90 authored by Tristan Gingold's avatar Tristan Gingold

Rework verilog include dependencies.

They are now handled separately, as they aren't source files.
parent 1f6dad04
...@@ -138,6 +138,7 @@ class DepFile(File): ...@@ -138,6 +138,7 @@ class DepFile(File):
self.provides = set() self.provides = set()
self.requires = set() self.requires = set()
self.depends_on = set() # Set of files this file depends on. self.depends_on = set() # Set of files this file depends on.
self.included_files = set()
self.dep_level = None self.dep_level = None
self.is_parsed = False self.is_parsed = False
......
...@@ -40,10 +40,7 @@ class SourceFile(DepFile): ...@@ -40,10 +40,7 @@ class SourceFile(DepFile):
def __init__(self, path, module, library): def __init__(self, path, module, library):
assert isinstance(path, six.string_types) assert isinstance(path, six.string_types)
self.is_include = False self.library = library or "work"
self.library = library
if not library:
self.library = "work"
DepFile.__init__(self, path=path, module=module) DepFile.__init__(self, path=path, module=module)
def __hash__(self): def __hash__(self):
...@@ -66,16 +63,12 @@ class VerilogFile(SourceFile): ...@@ -66,16 +63,12 @@ class VerilogFile(SourceFile):
"""This is the class providing the generic Verilog file""" """This is the class providing the generic Verilog file"""
def __init__(self, path, module, library=None, def __init__(self, path, module, library=None, include_dirs=None):
include_dirs=None, is_include=False):
SourceFile.__init__(self, path=path, module=module, library=library) SourceFile.__init__(self, path=path, module=module, library=library)
from .vlog_parser import VerilogParser from .vlog_parser import VerilogParser
self.include_dirs = [] self.include_dirs = include_dirs[:] if include_dirs else []
if include_dirs:
self.include_dirs.extend(include_dirs)
self.include_dirs.append(path_mod.relpath(self.dirname)) self.include_dirs.append(path_mod.relpath(self.dirname))
self.parser = VerilogParser(self) self.parser = VerilogParser(self)
self.is_include = is_include
class SVFile(VerilogFile): class SVFile(VerilogFile):
...@@ -322,8 +315,7 @@ ALTERA_FILE_DICT = { ...@@ -322,8 +315,7 @@ ALTERA_FILE_DICT = {
'gdf': GDFFile} 'gdf': GDFFile}
def create_source_file(path, module, library=None, def create_source_file(path, module, library=None, include_dirs=None):
include_dirs=None, is_include=False):
"""Function that analyzes the given arguments and returns a new HDL source """Function that analyzes the given arguments and returns a new HDL source
file of the appropriated type""" file of the appropriated type"""
assert path assert path
...@@ -342,14 +334,12 @@ def create_source_file(path, module, library=None, ...@@ -342,14 +334,12 @@ def create_source_file(path, module, library=None,
new_file = VerilogFile(path=path, new_file = VerilogFile(path=path,
module=module, module=module,
library=library, library=library,
include_dirs=include_dirs, include_dirs=include_dirs)
is_include=is_include)
elif extension == 'sv' or extension == 'svh': elif extension == 'sv' or extension == 'svh':
new_file = SVFile(path=path, new_file = SVFile(path=path,
module=module, module=module,
library=library, library=library,
include_dirs=include_dirs, include_dirs=include_dirs)
is_include=is_include)
elif extension == 'wb': elif extension == 'wb':
new_file = WBGenFile(path=path, module=module) new_file = WBGenFile(path=path, module=module)
elif extension == 'tcl': elif extension == 'tcl':
......
...@@ -60,8 +60,7 @@ class VerilogPreprocessor(object): ...@@ -60,8 +60,7 @@ class VerilogPreprocessor(object):
self.vlog_file = None self.vlog_file = None
# List of macro definitions # List of macro definitions
self.vpp_macros = [] self.vpp_macros = []
# Dictionary of files sub-included by each file parsed self.included_files = set()
self.vpp_filedeps = {}
self.macro_depth = 0 self.macro_depth = 0
def _search_include(self, filename, parent_dir=None): def _search_include(self, filename, parent_dir=None):
...@@ -192,8 +191,7 @@ class VerilogPreprocessor(object): ...@@ -192,8 +191,7 @@ class VerilogPreprocessor(object):
"includes %s", "includes %s",
file_name, library, included_file_path) file_name, library, included_file_path)
# add include file to the dependancies # add include file to the dependancies
self.vpp_filedeps[file_name + library].append( self.included_files.add(included_file_path)
included_file_path)
# tokenize the file & prepend to the current stack # tokenize the file & prepend to the current stack
decomment = _remove_comment(open(included_file_path).read()) decomment = _remove_comment(open(included_file_path).read())
tokens = _tok_string(decomment) tokens = _tok_string(decomment)
...@@ -222,7 +220,6 @@ class VerilogPreprocessor(object): ...@@ -222,7 +220,6 @@ class VerilogPreprocessor(object):
return re.sub(r'^\s*\n','', _proc_macros_layer(parts, vpp_macros)[0], flags=re.MULTILINE) return re.sub(r'^\s*\n','', _proc_macros_layer(parts, vpp_macros)[0], flags=re.MULTILINE)
# init dependencies # init dependencies
self.vpp_filedeps[file_name + library] = []
logging.debug("preprocess file %s (of length %d) in library %s", logging.debug("preprocess file %s (of length %d) in library %s",
file_name, len(file_content), library) file_name, len(file_content), library)
buf = _filter_protected_regions(_remove_comment(file_content)) buf = _filter_protected_regions(_remove_comment(file_content))
...@@ -500,14 +497,8 @@ class VerilogParser(DepParser): ...@@ -500,14 +497,8 @@ class VerilogParser(DepParser):
# Preprocess the file and add included files as dependencies # Preprocess the file and add included files as dependencies
buf = self.preprocessor.preprocess(dep_file) buf = self.preprocessor.preprocess(dep_file)
includes = self.preprocessor.vpp_filedeps[ dep_file.included_files = self.preprocessor.included_files
dep_file.path + dep_file.library] logging.debug("%s has %d includes.", str(dep_file), len(dep_file.included_files))
for file_aux in includes:
dep_file.depends_on.add(
create_source_file(path=file_aux,
module=dep_file.module,
is_include=True))
logging.debug("%s has %d includes.", str(dep_file), len(includes))
# look for packages used inside in file # look for packages used inside in file
# it may generate false dependencies as package in SV can be used by: # it may generate false dependencies as package in SV can be used by:
...@@ -588,4 +579,5 @@ class VerilogParser(DepParser): ...@@ -588,4 +579,5 @@ class VerilogParser(DepParser):
if match: if match:
do_inst(match) do_inst(match)
m_inside_module.subn(do_module, buf) m_inside_module.subn(do_module, buf)
dep_file.is_parsed = True dep_file.is_parsed = True
...@@ -8,7 +8,7 @@ import logging ...@@ -8,7 +8,7 @@ import logging
from .makefile import ToolMakefile from .makefile import ToolMakefile
from ..util import shell from ..util import shell
from ..sourcefiles.srcfile import VerilogFile, VHDLFile, SVFile from ..sourcefiles.srcfile import VerilogFile, VHDLFile, SVFile
from ..util import path as path_mod
def _check_simulation_manifest(top_manifest): def _check_simulation_manifest(top_manifest):
"""Check if the simulation keys are provided by the top manifest""" """Check if the simulation keys are provided by the top manifest"""
...@@ -75,14 +75,10 @@ TOP_MODULE := {top_module} ...@@ -75,14 +75,10 @@ TOP_MODULE := {top_module}
fileset = self.fileset fileset = self.fileset
self.write("VERILOG_SRC := ") self.write("VERILOG_SRC := ")
for vlog in fileset.filter(VerilogFile).sort(): for vlog in fileset.filter(VerilogFile).sort():
if vlog.is_include:
continue
self.writeln(vlog.rel_path() + " \\") self.writeln(vlog.rel_path() + " \\")
self.writeln() self.writeln()
self.write("VERILOG_OBJ := ") self.write("VERILOG_OBJ := ")
for vlog in fileset.filter(VerilogFile).sort(): for vlog in fileset.filter(VerilogFile).sort():
if vlog.is_include:
continue
# make a file compilation indicator (these .dat files are made even # make a file compilation indicator (these .dat files are made even
# if the compilation process fails) and add an ending according # if the compilation process fails) and add an ending according
# to file's extension (.sv and .vhd files may have the same # to file's extension (.sv and .vhd files may have the same
...@@ -102,6 +98,7 @@ TOP_MODULE := {top_module} ...@@ -102,6 +98,7 @@ TOP_MODULE := {top_module}
def _makefile_sim_dep_files(self): def _makefile_sim_dep_files(self):
"""Print dummy targets to handle file dependencies""" """Print dummy targets to handle file dependencies"""
cwd = os.getcwd()
fileset = self.fileset.sort() fileset = self.fileset.sort()
for file_aux in fileset: for file_aux in fileset:
# Consider only HDL files. # Consider only HDL files.
...@@ -112,21 +109,15 @@ TOP_MODULE := {top_module} ...@@ -112,21 +109,15 @@ TOP_MODULE := {top_module}
if dep_file is file_aux: if dep_file is file_aux:
# Do not depend on itself. # Do not depend on itself.
continue continue
if dep_file in fileset: self.write(" \\\n" + self.get_stamp_file(dep_file))
self.write(" \\\n" + self.get_stamp_file(dep_file)) for dep_file in sorted(file_aux.included_files):
else: self.write(" \\\n{}".format(path_mod.relpath(dep_file, cwd)))
# the file is included -> we depend directly on it
self.write(" \\\n" + dep_file.rel_path())
self.writeln() self.writeln()
is_include = False
if isinstance(file_aux, VHDLFile): if isinstance(file_aux, VHDLFile):
command_key = 'vhdl' command_key = 'vhdl'
elif (isinstance(file_aux, VerilogFile) or elif (isinstance(file_aux, VerilogFile) or
isinstance(file_aux, SVFile)): isinstance(file_aux, SVFile)):
is_include = file_aux.is_include
command_key = 'vlog' command_key = 'vlog'
if is_include:
continue
self.writeln("\t\t" + self.SIMULATOR_CONTROLS[command_key]) self.writeln("\t\t" + self.SIMULATOR_CONTROLS[command_key])
self.write("\t\t@" + shell.mkdir_command() + " $(dir $@)") self.write("\t\t@" + shell.mkdir_command() + " $(dir $@)")
self.writeln(" && " + shell.touch_command() + " $@ \n") self.writeln(" && " + shell.touch_command() + " $@ \n")
......
...@@ -96,13 +96,10 @@ endif""") ...@@ -96,13 +96,10 @@ endif""")
file_list = [] file_list = []
for file_aux in self.fileset: for file_aux in self.fileset:
if isinstance(file_aux, filetype): if isinstance(file_aux, filetype):
if ( if filetype == VerilogFile and isinstance(file_aux, SVFile):
not (filetype == VerilogFile and # Discard SVerilog files for verilog type.
isinstance(file_aux, SVFile)) and continue
not (isinstance(file_aux, VerilogFile) and file_list.append(shell.tclpath(file_aux.rel_path()))
file_aux.is_include)
):
file_list.append(shell.tclpath(file_aux.rel_path()))
if not file_list == []: if not file_list == []:
ret.append( ret.append(
'SOURCES_{0} := \\\n' 'SOURCES_{0} := \\\n'
......
...@@ -30,6 +30,7 @@ import string ...@@ -30,6 +30,7 @@ import string
from .makefilesim import MakefileSim from .makefilesim import MakefileSim
from ..util import shell from ..util import shell
from ..sourcefiles.srcfile import VerilogFile, VHDLFile, SVFile from ..sourcefiles.srcfile import VerilogFile, VHDLFile, SVFile
from ..util import path as path_mod
import six import six
...@@ -92,8 +93,10 @@ class MakefileVsim(MakefileSim): ...@@ -92,8 +93,10 @@ class MakefileVsim(MakefileSim):
\t\t%s $< . 2>&1 \t\t%s $< . 2>&1
""" % (name, src, shell.copy_command()) """ % (name, src, shell.copy_command())
return rule return rule
cwd = os.getcwd()
fileset = self.fileset fileset = self.fileset
if self.manifest_dict.get("include_dirs") == None: if self.manifest_dict.get("include_dirs") is None:
self.writeln("INCLUDE_DIRS :=") self.writeln("INCLUDE_DIRS :=")
else: else:
self.writeln("INCLUDE_DIRS := +incdir+%s" % self.writeln("INCLUDE_DIRS := +incdir+%s" %
...@@ -112,10 +115,7 @@ class MakefileVsim(MakefileSim): ...@@ -112,10 +115,7 @@ class MakefileVsim(MakefileSim):
"simulation: %s $(LIB_IND) $(VERILOG_OBJ) $(VHDL_OBJ)" % "simulation: %s $(LIB_IND) $(VERILOG_OBJ) $(VHDL_OBJ)" %
(' '.join(self.additional_deps)),) (' '.join(self.additional_deps)),)
self.writeln("$(VERILOG_OBJ) : " + ' '.join(self.additional_deps)) self.writeln("$(VERILOG_OBJ) : " + ' '.join(self.additional_deps))
self.writeln( self.writeln("$(VHDL_OBJ): $(LIB_IND) " + ' '.join(self.additional_deps))
"$(VHDL_OBJ): $(LIB_IND) " +
' '.join(
self.additional_deps))
self.writeln() self.writeln()
for filename, filesource in six.iteritems(self.copy_rules): for filename, filesource in six.iteritems(self.copy_rules):
self.write(__create_copy_rule(filename, filesource)) self.write(__create_copy_rule(filename, filesource))
...@@ -129,23 +129,19 @@ class MakefileVsim(MakefileSim): ...@@ -129,23 +129,19 @@ class MakefileVsim(MakefileSim):
self.write('\n\n') self.write('\n\n')
# rules for all _primary.dat files for sv # rules for all _primary.dat files for sv
for vlog in fileset.filter(VerilogFile).sort(): for vlog in fileset.filter(VerilogFile).sort():
if vlog.is_include:
continue
self.write("%s: %s" % (os.path.join( self.write("%s: %s" % (os.path.join(
vlog.library, vlog.purename, vlog.library, vlog.purename,
".%s_%s" % (vlog.purename, vlog.extension())), ".%s_%s" % (vlog.purename, vlog.extension())),
vlog.rel_path())) vlog.rel_path()))
# list dependencies, do not include the target file # list dependencies, do not include the target file
for dep_file in sorted([dfile for dfile for dep_file in sorted(vlog.depends_on, key=(lambda x: x.path)):
in vlog.depends_on if dfile is not vlog], if dep_file is not vlog:
key=(lambda x: x.path)):
if dep_file in fileset and not dep_file.is_include:
name = dep_file.purename name = dep_file.purename
extension = dep_file.extension() extension = dep_file.extension()
self.write(" \\\n" + os.path.join( self.write(" \\\n" + os.path.join(
dep_file.library, name, ".%s_%s" % (name, extension))) dep_file.library, name, ".%s_%s" % (name, extension)))
else: # the file is included -> we depend directly on the file for dep_file in sorted(vlog.included_files):
self.write(" \\\n" + dep_file.rel_path()) self.write(" \\\n{}".format(path_mod.relpath(dep_file, cwd)))
self.writeln() self.writeln()
compile_template = string.Template( compile_template = string.Template(
"\t\tvlog -work ${library} $$(VLOG_FLAGS) " "\t\tvlog -work ${library} $$(VLOG_FLAGS) "
......
...@@ -25,9 +25,8 @@ include_dirs: ...@@ -25,9 +25,8 @@ include_dirs:
echo "+incdir+inc" >> run.command echo "+incdir+inc" >> run.command
work/macros/.macros_v: inc/macros.v
work/vlog/.vlog_v: vlog.v \ work/vlog/.vlog_v: vlog.v \
work/macros/.macros_v inc/macros.v
echo $< >> run.command echo $< >> run.command
@mkdir -p $(dir $@) && touch $@ @mkdir -p $(dir $@) && touch $@
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment