opencos-eda 0.2.45__py3-none-any.whl → 0.2.47__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- opencos/deps_helpers.py +78 -32
- opencos/deps_schema.py +11 -0
- opencos/eda_base.py +28 -13
- opencos/eda_config_defaults.yml +1 -0
- opencos/tests/test_deps_helpers.py +56 -19
- opencos/tools/vivado.py +18 -12
- {opencos_eda-0.2.45.dist-info → opencos_eda-0.2.47.dist-info}/METADATA +1 -1
- {opencos_eda-0.2.45.dist-info → opencos_eda-0.2.47.dist-info}/RECORD +13 -13
- {opencos_eda-0.2.45.dist-info → opencos_eda-0.2.47.dist-info}/WHEEL +0 -0
- {opencos_eda-0.2.45.dist-info → opencos_eda-0.2.47.dist-info}/entry_points.txt +0 -0
- {opencos_eda-0.2.45.dist-info → opencos_eda-0.2.47.dist-info}/licenses/LICENSE +0 -0
- {opencos_eda-0.2.45.dist-info → opencos_eda-0.2.47.dist-info}/licenses/LICENSE.spdx +0 -0
- {opencos_eda-0.2.45.dist-info → opencos_eda-0.2.47.dist-info}/top_level.txt +0 -0
opencos/deps_helpers.py
CHANGED
|
@@ -68,6 +68,9 @@ class Defaults:
|
|
|
68
68
|
'shell',
|
|
69
69
|
'work-dir-add-srcs', 'work-dir-add-sources',
|
|
70
70
|
'peakrdl',
|
|
71
|
+
'run-from-work-dir', # default True
|
|
72
|
+
'filepath-subst-target-dir', # default True
|
|
73
|
+
'dirpath-subst-target-dir', # default False
|
|
71
74
|
'var-subst-args',
|
|
72
75
|
'var-subst-os-env',
|
|
73
76
|
'tee',
|
|
@@ -383,24 +386,38 @@ def deps_list_target_sanitize(entry, default_key:str='deps', target_node:str='',
|
|
|
383
386
|
assert False, f"Can't convert to list {entry=} {default_key=} {target_node=} {deps_file=}"
|
|
384
387
|
|
|
385
388
|
|
|
386
|
-
def path_substitutions_relative_to_work_dir(
|
|
389
|
+
def path_substitutions_relative_to_work_dir(
|
|
390
|
+
exec_list: list, info_str: str, target_path: str,
|
|
391
|
+
enable_filepath_subst: bool, enable_dirpath_subst: bool
|
|
392
|
+
) -> list:
|
|
393
|
+
|
|
394
|
+
if not enable_filepath_subst and not enable_dirpath_subst:
|
|
395
|
+
return exec_list
|
|
387
396
|
|
|
388
397
|
# Look for path substitutions, b/c we later "work" in self.args['work-dir'], but
|
|
389
398
|
# files should be relative to our target_path.
|
|
390
|
-
for
|
|
399
|
+
for i,word in enumerate(exec_list):
|
|
391
400
|
m = re.search(r'(\.+\/+[^"\;\:\|\<\>\*]*)$', word)
|
|
392
401
|
if m:
|
|
393
402
|
# ./, ../, file=./../whatever It might be a filepath.
|
|
394
403
|
# [^"\;\:\|\<\>\*] is looking for non-path like characters, so we dont' have a trailing
|
|
395
404
|
# " : ; < > |
|
|
396
|
-
# try and see if this file exists. Note that files in the self.args['work-dir'] don't
|
|
405
|
+
# try and see if this file or dir exists. Note that files in the self.args['work-dir'] don't
|
|
397
406
|
# need this, and we can't assume dir levels in the work-dir.
|
|
398
407
|
try:
|
|
399
408
|
try_path = os.path.abspath(os.path.join(os.path.abspath(target_path), m.group(1)))
|
|
400
|
-
if os.path.isfile(try_path):
|
|
409
|
+
if enable_filepath_subst and os.path.isfile(try_path):
|
|
401
410
|
# make the substitution
|
|
402
|
-
exec_list[
|
|
403
|
-
debug(f'path substitution {info_str=} {target_path=}: replaced - {word=}
|
|
411
|
+
exec_list[i] = word.replace(m.group(1), try_path)
|
|
412
|
+
debug(f'file path substitution {info_str=} {target_path=}: replaced - {word=}'
|
|
413
|
+
f'is now ={exec_list[i]}. This can be disabled in DEPS with:',
|
|
414
|
+
'"filepath-subst-targetdir: false"')
|
|
415
|
+
elif enable_dirpath_subst and os.path.isdir(try_path):
|
|
416
|
+
# make the substitution
|
|
417
|
+
exec_list[i] = word.replace(m.group(1), try_path)
|
|
418
|
+
debug(f'dir path substitution {info_str=} {target_path=}: replaced - {word=}'
|
|
419
|
+
f'is now ={exec_list[i]}. This can be disabled in DEPS with:',
|
|
420
|
+
'"dirpath-subst-targetdir: false"')
|
|
404
421
|
except:
|
|
405
422
|
pass
|
|
406
423
|
|
|
@@ -1033,7 +1050,10 @@ class DepsProcessor:
|
|
|
1033
1050
|
|
|
1034
1051
|
|
|
1035
1052
|
|
|
1036
|
-
def parse_deps_shell_str(line
|
|
1053
|
+
def parse_deps_shell_str(line: str, target_path: str, target_node: str,
|
|
1054
|
+
enable_filepath_subst_target_dir: bool = True,
|
|
1055
|
+
enable_dirpath_subst_target_dir: bool = False,
|
|
1056
|
+
enable: bool = True) -> dict:
|
|
1037
1057
|
'''Returns None or a dict of a possible shell command from line (str)
|
|
1038
1058
|
|
|
1039
1059
|
Examples of 'line' str:
|
|
@@ -1049,24 +1069,30 @@ def parse_deps_shell_str(line : str, target_path : str, target_node : str, enabl
|
|
|
1049
1069
|
target_node (str) -- from dependency parsing, the target containing this 'line' str.
|
|
1050
1070
|
'''
|
|
1051
1071
|
if not enable:
|
|
1052
|
-
return
|
|
1072
|
+
return {}
|
|
1053
1073
|
|
|
1054
1074
|
m = re.match(r'^\s*shell\@(.*)\s*$', line)
|
|
1055
1075
|
if not m:
|
|
1056
|
-
return
|
|
1076
|
+
return {}
|
|
1057
1077
|
|
|
1058
1078
|
exec_str = m.group(1)
|
|
1059
1079
|
exec_list = exec_str.split()
|
|
1060
1080
|
|
|
1061
1081
|
# Look for path substitutions, b/c we later "work" in self.args['work-dir'], but
|
|
1062
1082
|
# files should be relative to our target_path.
|
|
1063
|
-
|
|
1083
|
+
# Note this can be disable in DEPS via path-subst-target-dir=False
|
|
1084
|
+
exec_list = path_substitutions_relative_to_work_dir(
|
|
1085
|
+
exec_list=exec_list, info_str='shell@', target_path=target_path,
|
|
1086
|
+
enable_filepath_subst=enable_filepath_subst_target_dir,
|
|
1087
|
+
enable_dirpath_subst=enable_dirpath_subst_target_dir
|
|
1088
|
+
)
|
|
1064
1089
|
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1090
|
+
return {
|
|
1091
|
+
'target_path': os.path.abspath(target_path),
|
|
1092
|
+
'target_node': target_node,
|
|
1093
|
+
'run_from_work_dir': True, # may be overriden later.
|
|
1094
|
+
'exec_list': exec_list,
|
|
1095
|
+
}
|
|
1070
1096
|
|
|
1071
1097
|
|
|
1072
1098
|
def parse_deps_work_dir_add_srcs(line : str, target_path : str, target_node : str, enable : bool = True):
|
|
@@ -1098,8 +1124,12 @@ def parse_deps_work_dir_add_srcs(line : str, target_path : str, target_node : st
|
|
|
1098
1124
|
return d
|
|
1099
1125
|
|
|
1100
1126
|
|
|
1101
|
-
def parse_deps_peakrdl(
|
|
1102
|
-
|
|
1127
|
+
def parse_deps_peakrdl(
|
|
1128
|
+
line: str, target_path: str, target_node: str, enable: bool = True,
|
|
1129
|
+
enable_filepath_subst_target_dir: bool = True,
|
|
1130
|
+
enable_dirpath_subst_target_dir: bool = False,
|
|
1131
|
+
tool: str = ''
|
|
1132
|
+
) -> dict:
|
|
1103
1133
|
'''Returns None or a dict describing a PeakRDL CSR register generator dependency
|
|
1104
1134
|
|
|
1105
1135
|
Examples of 'line' str:
|
|
@@ -1137,12 +1167,12 @@ def parse_deps_peakrdl(line : str, target_path : str, target_node : str, enable
|
|
|
1137
1167
|
|
|
1138
1168
|
sv_files = list()
|
|
1139
1169
|
top = ''
|
|
1140
|
-
for
|
|
1170
|
+
for i,str_value in enumerate(args_list):
|
|
1141
1171
|
if '--top=' in str_value:
|
|
1142
1172
|
_, top = str_value.split('=')
|
|
1143
1173
|
elif '--top' in str_value:
|
|
1144
|
-
if
|
|
1145
|
-
top = args_list[
|
|
1174
|
+
if i + 1 < len(args_list):
|
|
1175
|
+
top = args_list[i + 1]
|
|
1146
1176
|
|
|
1147
1177
|
for str_item in args_list:
|
|
1148
1178
|
if str_item[-4:] == '.rdl':
|
|
@@ -1170,10 +1200,13 @@ def parse_deps_peakrdl(line : str, target_path : str, target_node : str, enable
|
|
|
1170
1200
|
# Make these look like a dep_shell_command:
|
|
1171
1201
|
for one_cmd_as_list in shell_commands:
|
|
1172
1202
|
ret_dict['shell_commands_list'].append(
|
|
1173
|
-
parse_deps_shell_str(
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1203
|
+
parse_deps_shell_str(
|
|
1204
|
+
line=(' shell@ ' + ' '.join(one_cmd_as_list)),
|
|
1205
|
+
target_path=target_path,
|
|
1206
|
+
target_node=target_node,
|
|
1207
|
+
enable_filepath_subst_target_dir=enable_filepath_subst_target_dir,
|
|
1208
|
+
enable_dirpath_subst_target_dir=enable_dirpath_subst_target_dir
|
|
1209
|
+
)
|
|
1177
1210
|
)
|
|
1178
1211
|
|
|
1179
1212
|
# Make the work_dir_add_srcs dict:
|
|
@@ -1236,13 +1269,21 @@ def deps_commands_handler(config: dict, eda_args: dict,
|
|
|
1236
1269
|
|
|
1237
1270
|
tee_fpath = command.get('tee', None)
|
|
1238
1271
|
|
|
1239
|
-
|
|
1272
|
+
# These are both optional bools, default True, would have to explicitly be set to False
|
|
1273
|
+
# to take effect:
|
|
1274
|
+
run_from_work_dir = command.get('run-from-work-dir', True)
|
|
1275
|
+
filepath_subst_target_dir = command.get('filepath-subst-target-dir', True)
|
|
1276
|
+
dirpath_subst_target_dir = command.get('dirpath-subst-target-dir', False)
|
|
1240
1277
|
|
|
1241
|
-
|
|
1242
|
-
if key.startswith('var-subst'):
|
|
1243
|
-
continue
|
|
1278
|
+
for key,item in command.items():
|
|
1244
1279
|
|
|
1245
|
-
|
|
1280
|
+
# skip the tee and var-subst-* keys, since these types are bools and not commands.
|
|
1281
|
+
if key in ['tee',
|
|
1282
|
+
'var-subst-os-env',
|
|
1283
|
+
'var-subst-args',
|
|
1284
|
+
'run-from-work-dir',
|
|
1285
|
+
'filepath-subst-target-dir',
|
|
1286
|
+
'dirpath-subst-target-dir']:
|
|
1246
1287
|
continue
|
|
1247
1288
|
|
|
1248
1289
|
# Optional variable substituion in commands
|
|
@@ -1253,15 +1294,18 @@ def deps_commands_handler(config: dict, eda_args: dict,
|
|
|
1253
1294
|
if key == 'shell':
|
|
1254
1295
|
# For now, piggyback on parse_deps_shell_str:
|
|
1255
1296
|
ret_dict = parse_deps_shell_str(
|
|
1256
|
-
line
|
|
1257
|
-
target_path
|
|
1258
|
-
target_node
|
|
1297
|
+
line=('shell@ ' + item),
|
|
1298
|
+
target_path=target_path,
|
|
1299
|
+
target_node=target_node,
|
|
1300
|
+
enable_filepath_subst_target_dir=filepath_subst_target_dir,
|
|
1301
|
+
enable_dirpath_subst_target_dir=dirpath_subst_target_dir,
|
|
1259
1302
|
enable=config['dep_command_enables']['shell'],
|
|
1260
1303
|
)
|
|
1261
1304
|
# To support 'tee: <some-file>' need to append it to last
|
|
1262
1305
|
# list item in ret_dict['exec_list'], and make it a util.ShellCommandList.
|
|
1263
1306
|
if tee_fpath:
|
|
1264
1307
|
ret_dict['exec_list'] = ShellCommandList(ret_dict['exec_list'], tee_fpath=tee_fpath)
|
|
1308
|
+
ret_dict['run_from_work_dir'] = run_from_work_dir
|
|
1265
1309
|
assert ret_dict, f'shell command failed in {dep=} {target_node=} in {deps_file=}'
|
|
1266
1310
|
shell_commands_list.append(ret_dict) # process this later, append to our to-be-returned tuple
|
|
1267
1311
|
|
|
@@ -1283,6 +1327,8 @@ def deps_commands_handler(config: dict, eda_args: dict,
|
|
|
1283
1327
|
line = 'peakrdl@ ' + item,
|
|
1284
1328
|
target_path = target_path,
|
|
1285
1329
|
target_node = target_node,
|
|
1330
|
+
enable_filepath_subst_target_dir=filepath_subst_target_dir,
|
|
1331
|
+
enable_dirpath_subst_target_dir=dirpath_subst_target_dir,
|
|
1286
1332
|
enable=config['dep_command_enables']['peakrdl'],
|
|
1287
1333
|
tool=eda_args.get('tool', '')
|
|
1288
1334
|
)
|
opencos/deps_schema.py
CHANGED
|
@@ -69,6 +69,14 @@ my_target_name:
|
|
|
69
69
|
- shell: <---- string for shell command to be run
|
|
70
70
|
var-subst-args: <---- bool, perform var substitution using args
|
|
71
71
|
var-subst-os-env: <---- bool, perform var substitution using os.environ
|
|
72
|
+
run-from-work-dir: <---- bool, default True, if False runs from target dir
|
|
73
|
+
instead of work-dir.
|
|
74
|
+
filepath-subst-target-dir: <---- bool, default True, if False does not perform
|
|
75
|
+
file path substitution relative to target dir
|
|
76
|
+
(if substituted file exists).
|
|
77
|
+
dirpath-subst-target-dir: <---- bool, default False, if True performs
|
|
78
|
+
directory path substitution relative to target dir
|
|
79
|
+
(if substituted directory exists).
|
|
72
80
|
tee: <---- string, filename to write logs to
|
|
73
81
|
- work-dir-add-sources: <---- work-dir-add-sources, optional list (or string)
|
|
74
82
|
- some_file_gen_from_sh.sv <---- string filename that we created with sh command
|
|
@@ -150,6 +158,9 @@ DEPS_COMMANDS_LIST = [
|
|
|
150
158
|
Optional('shell'): str,
|
|
151
159
|
Optional('var-subst-args'): bool,
|
|
152
160
|
Optional('var-subst-os-env'): bool,
|
|
161
|
+
Optional('run-from-work-dir'): bool,
|
|
162
|
+
Optional('filepath-subst-target-dir'): bool,
|
|
163
|
+
Optional('dirpath-subst-target-dir'): bool,
|
|
153
164
|
Optional('tee'): Or(str, type(None)),
|
|
154
165
|
},
|
|
155
166
|
{
|
opencos/eda_base.py
CHANGED
|
@@ -716,8 +716,9 @@ class CommandDesign(Command):
|
|
|
716
716
|
|
|
717
717
|
log_fnames_count = {} # count per target_node.
|
|
718
718
|
|
|
719
|
-
for
|
|
719
|
+
for i, d in enumerate(self.dep_shell_commands):
|
|
720
720
|
clist = util.ShellCommandList(d['exec_list'])
|
|
721
|
+
run_from_work_dir = d['run_from_work_dir'] # default True
|
|
721
722
|
log = clist.tee_fpath
|
|
722
723
|
target_node = d["target_node"]
|
|
723
724
|
if clist.tee_fpath is None:
|
|
@@ -729,24 +730,38 @@ class CommandDesign(Command):
|
|
|
729
730
|
all_cmds_lists += [
|
|
730
731
|
[], # blank line
|
|
731
732
|
# comment, where it came from, log to {node}__shell_{lognum}.log (or tee name from DEPS.yml)
|
|
732
|
-
[f'# command {
|
|
733
|
-
# actual command (list or util.ShellCommandList)
|
|
734
|
-
clist,
|
|
733
|
+
[f'# command {i}: target: {d["target_path"]} : {target_node} --> {log}'],
|
|
735
734
|
]
|
|
735
|
+
if not run_from_work_dir:
|
|
736
|
+
all_cmds_lists.append([f'cd {d["target_path"]}'])
|
|
737
|
+
|
|
738
|
+
# actual command (list or util.ShellCommandList)
|
|
739
|
+
all_cmds_lists.append(clist)
|
|
740
|
+
|
|
741
|
+
if not run_from_work_dir:
|
|
742
|
+
all_cmds_lists.append([f'cd {os.path.abspath(self.args["work-dir"])}'])
|
|
743
|
+
|
|
736
744
|
d['exec_list'] = clist # update to tee_fpath is set.
|
|
737
745
|
|
|
738
746
|
util.write_shell_command_file(dirpath=self.args['work-dir'], filename='pre_compile_dep_shell_commands.sh',
|
|
739
747
|
command_lists=all_cmds_lists)
|
|
740
748
|
|
|
741
|
-
for
|
|
742
|
-
util.info(f'run_dep_shell_commands {
|
|
749
|
+
for i,d in enumerate(self.dep_shell_commands):
|
|
750
|
+
util.info(f'run_dep_shell_commands {i=}: {d=}')
|
|
743
751
|
clist = util.ShellCommandList(d['exec_list'])
|
|
752
|
+
tee_fpath=clist.tee_fpath
|
|
753
|
+
if d['run_from_work_dir']:
|
|
754
|
+
run_from_dir = self.args['work-dir']
|
|
755
|
+
else:
|
|
756
|
+
# Run from the target's directory (not the `eda` caller $PWD)
|
|
757
|
+
run_from_dir = d["target_path"]
|
|
758
|
+
tee_fpath = os.path.abspath(os.path.join(self.args['work-dir'], tee_fpath))
|
|
744
759
|
# NOTE(drew): shell=True subprocess call, can disable with self.config
|
|
745
760
|
if sys.platform.startswith('win'):
|
|
746
761
|
# for Windows, we run shell=True otherwise most built-in cmd.exe calls won't work.
|
|
747
|
-
self.exec(
|
|
762
|
+
self.exec(run_from_dir, clist, tee_fpath=tee_fpath, shell=True)
|
|
748
763
|
else:
|
|
749
|
-
self.exec(
|
|
764
|
+
self.exec(run_from_dir, clist, tee_fpath=tee_fpath,
|
|
750
765
|
shell=self.config.get('deps_subprocess_shell', False))
|
|
751
766
|
|
|
752
767
|
def update_file_lists_for_work_dir(self):
|
|
@@ -766,10 +781,10 @@ class CommandDesign(Command):
|
|
|
766
781
|
my_file_lists_list = [self.files_v, self.files_sv, self.files_vhd, self.files_cpp,
|
|
767
782
|
self.files_sdc]
|
|
768
783
|
for my_file_list in my_file_lists_list:
|
|
769
|
-
for
|
|
784
|
+
for i,value in enumerate(my_file_list):
|
|
770
785
|
if value and type(value) is str and value.startswith(self._work_dir_add_srcs_path_string):
|
|
771
786
|
new_value = os.path.join(work_dir_abspath, value[_work_dir_add_srcs_path_string_len :])
|
|
772
|
-
my_file_list[
|
|
787
|
+
my_file_list[i] = new_value
|
|
773
788
|
util.debug(f"file lists: replaced {value} with {new_value}")
|
|
774
789
|
|
|
775
790
|
def update_non_source_files_in_work_dir(self):
|
|
@@ -1575,10 +1590,10 @@ class CommandParallel(Command):
|
|
|
1575
1590
|
else:
|
|
1576
1591
|
util.info(f"Parallel: <No jobs found>")
|
|
1577
1592
|
# Make sure all jobs have a set status:
|
|
1578
|
-
for
|
|
1593
|
+
for i,rc in enumerate(self.jobs_status):
|
|
1579
1594
|
if rc is None or type(rc) != int:
|
|
1580
|
-
self.error(f'job {
|
|
1581
|
-
jobs_status[
|
|
1595
|
+
self.error(f'job {i=} {rc=} did not return a proper return code')
|
|
1596
|
+
jobs_status[i] = 1
|
|
1582
1597
|
|
|
1583
1598
|
# if self.status > 0, then keep it non-zero, else set it if we still have running jobs.
|
|
1584
1599
|
if self.status == 0:
|
opencos/eda_config_defaults.yml
CHANGED
|
@@ -14,7 +14,7 @@ from opencos import eda_tool_helper, deps_helpers
|
|
|
14
14
|
|
|
15
15
|
THISPATH = os.path.dirname(__file__)
|
|
16
16
|
|
|
17
|
-
# Figure out what tools the system has
|
|
17
|
+
# Figure out what tools the system has avail, without calling eda.main(..)
|
|
18
18
|
config, tools_loaded = eda_tool_helper.get_config_and_tools_loaded()
|
|
19
19
|
|
|
20
20
|
|
|
@@ -58,63 +58,100 @@ def test_get_all_targets_eda_multi():
|
|
|
58
58
|
def test_parse_deps_shell_str__no_parse():
|
|
59
59
|
line = 'some_file.sv'
|
|
60
60
|
d = deps_helpers.parse_deps_shell_str(line, '', '')
|
|
61
|
-
assert d
|
|
61
|
+
assert not d, f'{d=}'
|
|
62
62
|
|
|
63
63
|
line = 'some_target:'
|
|
64
64
|
d = deps_helpers.parse_deps_shell_str(line, '', '')
|
|
65
|
-
assert d
|
|
65
|
+
assert not d, f'{d=}'
|
|
66
66
|
|
|
67
67
|
line = ' csr@some_file.sv'
|
|
68
68
|
d = deps_helpers.parse_deps_shell_str(line, '', '')
|
|
69
|
-
assert d
|
|
69
|
+
assert not d, f'{d=}'
|
|
70
70
|
|
|
71
71
|
def test_parse_deps_shell_str__cp():
|
|
72
72
|
line = ' shell@ cp ./oclib_fifo_test.sv oclib_fifo_test_COPY.sv ;'
|
|
73
73
|
d = deps_helpers.parse_deps_shell_str(line, '', '')
|
|
74
|
-
assert d
|
|
74
|
+
assert d, f'{d=}'
|
|
75
75
|
assert d['exec_list'] == ['cp', './oclib_fifo_test.sv', 'oclib_fifo_test_COPY.sv', ';'], f'{d=}'
|
|
76
76
|
|
|
77
77
|
def test_parse_deps_shell_str__echo():
|
|
78
78
|
line = ' shell@echo "hello world"'
|
|
79
79
|
d = deps_helpers.parse_deps_shell_str(line, '', '')
|
|
80
|
-
assert d
|
|
80
|
+
assert d, f'{d=}'
|
|
81
81
|
assert d['exec_list'] == ['echo', '"hello', 'world"'], f'{d=}'
|
|
82
82
|
|
|
83
|
-
def
|
|
83
|
+
def test_parse_deps_shell_str__enable_filepath_replacement():
|
|
84
84
|
# Dealing w/ relative paths, change the current working directory to the module directory
|
|
85
|
+
# Default is enabled.
|
|
85
86
|
module_dir = os.path.dirname(os.path.abspath(__file__))
|
|
86
87
|
os.chdir(module_dir)
|
|
87
88
|
line = 'shell@cp ../deps_helpers.py foo.py'
|
|
88
89
|
d = deps_helpers.parse_deps_shell_str(line, target_path='./', target_node='foo_target')
|
|
89
|
-
assert d
|
|
90
|
+
assert d, f'{d=}'
|
|
90
91
|
assert d['exec_list'] == ['cp', os.path.abspath('../deps_helpers.py'), 'foo.py'], f'{d=}'
|
|
91
92
|
assert d['target_node'] == 'foo_target'
|
|
92
93
|
assert d['target_path'] == os.path.abspath('./')
|
|
93
94
|
|
|
95
|
+
def test_parse_deps_shell_str__disable_filepath_replacement():
|
|
96
|
+
# Dealing w/ relative paths, change the current working directory to the module directory
|
|
97
|
+
module_dir = os.path.dirname(os.path.abspath(__file__))
|
|
98
|
+
os.chdir(module_dir)
|
|
99
|
+
line = 'shell@cp ../deps_helpers.py foo.py'
|
|
100
|
+
d = deps_helpers.parse_deps_shell_str(line, target_path='./', target_node='foo_target',
|
|
101
|
+
enable_filepath_subst_target_dir=False)
|
|
102
|
+
assert d, f'{d=}'
|
|
103
|
+
assert d['exec_list'] == ['cp', '../deps_helpers.py', 'foo.py'], f'{d=}'
|
|
104
|
+
assert d['target_node'] == 'foo_target'
|
|
105
|
+
assert d['target_path'] == os.path.abspath('./')
|
|
106
|
+
|
|
107
|
+
def test_parse_deps_shell_str__enable_dirpath_replacement():
|
|
108
|
+
# Dealing w/ relative paths, change the current working directory to the module directory
|
|
109
|
+
module_dir = os.path.dirname(os.path.abspath(__file__))
|
|
110
|
+
os.chdir(module_dir)
|
|
111
|
+
line = 'shell@ls -ltr ./'
|
|
112
|
+
d = deps_helpers.parse_deps_shell_str(line, target_path='./', target_node='foo_target',
|
|
113
|
+
enable_dirpath_subst_target_dir=True)
|
|
114
|
+
assert d, f'{d=}'
|
|
115
|
+
assert d['exec_list'] == ['ls', '-ltr', os.path.abspath('./')], f'{d=}'
|
|
116
|
+
assert d['target_node'] == 'foo_target'
|
|
117
|
+
assert d['target_path'] == os.path.abspath('./')
|
|
118
|
+
|
|
119
|
+
def test_parse_deps_shell_str__disable_dirpath_replacement():
|
|
120
|
+
# Dealing w/ relative paths, change the current working directory to the module directory
|
|
121
|
+
# Default is disabled.
|
|
122
|
+
module_dir = os.path.dirname(os.path.abspath(__file__))
|
|
123
|
+
os.chdir(module_dir)
|
|
124
|
+
line = 'shell@ls -ltr ./'
|
|
125
|
+
d = deps_helpers.parse_deps_shell_str(line, target_path='./', target_node='foo_target')
|
|
126
|
+
assert d, f'{d=}'
|
|
127
|
+
assert d['exec_list'] == ['ls', '-ltr', './'], f'{d=}'
|
|
128
|
+
assert d['target_node'] == 'foo_target'
|
|
129
|
+
assert d['target_path'] == os.path.abspath('./')
|
|
130
|
+
|
|
94
131
|
|
|
95
132
|
def test_parse_deps_work_dir_add_srcs__no_parse():
|
|
96
133
|
line = 'some_file.sv'
|
|
97
134
|
d = deps_helpers.parse_deps_work_dir_add_srcs(line, '', '')
|
|
98
|
-
assert d
|
|
135
|
+
assert not d, f'{d=}'
|
|
99
136
|
|
|
100
137
|
line = 'some_target:'
|
|
101
138
|
d = deps_helpers.parse_deps_work_dir_add_srcs(line, '', '')
|
|
102
|
-
assert d
|
|
139
|
+
assert not d, f'{d=}'
|
|
103
140
|
|
|
104
141
|
line = ' csr@some_file.sv'
|
|
105
142
|
d = deps_helpers.parse_deps_work_dir_add_srcs(line, '', '')
|
|
106
|
-
assert d
|
|
143
|
+
assert not d, f'{d=}'
|
|
107
144
|
|
|
108
145
|
def test_parse_deps_work_dir_add_srcs__single_file():
|
|
109
146
|
line = ' work_dir_add_srcs@ single_file.txt'
|
|
110
147
|
d = deps_helpers.parse_deps_work_dir_add_srcs(line, '', '')
|
|
111
|
-
assert d
|
|
148
|
+
assert d, f'{d=}'
|
|
112
149
|
assert d['file_list'] == ['single_file.txt']
|
|
113
150
|
|
|
114
151
|
def test_parse_deps_work_dir_add_srcs__several_file():
|
|
115
152
|
line = ' work_dir_add_srcs@ single_file.txt another.sv gen-verilog/mine.v ./gen-vhdl/wordy.vhdl'
|
|
116
153
|
d = deps_helpers.parse_deps_work_dir_add_srcs(line, '', '')
|
|
117
|
-
assert d
|
|
154
|
+
assert d, f'{d=}'
|
|
118
155
|
assert d['file_list'] == [
|
|
119
156
|
'single_file.txt', 'another.sv', 'gen-verilog/mine.v', './gen-vhdl/wordy.vhdl'
|
|
120
157
|
]
|
|
@@ -123,33 +160,33 @@ def test_parse_deps_work_dir_add_srcs__several_file():
|
|
|
123
160
|
def test_parse_deps_peakrdl__no_parse():
|
|
124
161
|
line = 'some_file.sv'
|
|
125
162
|
d = deps_helpers.parse_deps_peakrdl(line, '', '')
|
|
126
|
-
assert d
|
|
163
|
+
assert not d, f'{d=}'
|
|
127
164
|
|
|
128
165
|
line = 'some_target:'
|
|
129
166
|
d = deps_helpers.parse_deps_peakrdl(line, '', '')
|
|
130
|
-
assert d
|
|
167
|
+
assert not d, f'{d=}'
|
|
131
168
|
|
|
132
169
|
line = ' csr@some_file.sv'
|
|
133
170
|
d = deps_helpers.parse_deps_peakrdl(line, '', '')
|
|
134
|
-
assert d
|
|
171
|
+
assert not d, f'{d=}'
|
|
135
172
|
|
|
136
173
|
def test_parse_deps_peakrdl__with_top():
|
|
137
174
|
line = ' peakrdl@ --cpuif axi4-lite-flat --top my_fancy_csrs ./my_csrs.rdl'
|
|
138
175
|
d = deps_helpers.parse_deps_peakrdl(line, '', '')
|
|
139
|
-
assert d
|
|
176
|
+
assert d, f'{d=}'
|
|
140
177
|
assert len(d['shell_commands_list']) > 0
|
|
141
178
|
assert d['work_dir_add_srcs']['file_list'] == ['peakrdl/my_fancy_csrs_pkg.sv', 'peakrdl/my_fancy_csrs.sv']
|
|
142
179
|
|
|
143
180
|
def test_parse_deps_peakrdl__with_top2():
|
|
144
181
|
line = ' peakrdl@ --cpuif axi4-lite-flat --top=my_fancy_csrs ./my_csrs.rdl'
|
|
145
182
|
d = deps_helpers.parse_deps_peakrdl(line, '', '')
|
|
146
|
-
assert d
|
|
183
|
+
assert d, f'{d=}'
|
|
147
184
|
assert len(d['shell_commands_list']) > 0
|
|
148
185
|
assert d['work_dir_add_srcs']['file_list'] == ['peakrdl/my_fancy_csrs_pkg.sv', 'peakrdl/my_fancy_csrs.sv']
|
|
149
186
|
|
|
150
187
|
def test_parse_deps_peakrdl__infer_top():
|
|
151
188
|
line = ' peakrdl@ --cpuif axi4-lite-flat ./my_csrs.rdl'
|
|
152
189
|
d = deps_helpers.parse_deps_peakrdl(line, '', '')
|
|
153
|
-
assert d
|
|
190
|
+
assert d, f'{d=}'
|
|
154
191
|
assert len(d['shell_commands_list']) > 0
|
|
155
192
|
assert d['work_dir_add_srcs']['file_list'] == ['peakrdl/my_csrs_pkg.sv', 'peakrdl/my_csrs.sv']
|
opencos/tools/vivado.py
CHANGED
|
@@ -136,7 +136,7 @@ class CommandSimVivado(CommandSim, ToolVivado):
|
|
|
136
136
|
def __init__(self, config: dict):
|
|
137
137
|
CommandSim.__init__(self, config)
|
|
138
138
|
ToolVivado.__init__(self, config=self.config)
|
|
139
|
-
# add args specific to this
|
|
139
|
+
# add args specific to this tool
|
|
140
140
|
self.args.update({
|
|
141
141
|
'gui': False,
|
|
142
142
|
'tcl-file': 'sim.tcl',
|
|
@@ -349,7 +349,7 @@ class CommandElabVivado(CommandSimVivado):
|
|
|
349
349
|
'''CommandElabVivado is a command handler for: eda elab --tool=vivado, uses xvlog, xelab'''
|
|
350
350
|
def __init__(self, config: dict):
|
|
351
351
|
CommandSimVivado.__init__(self, config)
|
|
352
|
-
# add args specific to this
|
|
352
|
+
# add args specific to this tool
|
|
353
353
|
self.args['stop-after-elaborate'] = True
|
|
354
354
|
|
|
355
355
|
|
|
@@ -358,7 +358,7 @@ class CommandSynthVivado(CommandSynth, ToolVivado):
|
|
|
358
358
|
def __init__(self, config: dict):
|
|
359
359
|
CommandSynth.__init__(self, config)
|
|
360
360
|
ToolVivado.__init__(self, config=self.config)
|
|
361
|
-
# add args specific to this
|
|
361
|
+
# add args specific to this tool
|
|
362
362
|
self.args['gui'] = False
|
|
363
363
|
self.args['tcl-file'] = "synth.tcl"
|
|
364
364
|
self.args['xdc'] = ""
|
|
@@ -401,9 +401,7 @@ class CommandSynthVivado(CommandSynth, ToolVivado):
|
|
|
401
401
|
defines = ""
|
|
402
402
|
for key, value in self.defines.items():
|
|
403
403
|
defines += (f"-verilog_define {key}" + (" " if value is None else f"={value} "))
|
|
404
|
-
incdirs =
|
|
405
|
-
if self.incdirs:
|
|
406
|
-
incdirs = " -include_dirs " + ";".join(self.incdirs)
|
|
404
|
+
incdirs = ' '.join([f'-include_dirs {x}' for x in self.incdirs])
|
|
407
405
|
flatten = ""
|
|
408
406
|
if self.args['flatten-all']:
|
|
409
407
|
flatten = "-flatten_hierarchy full"
|
|
@@ -547,7 +545,7 @@ class CommandProjVivado(CommandProj, ToolVivado):
|
|
|
547
545
|
def __init__(self, config: dict):
|
|
548
546
|
CommandProj.__init__(self, config)
|
|
549
547
|
ToolVivado.__init__(self, config=self.config)
|
|
550
|
-
# add args specific to this
|
|
548
|
+
# add args specific to this tool
|
|
551
549
|
self.args['gui'] = True
|
|
552
550
|
self.args['oc-vivado-tcl'] = True
|
|
553
551
|
self.args['tcl-file'] = "proj.tcl"
|
|
@@ -630,10 +628,11 @@ class CommandBuildVivado(CommandBuild, ToolVivado):
|
|
|
630
628
|
def __init__(self, config: dict):
|
|
631
629
|
CommandBuild.__init__(self, config)
|
|
632
630
|
ToolVivado.__init__(self, config=self.config)
|
|
633
|
-
# add args specific to this
|
|
631
|
+
# add args specific to this tool
|
|
634
632
|
self.args['gui'] = False
|
|
635
633
|
self.args['fpga'] = ""
|
|
636
634
|
self.args['proj'] = False
|
|
635
|
+
self.args['resynth'] = False
|
|
637
636
|
self.args['reset'] = False
|
|
638
637
|
self.args['all-sv'] = False
|
|
639
638
|
|
|
@@ -705,6 +704,8 @@ class CommandBuildVivado(CommandBuild, ToolVivado):
|
|
|
705
704
|
]
|
|
706
705
|
if self.args['proj']:
|
|
707
706
|
command_list += ['--proj']
|
|
707
|
+
if self.args['resynth']:
|
|
708
|
+
command_list += ['--resynth']
|
|
708
709
|
if self.args['reset']:
|
|
709
710
|
command_list += ['--reset']
|
|
710
711
|
|
|
@@ -732,7 +733,7 @@ class CommandUploadVivado(CommandUpload, ToolVivado):
|
|
|
732
733
|
def __init__(self, config: dict):
|
|
733
734
|
CommandUpload.__init__(self, config)
|
|
734
735
|
ToolVivado.__init__(self, config=self.config)
|
|
735
|
-
# add args specific to this
|
|
736
|
+
# add args specific to this tool
|
|
736
737
|
self.args.update({
|
|
737
738
|
'gui': False,
|
|
738
739
|
'bitfile': "",
|
|
@@ -743,8 +744,10 @@ class CommandUploadVivado(CommandUpload, ToolVivado):
|
|
|
743
744
|
'device': -1,
|
|
744
745
|
'host': "localhost",
|
|
745
746
|
'port': 3121,
|
|
746
|
-
'tcl-file': "upload.tcl",
|
|
747
747
|
'all-sv': False,
|
|
748
|
+
'tcl-file': "eda_upload.tcl",
|
|
749
|
+
'log-file': "eda_upload.log",
|
|
750
|
+
'test-mode': False,
|
|
748
751
|
})
|
|
749
752
|
# TODO(drew): Add self.args_help.update({...})
|
|
750
753
|
|
|
@@ -825,7 +828,7 @@ class CommandUploadVivado(CommandUpload, ToolVivado):
|
|
|
825
828
|
|
|
826
829
|
# ── Generate TCL script ───────────────────────────────────────────────────
|
|
827
830
|
script_file = Path(self.args['tcl-file'])
|
|
828
|
-
log_file = Path(
|
|
831
|
+
log_file = Path(self.args['log-file'])
|
|
829
832
|
|
|
830
833
|
try:
|
|
831
834
|
with script_file.open("w", encoding="utf-8") as fout:
|
|
@@ -924,6 +927,9 @@ class CommandUploadVivado(CommandUpload, ToolVivado):
|
|
|
924
927
|
command_list.append('-notrace')
|
|
925
928
|
self.exec(Path(util.getcwd()), command_list)
|
|
926
929
|
|
|
930
|
+
if not self.args['keep']:
|
|
931
|
+
os.unlink(self.args['tcl-file'])
|
|
932
|
+
|
|
927
933
|
util.info("Upload done")
|
|
928
934
|
|
|
929
935
|
|
|
@@ -935,7 +941,7 @@ class CommandOpenVivado(CommandOpen, ToolVivado):
|
|
|
935
941
|
def __init__(self, config: dict):
|
|
936
942
|
CommandOpen.__init__(self, config)
|
|
937
943
|
ToolVivado.__init__(self, config=self.config)
|
|
938
|
-
# add args specific to this
|
|
944
|
+
# add args specific to this tool
|
|
939
945
|
self.args['gui'] = True
|
|
940
946
|
self.args['file'] = False
|
|
941
947
|
self.args['all-sv'] = False
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opencos-eda
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.47
|
|
4
4
|
Summary: A simple Python package for wrapping RTL simuliatons and synthesis
|
|
5
5
|
Author-email: Simon Sabato <simon@cognichip.ai>, Drew Ranck <drew@cognichip.ai>
|
|
6
6
|
Project-URL: Homepage, https://github.com/cognichip/opencos
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
opencos/__init__.py,sha256=ZQ7aOCbP0jkIMYGdVrb-mkZX3rnvaK8epBkmp506tXU,85
|
|
2
2
|
opencos/_version.py,sha256=qN7iBoOv-v4tEZz-Pu9sVUJwefshJOsgdaddn8HcHio,510
|
|
3
3
|
opencos/_waves_pkg.sv,sha256=1lbhQOVGc3t_R8czYjP40hssP0I3FlZOpHTkI7yKFbI,1251
|
|
4
|
-
opencos/deps_helpers.py,sha256=
|
|
5
|
-
opencos/deps_schema.py,sha256=
|
|
4
|
+
opencos/deps_helpers.py,sha256=iFUMnrh8hiNflRgZWp0hid7x6BKk1P2PegUn_gJS8Z0,59452
|
|
5
|
+
opencos/deps_schema.py,sha256=ECysiiagTGXAtAVp2GnW3N_Iw2ZakYEuSEg-WUWtUKo,15469
|
|
6
6
|
opencos/eda.py,sha256=Ky_Uc47TU1N6lRs06eatdpAvtgoSh0iXO0BxhSfEuk0,19420
|
|
7
|
-
opencos/eda_base.py,sha256=
|
|
7
|
+
opencos/eda_base.py,sha256=utUTieQMv0RC2Mz5n8b7rtneKjSFI3YcgCiJON0T7Ws,84410
|
|
8
8
|
opencos/eda_config.py,sha256=8wwX4PTZ5rmxWogrVxxqAY6adQFPxTsFkkTYbo6H4vU,8853
|
|
9
|
-
opencos/eda_config_defaults.yml,sha256=
|
|
9
|
+
opencos/eda_config_defaults.yml,sha256=AteZbwRJ6wviinks47-e5TX0DoU0culJfBw6L3xYOOA,11535
|
|
10
10
|
opencos/eda_config_max_verilator_waivers.yml,sha256=lTAU4IOEbUWVlPzuer1YYhIyxpPINeA4EJqcRIT-Ymk,840
|
|
11
11
|
opencos/eda_config_reduced.yml,sha256=cQ9jY4J7EvAbeHTiP6bvpDSVJAYiitjLZPSxxLKIEbk,1440
|
|
12
12
|
opencos/eda_deps_bash_completion.bash,sha256=jMkQKY82HBgOnQeMdA1hMrXguRFtB52SMBxUemKovL4,1958
|
|
@@ -41,7 +41,7 @@ opencos/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
41
41
|
opencos/tests/custom_config.yml,sha256=TRoVM9ZFKPOA_8JmlpzaMhnGO1txmaD14N_8P1oqzew,257
|
|
42
42
|
opencos/tests/helpers.py,sha256=r4UYMckYzHY2i2RbSWvysOjerPhty_7i7RB-Z767M-c,8294
|
|
43
43
|
opencos/tests/test_build.py,sha256=FQAxOpLVQShAHD_L5rqJctPeSAoqoOCNFI0RXflLuY0,387
|
|
44
|
-
opencos/tests/test_deps_helpers.py,sha256=
|
|
44
|
+
opencos/tests/test_deps_helpers.py,sha256=_C5qH1YuScCCvG3E-Lr8aS_n6C6YKgEl-wIycJEFLRY,7697
|
|
45
45
|
opencos/tests/test_deps_schema.py,sha256=T3P9KjaMyKsk8b7snNVvNSsom2hIJcg6Z9apYiXoH9Y,941
|
|
46
46
|
opencos/tests/test_eda.py,sha256=tplHcx4FiEn8Jmw1mJMlD6tGjpUJ6cxdBGiVRKo7Ykw,38809
|
|
47
47
|
opencos/tests/test_eda_elab.py,sha256=75bJpOaoO8rn1FXFxiE4KSu5FdjZP1IbW6SyTCjM_ao,2553
|
|
@@ -68,12 +68,12 @@ opencos/tools/slang_yosys.py,sha256=3fyLRRdTXhSppNtUhhUl00oG-cT9TyyPTH6JvasS9ZE,
|
|
|
68
68
|
opencos/tools/surelog.py,sha256=XhxJCGt8hyligL0LNT1fCWkHF5pkt4WSp3eqVJlQ4uA,4998
|
|
69
69
|
opencos/tools/tabbycad_yosys.py,sha256=2LePPgYXBVdsy7YcffPIWN-I0B7queLQ_f_pme2SCGw,7803
|
|
70
70
|
opencos/tools/verilator.py,sha256=dWnoO8FUvjdMyFmuTjHvC_XYI_zwjApJApYy7iYubf0,18398
|
|
71
|
-
opencos/tools/vivado.py,sha256=
|
|
71
|
+
opencos/tools/vivado.py,sha256=D0we45_2M5dr7Dp6FBjSaXxYmRpgJWm4rq3dc23Uv1A,40219
|
|
72
72
|
opencos/tools/yosys.py,sha256=FV43RcejyFir4B24WRShnzUoppJMK0sDDNkSlIX8Vew,25579
|
|
73
|
-
opencos_eda-0.2.
|
|
74
|
-
opencos_eda-0.2.
|
|
75
|
-
opencos_eda-0.2.
|
|
76
|
-
opencos_eda-0.2.
|
|
77
|
-
opencos_eda-0.2.
|
|
78
|
-
opencos_eda-0.2.
|
|
79
|
-
opencos_eda-0.2.
|
|
73
|
+
opencos_eda-0.2.47.dist-info/licenses/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
|
|
74
|
+
opencos_eda-0.2.47.dist-info/licenses/LICENSE.spdx,sha256=8gn1610RMP6eFgT3Hm6q9VKXt0RvdTItL_oxMo72jII,189
|
|
75
|
+
opencos_eda-0.2.47.dist-info/METADATA,sha256=VNi89oYQGS94RsyWbns7hETc1o9STz57mwYYGvXXEi4,604
|
|
76
|
+
opencos_eda-0.2.47.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
77
|
+
opencos_eda-0.2.47.dist-info/entry_points.txt,sha256=V8OE1lySAFcFQpDNJuVxVZteeSmDH-joLMhGvrxrvmg,164
|
|
78
|
+
opencos_eda-0.2.47.dist-info/top_level.txt,sha256=J4JDP-LpRyJqPNeh9bSjx6yrLz2Mk0h6un6YLmtqql4,8
|
|
79
|
+
opencos_eda-0.2.47.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|