OpenCores
URL https://opencores.org/ocsvn/radiohdl/radiohdl/trunk

Subversion Repositories radiohdl

[/] [radiohdl/] [trunk/] [base/] [hdl_libraries_wizard.py] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 danv
###############################################################################
2
#
3
# Copyright (C) 2014
4
# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
5
# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
6
#
7
# This program is free software: you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation, either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
#
20
###############################################################################
21
 
22
"""HDL configuration for building simulation and synthesis targets.
23
 
24
   There should be one hdl_buildset_<buildset>.cfg file per buildset somewhere in the
25
   toolRootDir and at least one hdllib.cfg file somewhere in the libRootDir.
26
   Every HDL library that is in the libRootDir can be found if it has a hdllib.cfg file.
27
   Together the hdl_buildset_<buildset>.cfg and hdllib.cfg files contain all the keys and
28
   values that are sufficient to be able to build the targets for the HDL
29
   library. The possible targets are:
30
 
31
   - compile to created the library binaries for simulation
32
   - synthesize to created an image that can be loaded ion the FPGA
33
   - verify VHDL test benches in simulation
34
   - verify Python test cases via the MM control interface in simulation
35
   - validate Python test cases on hardware via the MM control interface
36
 
37
   The contents of the cfg files consist of a series of key - value pairs
38
   that are read into a dictionary as defined in hdl_configfile.py. Whether
39
   the key is a valid key depends on the application that interprets the
40
   dictionary.
41
 
42
   The methods can have the library dictionary or the library name as
43
   argument. The default arguments are the self.libs.dicts and the
44
   corresponding self.lib_names. The argument can be a list or a single value.
45
   Similar the return can be a list or a single value, because a list of one
46
   element is unlistified.
47
 
48
"""
49
 
50
import sys
51
from os                 import listdir
52
from os.path            import expandvars, isabs, join, isfile
53
import shutil
54
from distutils.dir_util import copy_tree
55
from argparse           import ArgumentParser
56
import collections
57
import common as cm
58
from configfile         import ConfigFile
59
from hdl_configfile     import HdlBuildset
60
from hdl_configtree     import HdlLibTree
61
 
62
__all__ = [ 'HdlLibrariesWizard' ]
63
 
64
class HdlLibrariesWizard:
65
 
66
    def __init__(self, toolRootDir, toolFileName, libFileName='hdllib.cfg', libFileSections=None):
67
        """Get tool dictionary info from toolRootDir and all HDL library dictionary info for it
68
 
69
           - self.tool.dicts = single dictionary that contains the tool info (only one tool dict in dicts list)
70
           - self.libs.dicts = list of dictionaries that contains the info of the HDL libraries.
71
 
72
           The libRootDir parameter is defined in the hdl_buildset_<buildset>.cfg file and is the root directory from where the hdllib.cfg
73
           files are searched for.
74
 
75
           - self.lib_names = the library names of self.libs.dicts
76
 
77
           In parallel to the self.libs.dicts list of dictionaries a list of self.lib_names is created to be able to identify
78
           a HDL library dict also by its library name. Iherefore it is important that the indexing of parallel lists remains
79
           intact at all times.
80
 
81
           - self.technologyNames = the technologyNames parameter is defined in the hdl_buildset_<buildset>.cfg file. All generic HDL
82
             libraries and these technology specific libraries are kept. If self.technologyNames is:
83
             []                              : Keep all HDL libraries that were found.
84
             ['ip_stratixiv', 'ip_arria10']  : The HDL libraries with a hdl_lib_technology that is not '' or does not match one of the technologies
85
                                               in technologyNames are removed from the list of HDL library dictionaries.
86
 
87
           - self.removed_libs = contains the HDL library dicts that have been removed from self.libs.dicts, because they are for
88
                                  a technology that is not within technologyNames.
89
 
90
           Keep lists of all unavailable library names that were found at the hdl_lib_uses_synth, hdl_lib_uses_ip, hdl_lib_uses_sim and
91
           hdl_lib_include_ip keys in the self.libs.dicts:
92
 
93
           - self.unavailable_use_libs = self.unavailable_use_synth_libs + self.unavailable_use_ip_libs + self.unavailable_use_sim_libs
94
           - self.unavailable_include_ip_libs
95
 
96
           Unavailable used libraries can be missing for a valid reason when they are not required (e.g. IP for another technology). Being able to
97
           ignore missing libraries does require that the entities from these libraries are instantiated as components in the VHDL. The difference
98
           between a removed library and an unavailable library is that for a removed library the HDL config information is still known, whereas
99
           for an unavailable library it is not. Therefore the library clause names for referred but unavailable HDL libraries are disclosed at the
100
           'hdl_lib_disclose_library_clause_names' keys of the libraries that use them and kept in a dictionary:
101
 
102
           - self.disclosed_library_clause_names
103
 
104
        """
