# 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
#
# Python Class: TODO
#
# License:
# ==============================================================================
# Copyright 2007-2016 Technische Universitaet 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 collections import OrderedDict
from enum import Enum, unique
from pathlib import Path
from flags import Flags
from lib.Functions import Init
from lib.Decorators import LazyLoadTrigger, ILazyLoadable
from ToolChain import ConfigurationException
__api__ = [
'EntityTypes',
'_PoCEntityTypes_parser',
'BaseFlags',
'TestbenchKind', 'NetlistKind',
'NamespaceRoot',
'Visibility',
'PathElement',
'Namespace',
'Library',
'WildCard', 'StarWildCard', 'AskWildCard',
'IPCore',
'LazyPathElement',
'Testbench', 'VHDLTestbench', 'CocoTestbench',
'Netlist', 'XstNetlist', 'QuartusNetlist', 'LatticeNetlist', 'CoreGeneratorNetlist', 'VivadoNetlist',
'FQN'
]
__all__ = __api__
@unique
[docs]class EntityTypes(Enum):
Unknown = 0
Source = 1
Testbench = 2
NetList = 3
def __str__(self):
if (self is EntityTypes.Unknown): return "??"
elif (self is EntityTypes.Source): return "src"
elif (self is EntityTypes.Testbench): return "tb"
elif (self is EntityTypes.NetList): return "nl"
[docs]def _PoCEntityTypes_parser(cls, value):
if not isinstance(value, str):
return Enum.__new__(cls, value)
else:
# map strings to enum values, default to Unknown
return {
'src': EntityTypes.Source,
'tb': EntityTypes.Testbench,
'nl': EntityTypes.NetList
}.get(value, EntityTypes.Unknown)
# override __new__ method in EntityTypes with _PoCEntityTypes_parser
setattr(EntityTypes, '__new__', _PoCEntityTypes_parser)
[docs]class BaseFlags(Flags):
__no_flags_name__ = "Unknown"
__all_flags_name__ = "All"
[docs]class TestbenchKind(BaseFlags):
VHDLTestbench = ()
CocoTestbench = ()
[docs]class NetlistKind(BaseFlags):
LatticeNetlist = ()
QuartusNetlist = ()
XstNetlist = ()
CoreGeneratorNetlist = ()
VivadoNetlist = ()
[docs]class NamespaceRoot:
__POCRoot_Name = "PoC"
__POCRoot_SectionName = "PoC"
def __init__(self, host):
self._host = host
self.__libraries = OrderedDict()
self.__libraries[self.__POCRoot_Name.lower()] = (Library(host, self.__POCRoot_Name, self.__POCRoot_SectionName, self))
@property
def Libraries(self): return [lib for lib in self.__libraries.values()]
@property
def LibraryNames(self): return [libName for libName in self.__libraries.keys()]
[docs] def GetLibraries(self): return self.__libraries.values()
[docs] def GetLibraryNames(self): return self.__libraries.keys()
def __contains__(self, item):
return item.lower() in self.__libraries
def __getitem__(self, key):
key = key.lower()
return self.__libraries[key]
[docs] def AddLibrary(self, libraryName, libraryPrefix):
self.__libraries[libraryName.lower()] = (Library(self._host, libraryName, libraryPrefix, self))
@unique
[docs]class Visibility(Enum):
Unknown = 0
Private = 1
Public = 2
def __eq__(self, other): return self.value == other.value
def __ne__(self, other): return self.value != other.value
def __lt__(self, other): return self.value < other.value
def __le__(self, other): return self.value <= other.value
def __gt__(self, other): return self.value > other.value
def __ge__(self, other): return self.value >= other.value
@classmethod
def Parse(cls, value):
for key,member in cls.__members__.items():
if (key == value):
return member
raise ValueError("'{0!s}' is not a valid {1}".format(value, cls.__name__))
[docs]class PathElement:
def __init__(self, host, name, configSectionName, parent):
self._host = host
self._name = name
self._parent = parent
self._configSectionName = configSectionName
self._visibility = Visibility.Unknown
self._Load()
@property
def Name(self): return self._name
@property
def Parent(self): return self._parent
@property
def ConfigSectionName(self): return self._configSectionName
@property
def ConfigSection(self): return self._host.PoCConfig[self._configSectionName]
@property
def Level(self): return self._parent.Level + 1
@property
def Visibility(self): return self._visibility
@property
def IsVisible(self): return self._host.Repository.Kind <= self._visibility
@property
def Path(self):
cur = self
result = []
while True:
result.insert(0, cur)
cur = cur.Parent
if isinstance(cur, Library):
break
else:
raise ConfigurationException("Hierarchy error. Expected Library.")
return result
[docs] def _Load(self):
self._visibility = Visibility.Parse(self.ConfigSection['Visibility'])
def __str__(self):
return "{0!s}.{1}".format(self.Parent, self.Name)
[docs]class Namespace(PathElement):
def __init__(self, host, name, configSectionName, parent):
self.__namespaces = OrderedDict()
self.__entities = OrderedDict()
super().__init__(host, name, configSectionName, parent)
[docs] def _Load(self):
super()._Load()
for optionName in self.ConfigSection:
kind = self.ConfigSection[optionName]
if (kind == "Namespace"):
# print("loading namespace: {0}".format(optionName))
section = self._configSectionName + "." + optionName
ns = Namespace(host=self._host, name=optionName, configSectionName=section, parent=self)
self.__namespaces[optionName.lower()] = ns
elif (kind == "Entity"):
# print("loading entity: {0}".format(optionName))
section = ".".join(["IP"] + self._configSectionName.split(".")[1:] + [optionName])
ent = IPCore(host=self._host, name=optionName, configSectionName=section, parent=self)
self.__entities[optionName.lower()] = ent
@property
def Namespaces(self): return [ns for ns in self.GetNamespaces()]
@property
def NamespaceNames(self): return [nsName for nsName in self.GetNamespaceNames()]
@property
def Entities(self): return [entity for entity in self.GetEntities()]
@property
def EntityNames(self): return [entityName for entityName in self.GetEntityNames()]
[docs] def GetNamespaces(self):
for namespace in self.__namespaces.values():
if namespace.IsVisible:
yield namespace
[docs] def GetNamespaceNames(self):
for namespace in self.__namespaces.values():
if namespace.IsVisible:
yield namespace.Name
[docs] def GetEntities(self):
for entity in self.__entities.values():
if entity.IsVisible:
yield entity
[docs] def GetEntityNames(self):
for entity in self.__entities.values():
if entity.IsVisible:
yield entity.Name
[docs] def GetAllEntities(self):
for namespace in self.GetNamespaces():
for entity in namespace.GetAllEntities():
yield entity
for entity in self.GetEntities():
yield entity
def __getitem__(self, key):
key = key.lower()
try:
item = self.__namespaces[key]
except KeyError:
item = self.__entities[key]
if (not item.IsVisible):
raise KeyError("Item '{0!s}' is not visible.".format(key))
return item
[docs] def pprint(self, indent=0):
__indent = " " * indent
buffer = "{0}{1}\n".format(__indent, self.Name)
for ent in self.GetEntities():
buffer += ent.pprint(indent + 1)
for ns in self.GetNamespaces():
buffer += ns.pprint(indent + 1)
return buffer
[docs]class Library(Namespace):
@property
def Level(self):
return 0
def __str__(self):
return self.Name
[docs]class WildCard(PathElement):
[docs] def GetEntities(self):
raise NotImplementedError()
[docs] def GetTestbenches(self, kind=TestbenchKind.All):
for entity in self.GetEntities():
for tb in entity.GetTestbenches():
if (tb.Kind in kind):
yield tb
[docs] def GetVHDLTestbenches(self): return self.GetTestbenches(TestbenchKind.VHDLTestbench)
[docs] def GetCocoTestbenches(self): return self.GetTestbenches(TestbenchKind.CocoTestbench)
[docs] def GetNetlists(self, kind=NetlistKind.All):
for entity in self.GetEntities():
for nl in entity.GetNetlists(kind):
if (nl.Kind in kind):
yield nl
[docs] def GetLatticeNetlists(self): return self.GetNetlists(NetlistKind.LatticeNetlist)
[docs] def GetQuartusNetlists(self): return self.GetNetlists(NetlistKind.QuartusNetlist)
[docs] def GetXSTNetlists(self): return self.GetNetlists(NetlistKind.XstNetlist)
[docs] def GetCoreGenNetlists(self): return self.GetNetlists(NetlistKind.CoreGeneratorNetlist)
[docs] def GetVivadoNetlists(self): return self.GetNetlists(NetlistKind.VivadoNetlist)
@property
def Testbenches(self): return [tb for tb in self.GetTestbenches()]
@property
def VHDLTestbenches(self): return [tb for tb in self.GetVHDLTestbenches()]
@property
def CocoTestbenches(self): return [tb for tb in self.GetCocoTestbenches()]
@property
def Netlists(self): return [tb for tb in self.GetNetlists()]
@property
def LatticeNetlists(self): return [nl for nl in self.GetLatticeNetlists()]
@property
def QuartusNetlists(self): return [nl for nl in self.GetQuartusNetlists()]
@property
def XSTNetlists(self): return [nl for nl in self.GetXSTNetlists()]
@property
def CoreGenNetlists(self): return [nl for nl in self.GetCoreGenNetlists()]
@property
def VivadoNetlists(self): return [nl for nl in self.GetVivadoNetlists()]
[docs]class StarWildCard(WildCard):
[docs] def GetEntities(self):
for entity in self._parent.GetAllEntities():
yield entity
[docs]class AskWildCard(WildCard):
[docs] def GetEntities(self):
for entity in self._parent.GetEntities():
yield entity
[docs]class IPCore(PathElement):
def __init__(self, host, name, configSectionName, parent):
self._dependencies = []
# Testbenches
self._vhdltb = [] # OrderedDict()
self._cocotb = [] # OrderedDict()
# Netlists
self._latticeNetlist = [] # OrderedDict()
self._quartusNetlist = [] # OrderedDict()
self._xstNetlist = [] # OrderedDict()
self._coreGenNetlist = [] # OrderedDict()
self._vivadoNetlist = [] # OrderedDict()
super().__init__(host, name, configSectionName, parent)
@property
def Dependencies(self): return self._dependencies
@property
def VHDLTestbench(self):
if (len(self._vhdltb) == 0):
raise ConfigurationException("No VHDL testbench configured for '{0!s}'.".format(self))
return self._vhdltb[0]
@property
def CocoTestbench(self):
if (len(self._cocotb) == 0):
raise ConfigurationException("No Cocotb testbench configured for '{0!s}'.".format(self))
return self._cocotb[0]
[docs] def GetTestbenches(self, kind=TestbenchKind.All):
if (TestbenchKind.VHDLTestbench in kind):
for tb in self._vhdltb:
if tb.IsVisible:
yield tb
if (TestbenchKind.CocoTestbench in kind):
for tb in self._cocotb:
if tb.IsVisible:
yield tb
@property
def LatticeNetlist(self):
if (len(self._latticeNetlist) == 0):
raise ConfigurationException("No Lattice netlist configured for '{0!s}'.".format(self))
return self._latticeNetlist[0]
@property
def QuartusNetlist(self):
if (len(self._quartusNetlist) == 0):
raise ConfigurationException("No Quartus-II netlist configured for '{0!s}'.".format(self))
return self._quartusNetlist[0]
@property
def XSTNetlist(self):
if (len(self._xstNetlist) == 0):
raise ConfigurationException("No XST netlist configured for '{0!s}'.".format(self))
return self._xstNetlist[0]
@property
def CGNetlist(self):
if (len(self._coreGenNetlist) == 0):
raise ConfigurationException("No CoreGen netlist configured for '{0!s}'.".format(self))
return self._coreGenNetlist[0]
@property
def VivadoNetlist(self):
if (len(self._vivadoNetlist) == 0):
raise ConfigurationException("No Vivado netlist configured for '{0!s}'.".format(self))
return self._vivadoNetlist[0]
[docs] def GetNetlists(self, kind=NetlistKind.All): # mccabe:disable=MC0001
if (NetlistKind.LatticeNetlist in kind):
for nl in self._latticeNetlist:
if nl.IsVisible:
yield nl
if (NetlistKind.QuartusNetlist in kind):
for nl in self._quartusNetlist:
if nl.IsVisible:
yield nl
if (NetlistKind.XstNetlist in kind):
for nl in self._xstNetlist:
if nl.IsVisible:
yield nl
if (NetlistKind.CoreGeneratorNetlist in kind):
for nl in self._coreGenNetlist:
if nl.IsVisible:
yield nl
if (NetlistKind.VivadoNetlist in kind):
for nl in self._vivadoNetlist:
if nl.IsVisible:
yield nl
[docs] def _Load(self):
super()._Load()
section = self.ConfigSection
# load dependencies (as names)
self._dependencies = section['Dependencies'].split()
# load testbenches and netlists
for optionName in section:
kind = section[optionName].lower()
if (kind == "vhdltestbench"):
sectionName = self._configSectionName.replace("IP", "TB") + "." + optionName
tb = VHDLTestbench(host=self._host, name=optionName, configSectionName=sectionName, parent=self)
self._vhdltb.append(tb)
# self._vhdltb[optionName] = tb
elif (kind == "cocotestbench"):
sectionName = self._configSectionName.replace("IP", "COCOTB") + "." + optionName
tb = CocoTestbench(host=self._host, name=optionName, configSectionName=sectionName, parent=self)
self._cocotb.append(tb)
# self._cocotb[optionName] = tb
elif (kind == "lsenetlist"):
sectionName = self._configSectionName.replace("IP", "LSE") + "." + optionName
nl = LatticeNetlist(host=self._host, name=optionName, configSectionName=sectionName, parent=self)
self._latticeNetlist.append(nl)
# self._xstNetlist[optionName] = nl
elif (kind == "quartusnetlist"):
sectionName = self._configSectionName.replace("IP", "QMAP") + "." + optionName
nl = QuartusNetlist(host=self._host, name=optionName, configSectionName=sectionName, parent=self)
self._quartusNetlist.append(nl)
# self._xstNetlist[optionName] = nl
elif (kind == "xstnetlist"):
sectionName = self._configSectionName.replace("IP", "XST") + "." + optionName
nl = XstNetlist(host=self._host, name=optionName, configSectionName=sectionName, parent=self)
self._xstNetlist.append(nl)
# self._xstNetlist[optionName] = nl
elif (kind == "coregennetlist"):
sectionName = self._configSectionName.replace("IP", "CG") + "." + optionName
nl = CoreGeneratorNetlist(host=self._host, name=optionName, configSectionName=sectionName, parent=self)
self._coreGenNetlist.append(nl)
# self._coreGenNetlist[optionName] = nl
elif (kind == "vivadonetlist"):
sectionName = self._configSectionName.replace("IP", "VIVADO") + "." + optionName
nl = VivadoNetlist(host=self._host, name=optionName, configSectionName=sectionName, parent=self)
self._vivadoNetlist.append(nl)
# self._vivadoNetlist[optionName] = nl
[docs] def pprint(self, indent=0):
buffer = "{0}Entity: {1}\n".format(" " * indent, self.Name)
if (len(self._vhdltb) > 0):
buffer += self._vhdltb.pprint(indent + 1)
if (len(self._cocotb) > 0):
buffer += self._cocotb.pprint(indent + 1)
if (len(self._xstNetlist) > 0):
buffer += self._xstNetlist.pprint(indent + 1)
if (len(self._coreGenNetlist) > 0):
buffer += self._coreGenNetlist.pprint(indent + 1)
if (len(self._vivadoNetlist) > 0):
buffer += self._vivadoNetlist.pprint(indent + 1)
return buffer
[docs]class LazyPathElement(PathElement, ILazyLoadable):
def __init__(self, host, name, configSectionName, parent):
self._kind = None
super().__init__(host, name, configSectionName, parent)
ILazyLoadable.__init__(self)
@property
def Kind(self): return self._kind
def __str__(self):
return "{0!s}.{1}".format(self._parent, self._name)
@unique
[docs]class SimulationResult(Enum):
"""Simulation result enumeration."""
NotRun = 0
DryRun = 1
Error = 2
Failed = 3
NoAsserts = 4
Passed = 5
GUIRun = 6
[docs]class Testbench(LazyPathElement):
def __init__(self, host, name, configSectionName, parent):
self._kind = TestbenchKind.Unknown
self._moduleName = ""
self._filesFile = None
self._result = SimulationResult.NotRun
super().__init__(host, name, configSectionName, parent)
@property
@LazyLoadTrigger
def ModuleName(self): return self._moduleName
@property
@LazyLoadTrigger
def FilesFile(self): return self._filesFile
@property
def Result(self): return self._result
@Result.setter
def Result(self, value): self._result = value
# def __setattr__(self, key, value):
# super().__setattr__(key, value)
[docs] def _LazyLoadable_Load(self):
super()._LazyLoadable_Load()
self._moduleName = self.ConfigSection["TestbenchModule"]
self._filesFile = Path(self.ConfigSection["FilesFile"])
[docs] def pprint(self, indent):
__indent = " " * indent
buffer = "{0}Testbench:\n".format(__indent)
buffer += "{0} Files: {1!s}\n".format(__indent, self._filesFile)
return buffer
[docs]class VHDLTestbench(Testbench):
def __init__(self, host, name, configSectionName, parent):
super().__init__(host, name, configSectionName, parent)
self._kind = TestbenchKind.VHDLTestbench
[docs] def _LazyLoadable_Load(self):
super()._LazyLoadable_Load()
def __str__(self):
return super().__str__() + " (VHDL testbench)"
[docs] def pprint(self, indent):
__indent = " " * indent
buffer = "{0}VHDL Testbench:\n".format(__indent)
buffer += "{0} Files: {1!s}\n".format(__indent, self._filesFile)
return buffer
[docs]class CocoTestbench(Testbench):
def __init__(self, host, name, configSectionName, parent):
self._topLevel = ""
super().__init__(host, name, configSectionName, parent)
self._kind = TestbenchKind.CocoTestbench
@property
@LazyLoadTrigger
def TopLevel(self):
return self._topLevel
[docs] def _LazyLoadable_Load(self):
super()._LazyLoadable_Load()
self._topLevel = self.ConfigSection["TopLevel"]
def __str__(self):
return super().__str__() + " (Cocotb testbench)"
[docs] def pprint(self, indent):
__indent = " " * indent
buffer = "{0}Cocotb Testbench:\n".format(__indent)
buffer += "{0} Files: {1!s}\n".format(__indent, self._filesFile)
return buffer
[docs]class Netlist(LazyPathElement):
def __init__(self, host, name, configSectionName, parent):
self._kind = NetlistKind.Unknown
self._moduleName = ""
self._rulesFile = None
super().__init__(host, name, configSectionName, parent)
@property
@LazyLoadTrigger
def ModuleName(self): return self._moduleName
@property
@LazyLoadTrigger
def RulesFile(self): return self._rulesFile
[docs] def _LazyLoadable_Load(self):
super()._LazyLoadable_Load()
self._moduleName = self.ConfigSection["TopLevel"]
self._dependencies = self.ConfigSection['Dependencies'].split()
value = self.ConfigSection["RulesFile"]
self._rulesFile = Path(value) if (value != "") else None
[docs]class XstNetlist(Netlist):
def __init__(self, host, name, configSectionName, parent):
self._filesFile = None
self._prjFile = None
self._xcfFile = None
self._filterFile = None
self._xstTemplateFile = None
self._xstFile = None
super().__init__(host, name, configSectionName, parent)
self._kind = NetlistKind.XstNetlist
@property
@LazyLoadTrigger
def FilesFile(self): return self._filesFile
@property
@LazyLoadTrigger
def XcfFile(self): return self._xcfFile
@property
@LazyLoadTrigger
def FilterFile(self): return self._filterFile
@property
@LazyLoadTrigger
def XstTemplateFile(self): return self._xstTemplateFile
@property
def PrjFile(self):
return self._prjFile
@PrjFile.setter
def PrjFile(self, value):
if isinstance(value, str):
value = Path(value)
self._prjFile = value
@property
def XstFile(self):
return self._xstFile
@XstFile.setter
def XstFile(self, value):
if isinstance(value, str):
value = Path(value)
self._xstFile = value
[docs] def _LazyLoadable_Load(self):
super()._LazyLoadable_Load()
self._filesFile = Path(self.ConfigSection["FilesFile"])
self._xcfFile = Path(self.ConfigSection['XSTConstraintsFile'])
self._filterFile = Path(self.ConfigSection['XSTFilterFile'])
self._xstTemplateFile = Path(self.ConfigSection['XSTOptionsFile'])
def __str__(self):
return super().__str__() + " (XST netlist)"
[docs] def pprint(self, indent):
__indent = " " * indent
buffer = "{0}Netlist: {1}\n".format(__indent, self._moduleName)
buffer += "{0} Files: {1!s}\n".format(__indent, self._filesFile)
buffer += "{0} Rules: {1!s}\n".format(__indent, self._rulesFile)
return buffer
[docs]class QuartusNetlist(Netlist):
def __init__(self, host, name, configSectionName, parent):
self._filesFile = None
self._qsfFile = None
super().__init__(host, name, configSectionName, parent)
self._kind = NetlistKind.QuartusNetlist
@property
@LazyLoadTrigger
def FilesFile(self): return self._filesFile
@property
def QsfFile(self): return self._qsfFile
@QsfFile.setter
def QsfFile(self, value):
if isinstance(value, str):
value = Path(value)
self._qsfFile = value
[docs] def _LazyLoadable_Load(self):
super()._LazyLoadable_Load()
self._filesFile = Path(self.ConfigSection["FilesFile"])
def __str__(self):
return super().__str__() + " (Quartus netlist)"
[docs] def pprint(self, indent):
__indent = " " * indent
buffer = "{0}Netlist: {1}\n".format(__indent, self._moduleName)
buffer += "{0} Files: {1!s}\n".format(__indent, self._filesFile)
buffer += "{0} Rules: {1!s}\n".format(__indent, self._rulesFile)
return buffer
[docs]class LatticeNetlist(Netlist):
def __init__(self, host, name, configSectionName, parent):
self._filesFile = None
self._prjFile = None
super().__init__(host, name, configSectionName, parent)
self._kind = NetlistKind.LatticeNetlist
@property
@LazyLoadTrigger
def FilesFile(self): return self._filesFile
@property
def PrjFile(self): return self._prjFile
@PrjFile.setter
def PrjFile(self, value):
if isinstance(value, str):
value = Path(value)
self._prjFile = value
[docs] def _LazyLoadable_Load(self):
super()._LazyLoadable_Load()
self._filesFile = Path(self.ConfigSection["FilesFile"])
def __str__(self):
return super().__str__() + " (Lattice netlist)"
[docs] def pprint(self, indent):
__indent = " " * indent
buffer = "{0}Netlist: {1}\n".format(__indent, self._moduleName)
buffer += "{0} Files: {1!s}\n".format(__indent, self._filesFile)
buffer += "{0} Rules: {1!s}\n".format(__indent, self._rulesFile)
return buffer
[docs]class CoreGeneratorNetlist(Netlist):
def __init__(self, host, name, configSectionName, parent):
self._xcoFile = None
super().__init__(host, name, configSectionName, parent)
self._kind = NetlistKind.CoreGeneratorNetlist
def __str__(self):
return super().__str__() + " (Core Generator netlist)"
@property
def FilesFile(self): return None
@property
def XcoFile(self): return self._xcoFile
[docs] def _LazyLoadable_Load(self):
super()._LazyLoadable_Load()
self._xcoFile = Path(self.ConfigSection['CoreGeneratorFile'])
[docs] def pprint(self, indent):
__indent = " " * indent
buffer = "{0}Netlist: {1}\n".format(__indent, self._moduleName)
buffer += "{0} Rules: {1!s}\n".format(__indent, self._rulesFile)
return buffer
[docs]class VivadoNetlist(Netlist):
def __init__(self, host, name, configSectionName, parent):
self._filesFile = None
self._tclFile = None
super().__init__(host, name, configSectionName, parent)
self._kind = NetlistKind.VivadoNetlist
@property
@LazyLoadTrigger
def FilesFile(self): return self._filesFile
@property
def TclFile(self): return self._tclFile
@TclFile.setter
def TclFile(self, value):
if isinstance(value, str):
value = Path(value)
self._tclFile = value
[docs] def _LazyLoadable_Load(self):
super()._LazyLoadable_Load()
self._filesFile = Path(self.ConfigSection["FilesFile"])
def __str__(self):
return super().__str__() + " (Vivado netlist)"
[docs] def pprint(self, indent):
__indent = " " * indent
buffer = "{0}Netlist: {1}\n".format(__indent, self._moduleName)
buffer += "{0} Files: {1!s}\n".format(__indent, self._filesFile)
buffer += "{0} Rules: {1!s}\n".format(__indent, self._rulesFile)
return buffer
[docs]class FQN:
def __init__(self, host, fqn, defaultLibrary="PoC", defaultType=EntityTypes.Source):
self.__host = host
self.__type = None
self.__parts = []
if (fqn is None): raise ValueError("Parameter 'fqn' is None.")
if (fqn == ""): raise ValueError("Parameter 'fqn' is empty.")
# extract EntityType
splitList1 = fqn.split(":")
if (len(splitList1) == 1):
self.__type = defaultType
entity = fqn
elif (len(splitList1) == 2):
self.__type = EntityTypes(splitList1[0])
entity = splitList1[1]
else:
raise ValueError("Argument 'fqn' has to many ':' signs.")
# extract parts
parts = entity.split(".")
if (parts[0].lower() not in self.__host.Root):
parts.insert(0, defaultLibrary)
# check and resolve parts
cur = self.__host.Root
self.__parts.append(cur)
last = len(parts) - 1
for pos,part in enumerate(parts):
if ((pos == last) and ("*" in part)):
pe = StarWildCard(host, part, "----", cur)
self.__parts.append(pe)
elif ((pos == last) and ("?" in part)):
pe = AskWildCard(host, part, "----", cur)
self.__parts.append(pe)
else:
try:
pe = cur[part]
except KeyError:
raise ConfigurationException("PoC entity '{GREEN}{good}{RED}.{bad}{NOCOLOR}' not found.".format(good=(".".join(parts[:pos])), bad=(".".join(parts[pos:])), **Init.Foreground))
self.__parts.append(pe)
cur = pe
[docs] def Root(self):
return self.__host.Root
@property
def Entity(self):
return self.__parts[-1]
def __str__(self):
return str(self.Entity)