Coverage for pyVHDLModel/Predefined.py: 96%

49 statements  

« prev     ^ index     » next       coverage.py v7.16.0, created at 2026-08-29 03:29 +0000

1# ==================================================================================================================== # 

2# __ ___ _ ____ _ __ __ _ _ # 

3# _ __ _ \ \ / / | | | _ \| | | \/ | ___ __| | ___| | # 

4# | '_ \| | | \ \ / /| |_| | | | | | | |\/| |/ _ \ / _` |/ _ \ | # 

5# | |_) | |_| |\ V / | _ | |_| | |___| | | | (_) | (_| | __/ | # 

6# | .__/ \__, | \_/ |_| |_|____/|_____|_| |_|\___/ \__,_|\___|_| # 

7# |_| |___/ # 

8# ==================================================================================================================== # 

9# Authors: # 

10# Patrick Lehmann # 

11# # 

12# License: # 

13# ==================================================================================================================== # 

14# Copyright 2017-2026 Patrick Lehmann - Boetzingen, Germany # 

15# Copyright 2016-2017 Patrick Lehmann - Dresden, Germany # 

16# # 

17# Licensed under the Apache License, Version 2.0 (the "License"); # 

18# you may not use this file except in compliance with the License. # 

19# You may obtain a copy of the License at # 

20# # 

21# http://www.apache.org/licenses/LICENSE-2.0 # 

22# # 

23# Unless required by applicable law or agreed to in writing, software # 

24# distributed under the License is distributed on an "AS IS" BASIS, # 

25# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # 

26# See the License for the specific language governing permissions and # 

27# limitations under the License. # 

28# # 

29# SPDX-License-Identifier: Apache-2.0 # 

30# ==================================================================================================================== # 

31# 

32"""This module contains base-classes for predefined library and package declarations.""" 

33from typing import Iterable, Optional as Nullable 

34 

35from pyTooling.Decorators import export 

36from pyTooling.MetaClasses import ExtendedType 

37 

38from pyVHDLModel import Library, Package, PackageBody, AllPackageMembersReferenceSymbol, PackageMemberReferenceSymbol 

39from pyVHDLModel.Name import SimpleName, SelectedName, AllName 

40from pyVHDLModel.Symbol import LibraryReferenceSymbol, PackageSymbol 

41from pyVHDLModel.DesignUnit import LibraryClause, UseClause 

42 

43 

44@export 

45class PredefinedLibrary(Library): 

46 """ 

47 A base-class for predefined VHDL libraries. 

48 

49 VHDL defines 2 predefined libraries: 

50 

51 * :class:`~pyVHDLModel.STD.Std` 

52 * :class:`~pyVHDLModel.IEEE.Ieee` 

53 

54 .. seealso:: 

55 

56 * :class:`Ieee <pyVHDLModel.IEEE.Ieee>` 

57 * :class:`Std <pyVHDLModel.STD.Std>` 

58 """ 

59 

60 def __init__(self, packages, documentation: Nullable[str] = None) -> None: 

61 """ 

62 Initializes a predefined library. 

63 

64 :param packages: Dictionary of all packages defined in a library. 

65 :param documentation: Documentation of this library, if the caller has one to supply. VHDL defines 

66 none for a predefined library, so it is empty unless supplied from outside. 

67 """ 

68 super().__init__(self.__class__.__name__, documentation) 

69 

70 self.AddPackages(packages) 

71 

72 def AddPackages(self, packages) -> None: 

73 for packageType, packageBodyType in packages: 

74 package: Package = packageType() 

75 package.Library = self 

76 self._packages[package.NormalizedIdentifier] = package 

77 

78 if packageBodyType is not None: 

79 packageBody: PackageBody = packageBodyType() 

80 packageBody.Library = self 

81 self._packageBodies[packageBody.NormalizedIdentifier] = packageBody 

82 

83 

84@export 

85class PredefinedPackageMixin(metaclass=ExtendedType, mixin=True): 

86 """ 

87 A mixin-class for predefined VHDL packages and package bodies. 

88 

89 .. seealso:: 

90 

91 * :class:`Predefined package <pyVHDLModel.Predefined.PredefinedPackage>` 

92 * :class:`Predefined package body <pyVHDLModel.Predefined.PredefinedPackageBody>` 

93 """ 

94 

95 def _AddLibraryClause(self, libraries: Iterable[str]) -> None: 

96 symbols = [LibraryReferenceSymbol(SimpleName(libName)) for libName in libraries] 

97 libraryClause = LibraryClause(symbols) 

98 

99 self._contextItems.append(libraryClause) 

100 self._libraryReferences.append(libraryClause) 

101 

102 def _AddPackageClause(self, packages: Iterable[str]) -> None: 

103 symbols = [] 

104 for qualifiedPackageName in packages: 

105 libName, packName, members = qualifiedPackageName.split(".") 

106 

107 packageName = SelectedName(packName, SimpleName(libName)) 

108 if members.lower() == "all": 108 ↛ 111line 108 didn't jump to line 111 because the condition on line 108 was always true

109 symbols.append(AllPackageMembersReferenceSymbol(AllName(packageName))) 

110 else: 

111 symbols.append(PackageMemberReferenceSymbol(SelectedName(members, packageName))) 

112 

113 useClause = UseClause(symbols) 

114 self._contextItems.append(useClause) 

115 self._packageReferences.append(useClause) 

116 

117 

118@export 

119class PredefinedPackage(Package, PredefinedPackageMixin): 

120 """ 

121 A base-class for predefined VHDL packages. 

122 """ 

123 

124 def __init__(self, identifier: Nullable[str] = None) -> None: 

125 """ 

126 Initializes a predefined package. 

127 

128 By default the VHDL package name is the Python class name. Pass ``identifier`` when the two must 

129 differ - e.g. when two vendor flavors of the same VHDL package need distinct Python classes. 

130 

131 :param identifier: The VHDL package name, or ``None`` to use the class name. 

132 """ 

133 super().__init__(self.__class__.__name__ if identifier is None else identifier) 

134 

135 

136@export 

137class PredefinedPackageBody(PackageBody, PredefinedPackageMixin): 

138 """ 

139 A base-class for predefined VHDL package bodies. 

140 """ 

141 

142 def __init__(self, packageIdentifier: Nullable[str] = None) -> None: 

143 """ 

144 Initializes a predefined package body. 

145 

146 By default the VHDL package name is the Python class name with the trailing ``_Body`` removed. 

147 Pass ``packageIdentifier`` when the two must differ. 

148 

149 :param packageIdentifier: The VHDL name of the package this body implements, or ``None`` to derive 

150 it from the class name. 

151 """ 

152 identifier = self.__class__.__name__[:-5] if packageIdentifier is None else packageIdentifier 

153 packageSymbol = PackageSymbol(SimpleName(identifier)) 

154 super().__init__(packageSymbol)