105
        print "HdlLibrariesWizard(toolRootDir=%s, toolFileName=%s, libFileName=%s, libFileSections=%s)" % \
106
                        (toolRootDir, toolFileName, libFileName, libFileSections)
107
        self.toolRootDir = toolRootDir  # TODO almost obsolete
108
 
109
        # read the buildset file. This file contains major information about paths, technologies, and so on
110
        full_buildsetfile_name = "%s/%s" % (toolRootDir, toolFileName)
111
        buildset_info = HdlBuildset(full_buildsetfile_name)
112
        buildset_info.resolve_key_references()
113
        self.buildset = buildset_info.content
114
 
115
        # HDL library config files
116
        self.libRootDirs = [ expandvars(rootdir) for rootdir in self.buildset['lib_root_dirs'].replace("\t"," ").split(" ")
117
                                                     if rootdir != '' ]
118
        self.libs = HdlLibTree(rootdirs = self.libRootDirs,
119
                               filename = libFileName,
120
                               sections = libFileSections)   # library dict files
121
        if len(self.libs.configfiles) == 0:
122
            sys.exit('Error : No HDL library config files found')
123
        print "Found %d hdllib files:" % len(self.libs.configfiles)
124
 
125
        # Substitute key words occurring in hdllib.cfg files with their value.
126
        self.substitute_key_words()
127
 
128
        # Keep the generic HDL libraries and remove those that do not match the specified IP technologies
129
        self.technologyNames = self.buildset['technology_names'].split()
130
        print "### self.technologyNames = ", self.technologyNames
131
        self.removed_libs = {}
132
        for cfglib_name in self.libs.configfiles.keys():
133
            techname = self.libs.configfiles[cfglib_name]['hdl_lib_technology']
134
            if (techname != '' and techname not in self.technologyNames):
135
                # keep the removed libs we need the content of those libs later.
136
                self.removed_libs[cfglib_name]=self.libs.configfiles[cfglib_name]
137
        self.libs.remove_files_from_tree(self.removed_libs.keys())
138
        print len(self.removed_libs), "REMOVED LIBS:", sorted(self.removed_libs)
139
 
140
        # Keep list of used HDL library names
141
        self.lib_names = self.libs.configfiles.keys()
142
        print len(self.lib_names), "KEPT LIBS:", sorted(self.lib_names)
143
 
144
        # No need to check for duplicates since HdlLibTree did that already.
145
 
146
        # create dictionary of library names with library clause names that are disclosed at the 'hdl_lib_disclose_library_clause_names' keys.
147
        self.disclosed_library_clause_names = {}
148
        for lib in self.libs.configfiles.values():
149
            if lib.get_value('hdl_lib_disclose_library_clause_names'):
150
                key_values = lib.get_value('hdl_lib_disclose_library_clause_names').split()
151
                lib_name = key_values[0::2]
152
                lib_clause_name = key_values[1::2]
153
                lib_pairs = zip(lib_name, lib_clause_name)
154
                # No need to check for duplicate lib_names, because a dictionary cannot have duplicate keys
155
                for lp in lib_pairs:
156
                    self.disclosed_library_clause_names[lp[0]] = lp[1]
157
        # Check whether the used libraries from the self.libs.dicts keys indeed exist, otherwise remove them from the dictionary key
158
        # string and add the used library name to the list of unavailable used library names and check that the library use clause
159
        # name was disclosed at the 'hdl_lib_disclose_library_clause_names' key. In this way other methods do not have to check a
160
        # used library does indeed exist.
161
        self.unavailable_use_synth_libs = []
162
        self.unavailable_use_ip_libs = []
163
        self.unavailable_use_sim_libs = []
164
        self.unavailable_include_ip_libs = []
165
        for lib in self.libs.configfiles.values():
166
            use_synth_libs = []
167
            use_ip_libs = []
168
            use_sim_libs = []
169
            include_ip_libs = []
170
            if lib.get_value('hdl_lib_uses_synth'):
171
                use_synth_libs = lib.get_value('hdl_lib_uses_synth').split()
172
            if lib.get_value('hdl_lib_uses_ip'):
173
                use_ip_libs += lib.get_value('hdl_lib_uses_ip').split()
