Commit d3cb6f5b authored by Tristan Gingold's avatar Tristan Gingold

Add 'system' modules (currently only xilinx).

parent 417d1f93
......@@ -34,6 +34,7 @@ from ..sourcefiles import new_dep_solver as dep_solver
from ..sourcefiles.srcfile import VHDLFile, VerilogFile, SVFile
from ..sourcefiles.sourcefileset import SourceFileSet
from ..module.module import Module, ModuleArgs
from ..sourcefiles import systemlibs
class Action(object):
......@@ -43,6 +44,7 @@ class Action(object):
super(Action, self).__init__()
self.top_manifest = None
self.all_manifests = []
self.system_libs = set()
self.parseable_fileset = SourceFileSet()
self.privative_fileset = SourceFileSet()
self._deps_solved = False
......@@ -66,6 +68,12 @@ class Action(object):
self.all_manifests.append(res)
return res
def add_system_lib(self, parent, url):
if url not in self.system_libs:
if url not in systemlibs.all_system_libs:
raise Exception("Unknown system module '{}' in '{}'".format(url, parent))
self.system_libs.add(url)
def load_all_manifests(self):
# Load the top level module (which is in the current directory).
assert self.top_manifest is None
......@@ -146,7 +154,7 @@ class Action(object):
libs = None
if self.tool is not None:
libs = self.tool.get_standard_libs()
dep_solver.solve(self.parseable_fileset, libs)
dep_solver.solve(self.parseable_fileset, self.system_libs, libs)
self._deps_solved = True
if self.options.all_files:
# If option -all is used, no need to compute dependencies.
......
......@@ -83,6 +83,7 @@ class ManifestParser(ConfigParser):
self.add_allowed_key('modules', key="git")
self.add_allowed_key('modules', key="gitsm")
self.add_allowed_key('modules', key="local")
self.add_allowed_key('modules', key="system")
fetch_options = [
{'name': 'fetchto',
'default': None,
......
......@@ -107,6 +107,10 @@ class Module(object):
+ "\nThis module was instantiated in: " + str(self.parent))
self.path = path_mod.relpath(url)
self.isfetched = True
elif self.source == 'system':
self.url, self.branch, self.revision = url, None, None
self.path = '<internal>'
self.isfetch = True
else:
# Split URL (extract basename, revision, branch...)
if self.source == 'svn':
......@@ -268,6 +272,10 @@ class Module(object):
if mod is not None:
mods.append(mod)
self.modules[m] = mods
# Handle 'system'.
paths = path_mod.flatten_list(self.manifest_dict["modules"].get('system', []))
for path in paths:
self.action.add_system_lib(parent=self, url=path)
def _process_manifest_makefiles(self):
"""Get the extra makefiles defined in the HDLMake module"""
......
......@@ -55,7 +55,7 @@ class DepRelation(object):
"""Check if the current dependency relation matches the provided one"""
return (rel_b.rel_type == self.rel_type
and rel_b.obj_name == self.obj_name
and rel_b.lib_name == self.lib_name)
and (self.lib_name is None or rel_b.lib_name == self.lib_name))
def __repr__(self):
ostr = {
......
......@@ -28,6 +28,7 @@ from __future__ import absolute_import
import logging
from ..sourcefiles.dep_file import DepFile
from .systemlibs import all_system_libs
class DepParser(object):
......@@ -42,14 +43,14 @@ class DepParser(object):
pass
def solve(fileset, standard_libs=None):
def solve(fileset, syslibs, standard_libs=None):
"""Function that Parses and Solves the provided HDL fileset. Note
that it doesn't return a new fileset, but modifies the original one"""
from .sourcefileset import SourceFileSet
from .dep_file import DepRelation
assert isinstance(fileset, SourceFileSet)
fset = fileset.filter(DepFile)
# Parse source files
logging.debug("PARSE BEGIN: Here, we will parse all the files in the "
"fileset: no parsing should be done beyond this point")
......@@ -60,6 +61,11 @@ def solve(fileset, standard_libs=None):
investigated_file.parser.parse(investigated_file)
logging.debug("PARSE END: now the parsing is done")
# Dependencies provided by system libraries.
system_rels = []
for e in syslibs:
system_rels.extend(all_system_libs[e]())
logging.debug("SOLVE BEGIN")
not_satisfied = 0
for investigated_file in fset:
......@@ -74,6 +80,9 @@ def solve(fileset, standard_libs=None):
# A file cannot depends on itself.
investigated_file.depends_on.add(dep_file)
satisfied_by.add(dep_file)
if len(satisfied_by) == 1:
# Perfect!
continue
if len(satisfied_by) > 1:
logging.warning(
"Relation %s satisfied by multiple (%d) files:\n %s",
......@@ -81,22 +90,34 @@ def solve(fileset, standard_libs=None):
len(satisfied_by),
'\n '.join([file_aux.path for
file_aux in list(satisfied_by)]))
elif len(satisfied_by) == 0:
# if relation is a USE PACKAGE, check against
# the standard libs provided by the tool HDL compiler
required_lib = rel.lib_name
if (standard_libs is not None
and rel.rel_type is DepRelation.PACKAGE
and required_lib in standard_libs):
logging.debug("Not satisfied relation %s in %s will "
"be covered by the target compiler "
"standard libs.",
str(rel), investigated_file.name)
else:
logging.warning("Relation %s in %s not satisfied by "
"any source file",
str(rel), investigated_file.name)
not_satisfied += 1
continue
# So we are handling an unsatisfied dependency.
assert(len(satisfied_by) == 0)
# Maybe provided by system libraries
found = False
for r in system_rels:
if r.satisfies(rel):
found = True
break
if found:
continue
# if relation is a USE PACKAGE, check against
# the standard libs provided by the tool HDL compiler
required_lib = rel.lib_name
if (standard_libs is not None
and rel.rel_type is DepRelation.PACKAGE
and required_lib in standard_libs):
logging.debug("Not satisfied relation %s in %s will "
"be covered by the target compiler "
"standard libs.",
str(rel), investigated_file.name)
continue
logging.warning("Relation %s in %s not satisfied by "
"any source file",
str(rel), investigated_file.name)
not_satisfied += 1
logging.debug("SOLVE END")
if not_satisfied != 0:
logging.warning(
......
#!/usr/bin/python
#
# Copyright (c) 2020 CERN
#
# This file is part of Hdlmake.
#
# Hdlmake is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Hdlmake is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
from .dep_file import DepRelation
def add_entity(res, name):
res.append(DepRelation(name, None, DepRelation.ENTITY))
def add_package(res, lib, name):
res.append(DepRelation(name, lib, DepRelation.PACKAGE))
def build_xilinx():
"""Modules and packages provided by Xilinx system libraries"""
res = []
add_package(res, 'unisim', 'vcomponents')
for n in ['ibufds', 'ibufgds', 'ibufds_diff_out',
'ibufds_gte2',
'obufds', 'bufio',
'oserdes2', 'oserdese2', 'iserdese2', 'iodelay2', 'odelaye2', 'idelaye2', 'idelayctrl',
'bufgmux_ctrl', 'bufg', 'bufr', 'bufpll',
'startupe2',
'mmcme2_adv', 'mmcme2_base', 'pll_base', 'dcm_base', 'dcm_adv', 'dcm_sp',
'icap_spartan6', 'gtxe2_channel',
'srlc32e']:
add_entity(res, n)
return res
all_system_libs = {'xilinx': build_xilinx}
\ No newline at end of file
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