247247import traceback
248248import logging
249249import json
250- import os
251- from os .path import exists , abspath , join , basename , splitext , normpath , dirname
250+ from os import mkdir , makedirs , environ , popen
251+ from os .path import (
252+ abspath ,
253+ basename ,
254+ dirname ,
255+ exists ,
256+ isabs ,
257+ isdir ,
258+ isfile ,
259+ join ,
260+ normpath ,
261+ splitext ,
262+ )
252263from glob import glob
253264from fnmatch import fnmatch
254265from vunit .database import PickledDataBase , DataBase
@@ -887,7 +898,7 @@ def _create_simulator_if(self):
887898 exit (1 )
888899
889900 if not exists (self ._simulator_output_path ):
890- os . makedirs (self ._simulator_output_path )
901+ makedirs (self ._simulator_output_path )
891902
892903 return self ._simulator_class .from_args (args = self ._args ,
893904 output_path = self ._simulator_output_path )
@@ -1011,7 +1022,7 @@ def _create_output_path(self, clean):
10111022 if clean :
10121023 ostools .renew_path (self ._output_path )
10131024 elif not exists (self ._output_path ):
1014- os . makedirs (self ._output_path )
1025+ makedirs (self ._output_path )
10151026
10161027 ostools .renew_path (self ._preprocessed_path )
10171028
@@ -1080,12 +1091,6 @@ def add_random(self):
10801091 """
10811092 self ._builtins .add ("random" )
10821093
1083- def add_verification_components (self ):
1084- """
1085- Add verification component library
1086- """
1087- self ._builtins .add ("verification_components" )
1088-
10891094 def add_osvvm (self ):
10901095 """
10911096 Add osvvm library
@@ -1098,6 +1103,27 @@ def add_json4vhdl(self):
10981103 """
10991104 self ._builtins .add ("json4vhdl" )
11001105
1106+ def add_verification_components (self , location = None ):
1107+ """
1108+ Add verification component library
1109+
1110+ :param location: path of the optional directory to contain third-party VCs.
1111+ :returns: a dict containing the 'third_party' location and the known/supported VCs.
1112+ """
1113+ self ._builtins .add ("verification_components" )
1114+ return _read_vcs_cfg (location = location )
1115+
1116+ def use_verification_components (self , cfg , vc_list ):
1117+ """
1118+ Use verification components named in 'vc_list' and defined in 'cfg'
1119+
1120+ :param cfg: the configuration object returned by 'add_verification_components'.
1121+ :param vc_list: a list containing the names of the VCs which are to be used.
1122+ """
1123+ def add_vc_library (vc_cfg , loc ):
1124+ self .add_library (vc_cfg ['lib' ], allow_duplicate = True ).add_source_files (join (loc , 'src' , '*.vhd' ))
1125+ _traverse_vc_cfg (cfg , vc_list , _add_vc , add_vc_library )
1126+
11011127 def get_compile_order (self , source_files = None ):
11021128 """
11031129 Get the compile order of all or specific source files and
@@ -1142,6 +1168,68 @@ def get_implementation_subset(self, source_files):
11421168 for source_file in source_files ])
11431169
11441170
1171+ def _read_vcs_cfg (location = None ):
1172+ """
1173+
1174+ """
1175+ root = join (dirname (__file__ ), 'vhdl' , 'verification_components' )
1176+ cfg = {'third_party' : location or join (root , 'third_party' )}
1177+ cfg .update (json .loads (open (join (root , 'vc_list.json' )).read ()))
1178+ return cfg
1179+
1180+
1181+ def _traverse_vc_cfg (cfg , vc_list , func , task , depends = True ):
1182+ """
1183+
1184+ """
1185+ wh_loc = cfg ['third_party' ]
1186+ if not isdir (wh_loc ):
1187+ print ('Creating directory ' + wh_loc )
1188+ mkdir (wh_loc )
1189+
1190+ for key in vc_list :
1191+ if key not in cfg :
1192+ print ('VC <' + key + '> not defined. Please add it to the configuration first.' )
1193+ exit (1 )
1194+ else :
1195+ func (key , cfg , task , depends = depends )
1196+
1197+
1198+ def _add_vc (key , cfg , task , depends = True ):
1199+ """
1200+ Add the sources of a known VC to this project
1201+
1202+ :param key: name of the VC to be added.
1203+ :param cfg: configuration object returned by 'add_verification_components'.
1204+ :param task: function to be executed for each valid VC configuration.
1205+ """
1206+ item = cfg [key ]
1207+ loc = item ['path' ] if isabs (item ['path' ]) else join (cfg ['third_party' ], item ['path' ])
1208+ if not isdir (loc ):
1209+ print ('VC <' + key + '> not available locally.' )
1210+ print (popen (' ' .join ([
1211+ 'git' ,
1212+ 'clone' ,
1213+ item ['remote' ],
1214+ loc
1215+ ])).read ())
1216+
1217+ vc_cfg_file = join (loc , 'vunit_cfg.json' )
1218+ if not isfile (vc_cfg_file ):
1219+ print ('File <' + vc_cfg_file + '> not found.' )
1220+ exit (1 )
1221+ vc_cfg = json .loads (open (vc_cfg_file ).read ())
1222+
1223+ if depends :
1224+ for name , _ in vc_cfg ['depends' ].items ():
1225+ # TODO Check 'val', which tells the minimum and/or maximum required version
1226+ if name == 'VUnit' :
1227+ continue
1228+ _add_vc (name , cfg , task )
1229+
1230+ task (vc_cfg , loc )
1231+
1232+
11451233class Library (object ):
11461234 """
11471235 User interface of a library
@@ -1994,7 +2082,7 @@ def select_vhdl_standard(vhdl_standard=None):
19942082 if vhdl_standard is not None :
19952083 check_vhdl_standard (vhdl_standard , from_str = "From class initialization" )
19962084 else :
1997- vhdl_standard = os . environ .get ('VUNIT_VHDL_STANDARD' , '2008' )
2085+ vhdl_standard = environ .get ('VUNIT_VHDL_STANDARD' , '2008' )
19982086 check_vhdl_standard (vhdl_standard , from_str = "VUNIT_VHDL_STANDARD environment variable" )
19992087
20002088 return vhdl_standard
0 commit comments