174
            if lib.get_value('hdl_lib_uses_sim'):
175
                use_sim_libs += lib.get_value('hdl_lib_uses_sim').split()
176
            if lib.get_value('hdl_lib_include_ip'):
177
                include_ip_libs = lib.get_value('hdl_lib_include_ip').split()
178
            for use_name in use_synth_libs:
179
                if (use_name not in self.lib_names) and (use_name not in self.removed_libs):
180
                    lib['hdl_lib_uses_synth']=cm.remove_from_list_string(lib['hdl_lib_uses_synth'], use_name)
181
                    self.unavailable_use_synth_libs.append(use_name)
182
                    if use_name not in self.disclosed_library_clause_names.keys():
183
                        sys.exit("Error : Unavailable library %s at 'hdl_lib_uses_synth' key is not disclosed at 'hdl_lib_disclose_library_clause_names' key in library %s" % (use_name, lib_name))
184
            for use_name in use_ip_libs:
185
                if (use_name not in self.lib_names) and (use_name not in self.removed_libs):
186
                    lib['hdl_lib_uses_ip']=cm.remove_from_list_string(lib['hdl_lib_uses_ip'], use_name)
187
                    self.unavailable_use_ip_libs.append(use_name)
188
                    if use_name not in self.disclosed_library_clause_names.keys():
189
                        sys.exit("Error : Unavailable library %s at 'hdl_lib_uses_ip' key is not disclosed at 'hdl_lib_disclose_library_clause_names' key in library %s" % (use_name, lib_name))
190
            for use_name in use_sim_libs:
191
                if (use_name not in self.lib_names) and (use_name not in self.removed_libs):
192
                    lib['hdl_lib_uses_sim']=cm.remove_from_list_string(lib['hdl_lib_uses_sim'], use_name)
193
                    self.unavailable_use_sim_libs.append(use_name)
194
                    if use_name not in self.disclosed_library_clause_names.keys():
195
                        sys.exit("Error : Unavailable library %s at 'hdl_lib_uses_sim' key is not disclosed at 'hdl_lib_disclose_library_clause_names' key in library %s" % (use_name, lib_name))
196
            for use_name in include_ip_libs:
197
                if (use_name not in self.lib_names) and (use_name not in self.removed_libs):
198
                    lib['hdl_lib_include_ip']=cm.remove_from_list_string(lib['hdl_lib_include_ip'], use_name)
199
                    self.unavailable_include_ip_libs.append(use_name)
200
                    if use_name not in self.disclosed_library_clause_names.keys():
201
                        sys.exit("Error : Unavailable library %s at 'hdl_lib_include_ip' key in library %s is not disclosed at any 'hdl_lib_disclose_library_clause_names' key" % (use_name, lib_name))
202
        # remove all duplicates from the list
203
        self.unavailable_use_synth_libs  = cm.unique(self.unavailable_use_synth_libs)
204
        self.unavailable_use_ip_libs     = cm.unique(self.unavailable_use_ip_libs)
205
        self.unavailable_use_sim_libs    = cm.unique(self.unavailable_use_sim_libs)
206
        self.unavailable_include_ip_libs = cm.unique(self.unavailable_include_ip_libs)   # list of include_ip_use_libs
207
        self.unavailable_use_libs        = self.unavailable_use_synth_libs + self.unavailable_use_ip_libs + self.unavailable_use_sim_libs
208
        self.unavailable_use_libs        = cm.unique(self.unavailable_use_libs)          # aggregate list of use_*_libs
209
 
210
    # The Key value pairs defined in hdltool<buildset>.cfg can be used in hdllib.cfg files. See hdllib.cfg of technology library
211
    def substitute_key_words(self):
212
        for lib in self.libs.configfiles.values():
213
            for lib_key, lib_value in lib.content.items():
214
                for tool_key, tool_value in self.buildset.items():
215
                    tool_key_string = '<%s>' % tool_key
216
                    if tool_key_string in lib_value:
217
                        lib[lib_key] = lib_value.replace(tool_key_string,tool_value)
218
 
219
    def check_library_names(self, check_lib_names, lib_names=None):
220
        """Check that HDL library names exists within the list of library names, if not then exit with Error message.
221
           The list of library names can be specified via the argument lib_names, or it defaults to the list of
222
           self.lib_names of HDL libraries that were found in the toolRootDir for the libFileName of this object.
223
        """
224
        if lib_names==None: lib_names=self.lib_names
225
        for check_lib_name in cm.listify(check_lib_names):
226
            if check_lib_name not in cm.listify(lib_names):
227
                sys.exit('Error : Unknown HDL library name %s found with %s' % (check_lib_name, cm.method_name()))
228
 
229
 
230
    def get_used_libs(self, build_type, lib_dict, arg_include_ip_libs=[]):
231
        """Get the list of used HDL libraries from the lib_dict that this library directly depends on, so only at this HDL library hierachy level.
232
 
233
           Which libraries are actually used depends on the build_type. The build_type can be:
234
            ''      uses all libraries from 'hdl_lib_uses_synth', 'hdl_lib_uses_ip' and 'hdl_lib_uses_sim' in the lib_dict
235
            'sim'   uses all libraries from 'hdl_lib_uses_synth', 'hdl_lib_uses_ip' and 'hdl_lib_uses_sim' in the lib_dict
236
            'synth' uses all libraries from 'hdl_lib_uses_synth' in the lib_dict and from 'hdl_lib_uses_ip' it only uses the IP
237
                    libraries that are mentioned in the local 'hdl_lib_include_ip' key or in the global arg_include_ip_libs
238
 
239
           The 'hdl_lib_uses_*' keys all appear locally in the same hdllib.cfg file. The 'hdl_lib_include_ip' key appears at this level or at
240
           a higher level (design) library hdllib.cfg file to select which of all available 'hdl_lib_uses_ip' IP libraries will actually be
241
           used in the design. The 'hdl_lib_include_ip' cannot appear in a lower level hdllib.cfg, because a lower level HDL library cannot
242
           depend on a higher level HDL library. Therefore the IP libraries that need to be included from 'hdl_lib_uses_ip' will be known in
243
           include_ip_libs.
244
        """
245
        # Get local library dependencies
246
        use_synth_libs = []
247
        use_ip_libs = []
248
        use_sim_libs = []
249
        include_ip_libs = []
250
        if 'hdl_lib_uses_synth' in lib_dict.content:
251
            use_synth_libs = lib_dict['hdl_lib_uses_synth'].split()
252
        if 'hdl_lib_uses_ip' in lib_dict.content:
253
            use_ip_libs += lib_dict['hdl_lib_uses_ip'].split()
254
        if 'hdl_lib_uses_sim' in lib_dict.content:
255
            use_sim_libs += lib_dict['hdl_lib_uses_sim'].split()
256
        if 'hdl_lib_include_ip' in lib_dict.content:
257
            include_ip_libs = lib_dict['hdl_lib_include_ip'].split()
258
 
259
        # Append include_ip_libs from this level to the global list of arg_include_ip_libs
260
        include_ip_libs = list(arg_include_ip_libs) + include_ip_libs
261
 
262
        # Get the actually use_libs for lib_dict
263
        use_libs = use_synth_libs + use_ip_libs + use_sim_libs  # default include all IP, so ignore include_ip_libs
264
        if build_type=='sim':
265
            use_libs = use_synth_libs + use_ip_libs + use_sim_libs    # for simulation included all IP, so ignore include_ip_libs
266
        if build_type=='synth':
267
            use_libs = use_synth_libs
268
            # For synthesis only keep the local use_ip_libs if it is mentioned in the global include_ip_libs. Vice versa also only
269
            # include the global include_ip_libs if they appear in a local use_ip_libs, to avoid that an IP library that is mentioned
270
            # in the global include_ip_libs gets included while it is not instantiated anywhere in the design.
271
            for ip_lib in use_ip_libs:
272
                if ip_lib in include_ip_libs:
273
                    use_libs += [ip_lib]
274
 
275
        # Remove any duplicate library names from the lists
276
        use_libs = cm.unique(use_libs)
277
        include_ip_libs = cm.unique(include_ip_libs)
278
 
279
        # Remove libraries that are in the removed technologies (use list() to take copy)
280
        for use_name in list(use_libs):
281
            if use_name in self.removed_libs:
282
                use_libs.remove(use_name)
283
        for use_name in list(include_ip_libs):
284
            if use_name in self.removed_libs:
285
                include_ip_libs.remove(use_name)
286
 
287
        return use_libs, include_ip_libs
288
 
289
 
290
    def derive_all_use_libs(self, build_type, lib_name, arg_include_ip_libs=[]):
291
        """Recursively derive a complete list of all HDL libraries that the specified HDL lib_name library depends on, so from this
292
           HDL library down the entire hierachy.
293
 
294
           The hdl_lib_uses_* key only needs to contain all libraries that are declared at the VHDL LIBRARY clauses of the
295
           source files in this VHDL library. This derive_all_use_libs() will recursively find all deeper level VHDL libraries as well.
296
 
297
           The arg_include_ip_libs selects the IP library to keep from 'hdl_lib_uses_ip'. The include_ip_libs is passed on
298
           through the recursion hierarchy via arg_include_ip_libs to ensure that the from the top level library down all
299
           multiple choice IP libraries in 'hdl_lib_uses_ip' that need to be included are indeed included. The multiple choice IP
300
           libraries in 'hdl_lib_uses_ip' that are not in include_ip_libs are excluded.
301
 
302
           Note:
303
           . Only the generic HDL libraries and the technology specific libraries that match self.technologyNames are used,
304
             because the other technology libraries have been removed from self.libs.dicts already at __init__() and from the
305
             library dependency lists in get_used_libs()
306
           . If Python breaks because recursion limit is reached, then two hdllib.cfg probably mutually use eachother which is
307
             not allowed.
308
        """
309
        # use list() to take local copy, to avoid next that default empty list argument arg_include_ip_libs=[] gets disturbed
310
        include_ip_libs = list(arg_include_ip_libs)
311
        if lib_name in self.lib_names:
312
            all_use_libs = [lib_name]
313
            lib_dict = self.libs.configfiles[lib_name]
314
            use_libs, include_ip_libs = self.get_used_libs(build_type, lib_dict, include_ip_libs)
315
 
316
            for use_lib in use_libs:
317
                if use_lib not in all_use_libs:
318
                    all_use_libs.append(use_lib)
319
                    # use recursion to include all used libs
320
                    all_use_libs += self.derive_all_use_libs(build_type, use_lib, include_ip_libs)
321
            # remove all duplicates from the list
322
            return cm.unique(all_use_libs)
323
        else:
324
            sys.exit('Error : Unknown HDL library name %s in %s()' % (lib_name, cm.method_name()))
325
 
326
 
327
    def derive_lib_order(self, build_type, lib_name, lib_names=None):
328
        """Derive the dependency order for all HDL libraries in lib_names that HDL library lib_name depends on.
329
        """
330
        if lib_names==None:
331
            # At first entry derive the list of all HDL libraries that lib_name depends on
332
            lib_names = self.derive_all_use_libs(build_type, lib_name)
333
 
334
        # Derive the order of all HDL libraries that lib_name depends on, start with the order of lib_names
335
        lib_dicts = self.libs.get_configfiles('hdl_lib_name', values=lib_names)
336
        # use list() to take local copy to avoid modifying list order of self.lib_names which matches self.libs.dicts list order
337
        lib_order = list(lib_names)
338
        for lib_dict in lib_dicts:
339
            lib_name = lib_dict['hdl_lib_name']
340
            use_libs, _ = self.get_used_libs('', lib_dict, [])
341
            for use_lib in use_libs:
342
                if use_lib in lib_names:
343
                    if lib_order.index(use_lib) > lib_order.index(lib_name):
344
                        lib_order.remove(use_lib)
345
                        lib_order.insert(lib_order.index(lib_name), use_lib)  # move used lib to just before this lib
346
        # use recursion to keep on reordering the lib_order until it is stable
347
        if lib_names != lib_order:
348
            lib_order = self.derive_lib_order(build_type, lib_name, lib_order)
349
        return lib_order
350
 
351
 
352
    def get_lib_dicts_from_lib_names(self, lib_names=None):
353
        """Get list the HDL libraries lib_dicts from list of HDL libraries lib_names and preseve the library order.
354
        """
355
        if lib_names==None:
356
            lib_names=self.lib_names
357
 
358
        # Cannot use:
359
        #lib_dicts = self.libs.get_configfiles('hdl_lib_name', values=lib_names)
360
        # because then the order of self.libs.dicts is used
361
        lib_dicts = []
362
        for lib_name in cm.listify(lib_names):
363
            lib_dicts.append(self.libs.configfiles[lib_name])
364
        return lib_dicts
365
 
366
 
367
    def get_lib_names_from_lib_dicts(self, lib_dicts=None):
368
        """Get list the HDL libraries lib_names from list of HDL libraries lib_dicts and preseve the library order.
369
        """
370
        lib_names = self.libs.get_key_values('hdl_lib_name', lib_dicts)
371
        return lib_names
372
 
373
 
374
    def get_tool_build_dir(self, build_type):
375
        """Get the central tool build directory.
376
 
377
        The build_type can be:
378
            'sim'   uses the 'sim_tool_name'   key in the self.buildset
379
            'synth' uses the 'synth_tool_name' key in the self.buildset
380
            When another name is used that name is used directly as toolname in the construction of the path.
381
 
382
        The function returns a tuple with the following four components:
383
            - the absolute path to the central main build directory
384
            - the buildset_name key value as subdirectory
385
            - the toolname as subdirectory (derived from *_tool_name or the given value of 'build_type')
386
            - project_deeper_subdir. See explanation below.
387
 
388
        The project file will be located in the build dir or at some levels deeper in the build dir.
389
        These optional extra subdirectory levels allow for relative file reference from project file
390
        location. This is useful to be able to keep memory initialisation files in the library build
391
        directory that are referred to using some fixed ../../ path in the HDL code.
392
            - project_deeper_subdir = '' when project_dir_depth_<build_type> = 0 or not in buildset
393
            - project_deeper_subdir = 'p/' when project_dir_depth_<build_type> = 1
394
            - project_deeper_subdir = 'p/p/' when project_dir_depth_<build_type> = 2,
395
            - project_deeper_subdir = 'p/p/p/' when project_dir_depth_<build_type> = 3, etc
396
        """
397
        # Determine build_maindir
398
        build_maindir = expandvars('${HDL_BUILD_DIR}')
399
        if not isabs(build_maindir):
400
            sys.exit('Error : The build_dir value must be an absolute path')
401
 
402
        # Determine build_buildset_dir
403
        build_buildset_dir = self.buildset['buildset_name']
404
 
405
        # Determine build_tooldir
406
        tool_name_key = build_type + '_tool_name'
407
        if tool_name_key in self.buildset:
408
            build_tooldir = self.buildset[tool_name_key]
409
        else:
410
            build_tooldir = build_type
411
 
412
        # Determine project_deeper_subdir
413
        project_dir_depth_key = 'project_dir_depth_' + build_type
414
        if project_dir_depth_key not in self.buildset:
415
            project_deeper_subdir = ''
416
        else:
417
            project_deeper_subdir = 'p/' * int(self.buildset[project_dir_depth_key])
418
 
419
        return build_maindir, build_buildset_dir, build_tooldir, project_deeper_subdir
420
 
421
 
422
    def get_lib_build_dirs(self, build_type, lib_dicts=None):
423
        """Get the subdirectories within the central tool build directory for all HDL libraries in the specified list of lib_dicts.
424
 
425
        The build_type can be:
426
            'sim'   uses the 'sim_tool_name'   key in the self.buildset
427
            'synth' uses the 'synth_tool_name' key in the self.buildset
428
 
429
        The build dir key value must be an absolute directory path. The lib build dir consists of
430
            - the absolute path to the central main build directory
431
            - the buildset_name key value as subdirectory
432
            - the tool_name_key value as subdirectory
433
            - the library name as library subdirectory
434
            - zero or more extra subdirectory levels to allow for relative file reference from project file location
435
        """
436
        if lib_dicts==None:
437
            lib_dicts = self.libs.configfiles.values()
438
        build_maindir, build_buildset_dir, build_tooldir, project_deeper_subdir = self.get_tool_build_dir(build_type)
439
        build_dirs = []
440
        for lib_dict in cm.listify(lib_dicts):
441
            lib_name = lib_dict['hdl_lib_name']
442
            build_dirs.append(join(build_maindir, build_buildset_dir, build_tooldir, lib_name, project_deeper_subdir))  # central build main directory with subdirectory per library
443
        return cm.unlistify(build_dirs)
444
 
445
 
446
    def create_lib_order_files(self, build_type, lib_names=None):
447
        """Create the compile order file '<lib_name>_lib_order.txt' for all HDL libraries in the specified list of lib_names.
448
 
449
           The file is stored in the sim build directory of the HDL library.
450
           The file is read by commands.do in Modelsim to avoid having to derive the library compile order in TCL.
451
        """
452
        if lib_names==None:
453
            lib_names=self.lib_names
454
 
455
        lib_dicts = self.libs.get_configfiles(key='hdl_lib_name', values=lib_names)
456
        for lib_dict in lib_dicts:
457
            lib_name = lib_dict['hdl_lib_name']
458
            lib_order = self.derive_lib_order(build_type, lib_name)
459
            file_name = lib_name + '_lib_order.txt'
460
            file_path = self.get_lib_build_dirs('sim', lib_dicts=lib_dict)
461
            cm.mkdir(file_path)
462
            filePathName = join(file_path, file_name)
463
            with open(filePathName, 'w') as fp:
464
                for lib in lib_order:
465
                    fp.write('%s ' % lib)
466
        print "Created {} lib-order files".format(len(lib_dicts))
467
 
468
    # Methods to create sub directories at various levels in the build directory as defined in HDL tool config file
469
    def create_sub_directory_in_build_main_dir(self, build_type, subdir_name):
470
        """Create <subdir_name>/ in the central <build_main>/ directory
471
        """
472
        build_maindir, build_buildset_dir, build_tooldir, project_deeper_subdir = self.get_tool_build_dir(build_type)
473
        subdir_path = join(build_maindir, subdir_name)
474
        cm.mkdir(subdir_path)
475
 
476
    def create_sub_directory_in_build_buildset_dir(self, build_type, subdir_name):
477
        """Create <subdir_name>/ in the central <build_main>/<build_buildset_dir>/ directory.
478
        """
479
        build_maindir, build_buildset_dir, build_tooldir, project_deeper_subdir = self.get_tool_build_dir(build_type)
480
        subdir_path = join(build_maindir, build_buildset_dir, subdir_name)
481
        cm.mkdir(subdir_path)
482
 
483
    def create_sub_directory_in_build_tool_dir(self, build_type, subdir_name):
484
        """Create <subdir_name>/ in the central <build_main>/<build_buildset_dir>/<build_tooldir>/ directory.
485
        """
486
        build_maindir, build_buildset_dir, build_tooldir, project_deeper_subdir = self.get_tool_build_dir(build_type)
487
        subdir_path = join(build_maindir, build_buildset_dir, build_tooldir, subdir_name)
488
        cm.mkdir(subdir_path)
489
 
490
    def create_sub_directory_in_build_lib_dir(self, build_type, subdir_name, lib_names=None):
491
        """Create <subdir_name>/ in project local build directory <lib_name>/ for all HDL libraries in the specified list of lib_names.
492
        """
493
        if lib_names==None:
494
            lib_names=self.lib_names
495
        lib_dicts = self.libs.get_configfiles('hdl_lib_name', values=lib_names)
496
        for lib_dict in lib_dicts:
497
            lib_path = self.get_lib_build_dirs('sim', lib_dicts=lib_dict)
498
            subdir_path = join(lib_path, subdir_name)
499
            cm.mkdir(subdir_path)
500
        print "Created {} subdirectories".format(len(lib_dicts))
501
 
502
    def copy_files(self, build_type, lib_names=None):
503
        """
504
        Copy all source directories and source files listed at the <tool_name>_copy_files key.
505
        The build_type selects the <tool_name>_copy_files key using the <build_type>_tool_name key value
506
        from the hdl_buildset_<buildset>.cfg.
507
        The <tool_name>_copy_files key expects a source and a destination pair per listed directory or file:
508
        - The sources need to be specified with absolute path or relative to the HDL library source directory
509
          where the hdllib.cfg is stored
510
        - The destinations need to be specified with absolute path or relative to HDL library build directory
511
          where the project file (e.g. mpf, qpf) gets stored
512
 
513
        Arguments:
514
        - lib_names  : zero or more HDL libraries
515
        """
516
        if lib_names==None:
517
            lib_names=self.lib_names
518
 
519
        lib_dicts          = self.libs.get_configfiles(key='hdl_lib_name', values=lib_names)
520
        tool_name_key      = build_type + '_tool_name'
521
        tool_name_value    = self.buildset[tool_name_key]
522
        tool_name_copy_key = tool_name_value + '_copy_files'
523
        lib_count          = 0
524
        dir_count          = 0
525
        file_count         = 0
526
        for lib_dict in lib_dicts:
527
            if tool_name_copy_key in lib_dict.content:
528
                lib_count += 1
529
                lib_path       = lib_dict.location
530
                build_dir_path = self.get_lib_build_dirs(build_type, lib_dicts=lib_dict)
531
                cm.mkdir(build_dir_path)
532
                key_values     = lib_dict[tool_name_copy_key].split()
533
                sources        = key_values[0::2]
534
                destinations   = key_values[1::2]
535
                file_io = zip(sources, destinations)
536
                for fpn_io in file_io:
537
                    sourcePathName  = cm.expand_file_path_name(fpn_io[0], lib_path)
538
                    destinationPath = cm.expand_file_path_name(fpn_io[1], build_dir_path)
539
                    if isfile(sourcePathName):
540
                        file_count += 1
541
                        shutil.copy(sourcePathName, destinationPath)     # copy file
542
                    else:
543
                        dir_count += 1
544
                        copy_tree(sourcePathName, destinationPath)       # copy directory tree (will create new destinationPath directory)
545
        print "Copied {} files and {} directories for {} libraries".format(file_count, dir_count, lib_count)
546
 
547
 
548
if __name__ == '__main__':
549
    # Parse command line arguments
550
    buildsetSelect = sorted([cfgfile[13:-4] for cfgfile in listdir(expandvars('$HDL_CONFIG_DIR'))
551
                                                if cfgfile.startswith("hdl_buildset_") and cfgfile.endswith(".cfg")])
552
    argparser = ArgumentParser(description='Hdl_config shows several selections of all of your hdllib.cfg files.')
553
    argparser.add_argument('buildset', help='choose buildset %s' % (buildsetSelect))
554
    argparser.add_argument('--toplib', default=None, required=False, help='top library to show more information about.')
555
    args = argparser.parse_args()
556
 
557
    # check arguments
558
    if args.buildset not in buildsetSelect:
559
        print 'buildset %s is not supported' % args.buildset
560
        print "Supported buildset are:", buildsetSelect
561
        sys.exit(1)
562
    args.buildsetFile = 'hdl_buildset_' + args.buildset + '.cfg'
563
 
564
    # Read the dictionary info from all HDL tool and library configuration files in the current directory and the sub directories
565
    hdl = HdlLibrariesWizard(toolRootDir  = expandvars('${HDL_CONFIG_DIR}'),
566
                             toolFileName = args.buildsetFile,
567
                             libFileName  = 'hdllib.cfg')
568
 
569
    print '#'
570
    print '# HdlLibrariesWizard:'
571
    print '#'
572
    for libname in hdl.libs.configfiles.keys():
573
        print "\n", libname
574
        libinfo = hdl.libs.configfiles[libname]
575
        for k,v in libinfo.content.iteritems():
576
            print k, '=', v
577
    print ''
578
 
579
    print ''
580
    print 'Library paths :'
581
    for libname in hdl.libs.configfiles.keys():
582
        print '    ', hdl.libs.configfiles[libname].location
583
 
584
    print ''
585
    print 'Library file names :"'
586
    for libname in hdl.libs.configfiles.keys():
587
        print '    ', libname
588
 
589
    print ''
590
    print 'Library section headers :'
591
    for libname,libinfo in hdl.libs.configfiles.iteritems():
592
        print '    %-52s : %s' % (libname, libinfo['section_headers'])
593
 
594
    print ''
595
    print 'Build directories for simulation:'
596
    for build_dir in hdl.get_lib_build_dirs('sim'):
597
        print '    ', build_dir
598
 
599
    print ''
600
    print 'Build directories for synthesis:'
601
    for build_dir in hdl.get_lib_build_dirs('synth'):
602
        print '    ', build_dir
603
 
604
    print ''
605
    print 'Removed library names = \n', hdl.removed_libs.keys()
606
 
607
    print ''
608
    print "Unavailable library names in any 'hdl_lib_uses_synth' key = \n", hdl.unavailable_use_synth_libs
609
    print "Unavailable library names in any 'hdl_lib_uses_ip' key = \n", hdl.unavailable_use_ip_libs
610
    print "Unavailable library names in any 'hdl_lib_uses_sim' key = \n", hdl.unavailable_use_sim_libs
611
    print "Unavailable library names in any 'hdl_lib_uses_*' key = \n", hdl.unavailable_use_libs
612
    print ''
613
    print "Unavailable library names in any 'hdl_lib_include_ip' key = \n", hdl.unavailable_include_ip_libs
614
 
615
    print ''
616
    print "Used library clause names that are explicitly disclosed at the 'hdl_lib_disclose_library_clause_names' keys:"
617
    for key in hdl.disclosed_library_clause_names.keys():
618
        print '    %-52s : %s' % (key, hdl.disclosed_library_clause_names[key])
619
 
620
    if args.toplib:
621
        for build_type in ['sim', 'synth']:
622
            print ''
623
            print 'derive_all_use_libs for %s of %s = \n' % (build_type, args.toplib), \
624
                                                             hdl.derive_all_use_libs(build_type, args.toplib)
625
            print ''
626
            print 'derive_lib_order for %s of %s = \n' % (build_type, args.toplib), \
627
                                                          hdl.derive_lib_order(build_type, args.toplib)
628
 
629
 

powered by: WebSVN 2.1.0

© copyright 1999-2019 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.