opencos-eda 0.2.48__py3-none-any.whl → 0.2.50__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/__init__.py +4 -2
- opencos/_version.py +10 -7
- opencos/commands/flist.py +8 -7
- opencos/commands/multi.py +14 -15
- opencos/commands/sim.py +5 -0
- opencos/commands/sweep.py +3 -2
- opencos/deps/__init__.py +0 -0
- opencos/deps/defaults.py +69 -0
- opencos/deps/deps_commands.py +419 -0
- opencos/deps/deps_file.py +326 -0
- opencos/deps/deps_processor.py +670 -0
- opencos/deps_schema.py +7 -8
- opencos/eda.py +84 -64
- opencos/eda_base.py +585 -316
- opencos/eda_config.py +85 -14
- opencos/eda_config_defaults.yml +36 -4
- opencos/eda_extract_targets.py +22 -14
- opencos/eda_tool_helper.py +33 -7
- opencos/export_helper.py +166 -86
- opencos/export_json_convert.py +31 -23
- opencos/files.py +2 -1
- opencos/hw/__init__.py +0 -0
- opencos/{oc_cli.py → hw/oc_cli.py} +9 -4
- opencos/names.py +0 -4
- opencos/peakrdl_cleanup.py +13 -7
- opencos/seed.py +19 -11
- opencos/tests/helpers.py +3 -2
- opencos/tests/test_deps_helpers.py +35 -32
- opencos/tests/test_eda.py +36 -29
- opencos/tests/test_eda_elab.py +7 -4
- opencos/tests/test_eda_synth.py +1 -1
- opencos/tests/test_oc_cli.py +1 -1
- opencos/tests/test_tools.py +4 -2
- opencos/tools/iverilog.py +2 -2
- opencos/tools/modelsim_ase.py +24 -2
- opencos/tools/questa.py +5 -3
- opencos/tools/questa_fse.py +57 -0
- opencos/tools/riviera.py +1 -1
- opencos/tools/slang.py +9 -3
- opencos/tools/surelog.py +1 -1
- opencos/tools/verilator.py +26 -1
- opencos/tools/vivado.py +34 -27
- opencos/tools/yosys.py +4 -3
- opencos/util.py +532 -474
- opencos/utils/__init__.py +0 -0
- opencos/utils/markup_helpers.py +98 -0
- opencos/utils/str_helpers.py +111 -0
- opencos/utils/subprocess_helpers.py +108 -0
- {opencos_eda-0.2.48.dist-info → opencos_eda-0.2.50.dist-info}/METADATA +1 -1
- opencos_eda-0.2.50.dist-info/RECORD +89 -0
- {opencos_eda-0.2.48.dist-info → opencos_eda-0.2.50.dist-info}/entry_points.txt +1 -1
- opencos/deps_helpers.py +0 -1346
- opencos_eda-0.2.48.dist-info/RECORD +0 -79
- /opencos/{pcie.py → hw/pcie.py} +0 -0
- {opencos_eda-0.2.48.dist-info → opencos_eda-0.2.50.dist-info}/WHEEL +0 -0
- {opencos_eda-0.2.48.dist-info → opencos_eda-0.2.50.dist-info}/licenses/LICENSE +0 -0
- {opencos_eda-0.2.48.dist-info → opencos_eda-0.2.50.dist-info}/licenses/LICENSE.spdx +0 -0
- {opencos_eda-0.2.48.dist-info → opencos_eda-0.2.50.dist-info}/top_level.txt +0 -0
opencos/peakrdl_cleanup.py
CHANGED
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
|
|
3
|
+
''' peakrdl_cleanup is intended as CLI or callable via run(file-in, file-out)
|
|
4
|
+
|
|
5
|
+
to apply verilator comment waivers to a SystemVerilog file
|
|
6
|
+
'''
|
|
7
|
+
|
|
3
8
|
import sys
|
|
4
|
-
import os
|
|
5
9
|
|
|
6
|
-
|
|
7
|
-
|
|
10
|
+
|
|
11
|
+
def run(file_in: str, file_out: str) -> None:
|
|
12
|
+
'''Returns None, writes file_out (filepath) with updates given file_in (filepath)'''
|
|
13
|
+
|
|
14
|
+
with open(file_in, encoding='utf-8') as f:
|
|
8
15
|
lines = f.readlines()
|
|
9
16
|
|
|
10
|
-
with open(file_out, 'w') as f:
|
|
17
|
+
with open(file_out, 'w', encoding='utf-8') as f:
|
|
11
18
|
f.write('// verilator lint_off MULTIDRIVEN\n')
|
|
12
19
|
for line in lines:
|
|
13
20
|
f.write(line)
|
|
14
21
|
f.write('// verilator lint_on MULTIDRIVEN\n')
|
|
15
22
|
|
|
23
|
+
|
|
16
24
|
if __name__ == '__main__':
|
|
17
25
|
assert len(sys.argv) == 3, f'{sys.argv=}'
|
|
18
|
-
file_in
|
|
19
|
-
file_out = sys.argv[2]
|
|
20
|
-
run(file_in, file_out)
|
|
26
|
+
run(file_in=sys.argv[1], file_out=sys.argv[2])
|
opencos/seed.py
CHANGED
|
@@ -1,28 +1,36 @@
|
|
|
1
|
+
''' opencos.seed handles getting a 'seed' int, and keeping a list of seeds.
|
|
2
|
+
|
|
3
|
+
Used by opencos.command.sim and opencos.tools, because some tools prefer 32-bit uint,
|
|
4
|
+
31-bit > 0, or want to avoid a seed=0
|
|
5
|
+
'''
|
|
6
|
+
|
|
1
7
|
import random
|
|
8
|
+
import time
|
|
2
9
|
|
|
3
|
-
seeds =
|
|
10
|
+
seeds = []
|
|
4
11
|
|
|
12
|
+
def get_seed(style: str = "", limit_31bit: bool = True, avoid_zero: bool = True) -> int:
|
|
13
|
+
'''Returns a random int, using python random or time.time, with constraints.
|
|
5
14
|
|
|
6
|
-
|
|
7
|
-
'''Returns a random int
|
|
15
|
+
Appends returned value to global list seeds.
|
|
8
16
|
|
|
9
17
|
style (str)
|
|
10
|
-
-- "", default: uses python random.randint
|
|
11
|
-
-- "time" : uses python
|
|
18
|
+
-- "", default: uses python random.randint 32-bit
|
|
19
|
+
-- "time" : uses python time.time_ns() 32-bit LSBs
|
|
12
20
|
'''
|
|
13
21
|
|
|
14
|
-
global seeds
|
|
15
22
|
seed = 1
|
|
16
23
|
|
|
17
24
|
if style.lower() == "time":
|
|
18
|
-
|
|
25
|
+
# use the float value fractional portion
|
|
26
|
+
seed = time.time_ns() & 0xFFFF_FFFF
|
|
19
27
|
else:
|
|
20
|
-
seed = random.randint(0,
|
|
28
|
+
seed = random.randint(0, 0xFFFF_FFFF)
|
|
21
29
|
|
|
22
|
-
if limit_31bit
|
|
23
|
-
seed
|
|
30
|
+
if limit_31bit:
|
|
31
|
+
seed &= 0x7FFF_FFFF
|
|
24
32
|
if avoid_zero and seed == 0:
|
|
25
|
-
seed
|
|
33
|
+
seed = 1
|
|
26
34
|
|
|
27
35
|
seeds.append(seed)
|
|
28
36
|
return seed
|
opencos/tests/helpers.py
CHANGED
|
@@ -9,8 +9,9 @@ from pathlib import Path
|
|
|
9
9
|
|
|
10
10
|
from contextlib import redirect_stdout, redirect_stderr
|
|
11
11
|
|
|
12
|
-
from opencos import eda
|
|
12
|
+
from opencos import eda
|
|
13
13
|
from opencos import deps_schema
|
|
14
|
+
from opencos.utils.markup_helpers import yaml_safe_load
|
|
14
15
|
|
|
15
16
|
def can_run_eda_command(*commands, config: dict) -> bool:
|
|
16
17
|
'''Returns True if we have any installed tool that can run: eda <command>'''
|
|
@@ -74,7 +75,7 @@ def assert_gen_deps_yml_good(filepath:str, want_target:str='') -> dict:
|
|
|
74
75
|
|
|
75
76
|
so we also confirm they pass the deps_schema.FILE_SIMPLIFIED'''
|
|
76
77
|
assert os.path.exists(filepath), f'{filepath=} does not exist'
|
|
77
|
-
data =
|
|
78
|
+
data = yaml_safe_load(filepath)
|
|
78
79
|
assert len(data.keys()) > 0
|
|
79
80
|
if want_target:
|
|
80
81
|
assert want_target, f'{want_target=} not in {filepath=} {data=}'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
'''pytests for opencos.
|
|
1
|
+
'''pytests for opencos.deps modules'''
|
|
2
2
|
|
|
3
|
-
# TODO(drew): these need to be refactored if we cleanup
|
|
4
|
-
# uses the old DEPS (non-markup) command format, such as 'shell@some bash command'
|
|
3
|
+
# TODO(drew): these need to be refactored if we cleanup opencos.deps commands;
|
|
4
|
+
# this uses the old DEPS (non-markup) command format, such as 'shell@some bash command'
|
|
5
5
|
|
|
6
6
|
# TODO(drew): for now, ignore long lines and docstrings
|
|
7
7
|
# pylint: disable=line-too-long,missing-function-docstring
|
|
@@ -10,7 +10,9 @@ from pathlib import Path
|
|
|
10
10
|
import os
|
|
11
11
|
import pytest
|
|
12
12
|
|
|
13
|
-
from opencos import eda_tool_helper
|
|
13
|
+
from opencos import eda_tool_helper
|
|
14
|
+
|
|
15
|
+
from opencos.deps import deps_file, deps_commands
|
|
14
16
|
|
|
15
17
|
THISPATH = os.path.dirname(__file__)
|
|
16
18
|
|
|
@@ -19,9 +21,9 @@ config, tools_loaded = eda_tool_helper.get_config_and_tools_loaded()
|
|
|
19
21
|
|
|
20
22
|
|
|
21
23
|
def test_get_all_targets():
|
|
22
|
-
'''Makes sure that
|
|
24
|
+
'''Makes sure that deps_file.get_all_targets(filter_str:str) works'''
|
|
23
25
|
|
|
24
|
-
targets =
|
|
26
|
+
targets = deps_file.get_all_targets(
|
|
25
27
|
dirs=[
|
|
26
28
|
str(Path('../../lib/tests')),
|
|
27
29
|
str(Path('../../lib/rams/tests')),
|
|
@@ -42,9 +44,9 @@ def test_get_all_targets():
|
|
|
42
44
|
reason="requires vivado or verilator"
|
|
43
45
|
)
|
|
44
46
|
def test_get_all_targets_eda_multi():
|
|
45
|
-
'''Makes sure that
|
|
47
|
+
'''Makes sure that deps_file.get_all_targets(filter_using_mult:str) works'''
|
|
46
48
|
|
|
47
|
-
targets =
|
|
49
|
+
targets = deps_file.get_all_targets(
|
|
48
50
|
base_path=THISPATH,
|
|
49
51
|
filter_using_multi='sim ../../lib/tests/*test ../../lib/rams/tests/*test',
|
|
50
52
|
)
|
|
@@ -57,26 +59,26 @@ def test_get_all_targets_eda_multi():
|
|
|
57
59
|
|
|
58
60
|
def test_parse_deps_shell_str__no_parse():
|
|
59
61
|
line = 'some_file.sv'
|
|
60
|
-
d =
|
|
62
|
+
d = deps_commands.parse_deps_shell_str(line, '', '')
|
|
61
63
|
assert not d, f'{d=}'
|
|
62
64
|
|
|
63
65
|
line = 'some_target:'
|
|
64
|
-
d =
|
|
66
|
+
d = deps_commands.parse_deps_shell_str(line, '', '')
|
|
65
67
|
assert not d, f'{d=}'
|
|
66
68
|
|
|
67
69
|
line = ' csr@some_file.sv'
|
|
68
|
-
d =
|
|
70
|
+
d = deps_commands.parse_deps_shell_str(line, '', '')
|
|
69
71
|
assert not d, f'{d=}'
|
|
70
72
|
|
|
71
73
|
def test_parse_deps_shell_str__cp():
|
|
72
74
|
line = ' shell@ cp ./oclib_fifo_test.sv oclib_fifo_test_COPY.sv ;'
|
|
73
|
-
d =
|
|
75
|
+
d = deps_commands.parse_deps_shell_str(line, '', '')
|
|
74
76
|
assert d, f'{d=}'
|
|
75
77
|
assert d['exec_list'] == ['cp', './oclib_fifo_test.sv', 'oclib_fifo_test_COPY.sv', ';'], f'{d=}'
|
|
76
78
|
|
|
77
79
|
def test_parse_deps_shell_str__echo():
|
|
78
80
|
line = ' shell@echo "hello world"'
|
|
79
|
-
d =
|
|
81
|
+
d = deps_commands.parse_deps_shell_str(line, '', '')
|
|
80
82
|
assert d, f'{d=}'
|
|
81
83
|
assert d['exec_list'] == ['echo', '"hello', 'world"'], f'{d=}'
|
|
82
84
|
|
|
@@ -85,10 +87,11 @@ def test_parse_deps_shell_str__enable_filepath_replacement():
|
|
|
85
87
|
# Default is enabled.
|
|
86
88
|
module_dir = os.path.dirname(os.path.abspath(__file__))
|
|
87
89
|
os.chdir(module_dir)
|
|
88
|
-
line = 'shell@cp ../
|
|
89
|
-
d =
|
|
90
|
+
line = 'shell@cp ../deps/deps_commands.py .pytest.copied.py'
|
|
91
|
+
d = deps_commands.parse_deps_shell_str(line, target_path='./', target_node='foo_target')
|
|
90
92
|
assert d, f'{d=}'
|
|
91
|
-
|
|
93
|
+
spath = os.path.abspath(os.path.join('..', 'deps', 'deps_commands.py'))
|
|
94
|
+
assert d['exec_list'] == ['cp', spath, '.pytest.copied.py'], f'{d=}'
|
|
92
95
|
assert d['target_node'] == 'foo_target'
|
|
93
96
|
assert d['target_path'] == os.path.abspath('./')
|
|
94
97
|
|
|
@@ -96,11 +99,11 @@ def test_parse_deps_shell_str__disable_filepath_replacement():
|
|
|
96
99
|
# Dealing w/ relative paths, change the current working directory to the module directory
|
|
97
100
|
module_dir = os.path.dirname(os.path.abspath(__file__))
|
|
98
101
|
os.chdir(module_dir)
|
|
99
|
-
line = 'shell@cp ../
|
|
100
|
-
d =
|
|
102
|
+
line = 'shell@cp ../deps/deps_commands.py .pytest.copied.py'
|
|
103
|
+
d = deps_commands.parse_deps_shell_str(line, target_path='./', target_node='foo_target',
|
|
101
104
|
enable_filepath_subst_target_dir=False)
|
|
102
105
|
assert d, f'{d=}'
|
|
103
|
-
assert d['exec_list'] == ['cp', '../
|
|
106
|
+
assert d['exec_list'] == ['cp', '../deps/deps_commands.py', '.pytest.copied.py'], f'{d=}'
|
|
104
107
|
assert d['target_node'] == 'foo_target'
|
|
105
108
|
assert d['target_path'] == os.path.abspath('./')
|
|
106
109
|
|
|
@@ -109,7 +112,7 @@ def test_parse_deps_shell_str__enable_dirpath_replacement():
|
|
|
109
112
|
module_dir = os.path.dirname(os.path.abspath(__file__))
|
|
110
113
|
os.chdir(module_dir)
|
|
111
114
|
line = 'shell@ls -ltr ./'
|
|
112
|
-
d =
|
|
115
|
+
d = deps_commands.parse_deps_shell_str(line, target_path='./', target_node='foo_target',
|
|
113
116
|
enable_dirpath_subst_target_dir=True)
|
|
114
117
|
assert d, f'{d=}'
|
|
115
118
|
assert d['exec_list'] == ['ls', '-ltr', os.path.abspath('./')], f'{d=}'
|
|
@@ -122,7 +125,7 @@ def test_parse_deps_shell_str__disable_dirpath_replacement():
|
|
|
122
125
|
module_dir = os.path.dirname(os.path.abspath(__file__))
|
|
123
126
|
os.chdir(module_dir)
|
|
124
127
|
line = 'shell@ls -ltr ./'
|
|
125
|
-
d =
|
|
128
|
+
d = deps_commands.parse_deps_shell_str(line, target_path='./', target_node='foo_target')
|
|
126
129
|
assert d, f'{d=}'
|
|
127
130
|
assert d['exec_list'] == ['ls', '-ltr', './'], f'{d=}'
|
|
128
131
|
assert d['target_node'] == 'foo_target'
|
|
@@ -131,26 +134,26 @@ def test_parse_deps_shell_str__disable_dirpath_replacement():
|
|
|
131
134
|
|
|
132
135
|
def test_parse_deps_work_dir_add_srcs__no_parse():
|
|
133
136
|
line = 'some_file.sv'
|
|
134
|
-
d =
|
|
137
|
+
d = deps_commands.parse_deps_work_dir_add_srcs(line, '', '')
|
|
135
138
|
assert not d, f'{d=}'
|
|
136
139
|
|
|
137
140
|
line = 'some_target:'
|
|
138
|
-
d =
|
|
141
|
+
d = deps_commands.parse_deps_work_dir_add_srcs(line, '', '')
|
|
139
142
|
assert not d, f'{d=}'
|
|
140
143
|
|
|
141
144
|
line = ' csr@some_file.sv'
|
|
142
|
-
d =
|
|
145
|
+
d = deps_commands.parse_deps_work_dir_add_srcs(line, '', '')
|
|
143
146
|
assert not d, f'{d=}'
|
|
144
147
|
|
|
145
148
|
def test_parse_deps_work_dir_add_srcs__single_file():
|
|
146
149
|
line = ' work_dir_add_srcs@ single_file.txt'
|
|
147
|
-
d =
|
|
150
|
+
d = deps_commands.parse_deps_work_dir_add_srcs(line, '', '')
|
|
148
151
|
assert d, f'{d=}'
|
|
149
152
|
assert d['file_list'] == ['single_file.txt']
|
|
150
153
|
|
|
151
154
|
def test_parse_deps_work_dir_add_srcs__several_file():
|
|
152
155
|
line = ' work_dir_add_srcs@ single_file.txt another.sv gen-verilog/mine.v ./gen-vhdl/wordy.vhdl'
|
|
153
|
-
d =
|
|
156
|
+
d = deps_commands.parse_deps_work_dir_add_srcs(line, '', '')
|
|
154
157
|
assert d, f'{d=}'
|
|
155
158
|
assert d['file_list'] == [
|
|
156
159
|
'single_file.txt', 'another.sv', 'gen-verilog/mine.v', './gen-vhdl/wordy.vhdl'
|
|
@@ -159,34 +162,34 @@ def test_parse_deps_work_dir_add_srcs__several_file():
|
|
|
159
162
|
|
|
160
163
|
def test_parse_deps_peakrdl__no_parse():
|
|
161
164
|
line = 'some_file.sv'
|
|
162
|
-
d =
|
|
165
|
+
d = deps_commands.parse_deps_peakrdl(line, '', '')
|
|
163
166
|
assert not d, f'{d=}'
|
|
164
167
|
|
|
165
168
|
line = 'some_target:'
|
|
166
|
-
d =
|
|
169
|
+
d = deps_commands.parse_deps_peakrdl(line, '', '')
|
|
167
170
|
assert not d, f'{d=}'
|
|
168
171
|
|
|
169
172
|
line = ' csr@some_file.sv'
|
|
170
|
-
d =
|
|
173
|
+
d = deps_commands.parse_deps_peakrdl(line, '', '')
|
|
171
174
|
assert not d, f'{d=}'
|
|
172
175
|
|
|
173
176
|
def test_parse_deps_peakrdl__with_top():
|
|
174
177
|
line = ' peakrdl@ --cpuif axi4-lite-flat --top my_fancy_csrs ./my_csrs.rdl'
|
|
175
|
-
d =
|
|
178
|
+
d = deps_commands.parse_deps_peakrdl(line, '', '')
|
|
176
179
|
assert d, f'{d=}'
|
|
177
180
|
assert len(d['shell_commands_list']) > 0
|
|
178
181
|
assert d['work_dir_add_srcs']['file_list'] == ['peakrdl/my_fancy_csrs_pkg.sv', 'peakrdl/my_fancy_csrs.sv']
|
|
179
182
|
|
|
180
183
|
def test_parse_deps_peakrdl__with_top2():
|
|
181
184
|
line = ' peakrdl@ --cpuif axi4-lite-flat --top=my_fancy_csrs ./my_csrs.rdl'
|
|
182
|
-
d =
|
|
185
|
+
d = deps_commands.parse_deps_peakrdl(line, '', '')
|
|
183
186
|
assert d, f'{d=}'
|
|
184
187
|
assert len(d['shell_commands_list']) > 0
|
|
185
188
|
assert d['work_dir_add_srcs']['file_list'] == ['peakrdl/my_fancy_csrs_pkg.sv', 'peakrdl/my_fancy_csrs.sv']
|
|
186
189
|
|
|
187
190
|
def test_parse_deps_peakrdl__infer_top():
|
|
188
191
|
line = ' peakrdl@ --cpuif axi4-lite-flat ./my_csrs.rdl'
|
|
189
|
-
d =
|
|
192
|
+
d = deps_commands.parse_deps_peakrdl(line, '', '')
|
|
190
193
|
assert d, f'{d=}'
|
|
191
194
|
assert len(d['shell_commands_list']) > 0
|
|
192
195
|
assert d['work_dir_add_srcs']['file_list'] == ['peakrdl/my_csrs_pkg.sv', 'peakrdl/my_csrs.sv']
|
opencos/tests/test_eda.py
CHANGED
|
@@ -7,6 +7,12 @@ If you want to run this, consider running from the root of opencos repo:
|
|
|
7
7
|
> python3 -m pytest --verbose opencos/*/*.py
|
|
8
8
|
> python3 -m pytest -rx opencos/*/*.py
|
|
9
9
|
which avoids using any pip installed opencos.eda
|
|
10
|
+
|
|
11
|
+
Throughout this file, if you see:
|
|
12
|
+
assert rc > 1
|
|
13
|
+
It is not a typo. We would prefer all expected errors to be caught and reported by
|
|
14
|
+
eda.py. Python errors tend to return with rc=1, and those are problematic for us
|
|
15
|
+
and should be more gracefully handled.
|
|
10
16
|
'''
|
|
11
17
|
|
|
12
18
|
# pylint: disable=R0801 # (similar lines in 2+ files)
|
|
@@ -18,7 +24,8 @@ from contextlib import redirect_stdout, redirect_stderr
|
|
|
18
24
|
|
|
19
25
|
import pytest
|
|
20
26
|
|
|
21
|
-
from opencos import eda,
|
|
27
|
+
from opencos import eda, eda_tool_helper
|
|
28
|
+
from opencos.utils.markup_helpers import yaml_safe_load
|
|
22
29
|
from opencos.tests import helpers
|
|
23
30
|
from opencos.tests.helpers import eda_wrap, eda_sim_wrap, eda_elab_wrap, \
|
|
24
31
|
Helpers
|
|
@@ -89,7 +96,7 @@ class TestsRequiresVerilator( # pylint: disable=too-many-public-methods
|
|
|
89
96
|
chdir_remove_work_dir('../../lib')
|
|
90
97
|
rc = eda_wrap('synth', '--tool', 'verilator', 'oclib_fifo')
|
|
91
98
|
print(f'{rc=}')
|
|
92
|
-
assert rc
|
|
99
|
+
assert rc > 1
|
|
93
100
|
|
|
94
101
|
|
|
95
102
|
def test_args_sim(self):
|
|
@@ -228,7 +235,7 @@ class TestsRequiresVerilator( # pylint: disable=too-many-public-methods
|
|
|
228
235
|
# want to use the xfail pytest decorator.
|
|
229
236
|
rc = eda_sim_wrap('--xilinx', '--tool', 'verilator', 'oclib_fifo_test')
|
|
230
237
|
print(f'{rc=}')
|
|
231
|
-
assert rc
|
|
238
|
+
assert rc > 1
|
|
232
239
|
|
|
233
240
|
def test_more_plusargs_sim(self):
|
|
234
241
|
'''Test that unprocessed plusargs become sim-plusargs on CLI'''
|
|
@@ -266,7 +273,7 @@ class TestsRequiresVerilator( # pylint: disable=too-many-public-methods
|
|
|
266
273
|
rc = eda.main('multi', 'sim', '--fail-if-no-targets', '--seed=1', '--xilinx', '--tool',
|
|
267
274
|
'verilator', 'oclib_fifo_test')
|
|
268
275
|
print(f'{rc=}')
|
|
269
|
-
assert rc
|
|
276
|
+
assert rc > 1
|
|
270
277
|
|
|
271
278
|
def test_args_multi_sim_no_targets_should_fail(self):
|
|
272
279
|
'''Checks that: eda multi --fail-if-no-targets; will fail if no targets expanded'''
|
|
@@ -275,7 +282,7 @@ class TestsRequiresVerilator( # pylint: disable=too-many-public-methods
|
|
|
275
282
|
rc = eda.main('multi', 'sim', '--fail-if-no-targets', '--seed=1', '--tool', 'verilator',
|
|
276
283
|
'no_targets*')
|
|
277
284
|
print(f'{rc=}')
|
|
278
|
-
assert rc
|
|
285
|
+
assert rc > 1
|
|
279
286
|
|
|
280
287
|
def test_elab_verilator_no_deps_files_involved(self):
|
|
281
288
|
'''Test that inferring the --top from last file in provides files works.'''
|
|
@@ -295,7 +302,7 @@ class TestsRequiresVerilator( # pylint: disable=too-many-public-methods
|
|
|
295
302
|
eda_config_yml_path = os.path.join(
|
|
296
303
|
os.getcwd(), 'eda.work', 'oclib_fifo.elab', 'eda_output_config.yml'
|
|
297
304
|
)
|
|
298
|
-
data =
|
|
305
|
+
data = yaml_safe_load(eda_config_yml_path)
|
|
299
306
|
assert 'args' in data
|
|
300
307
|
assert data['args'].get('top', '') == 'oclib_fifo'
|
|
301
308
|
assert 'config' in data
|
|
@@ -315,7 +322,7 @@ class TestsRequiresVerilator( # pylint: disable=too-many-public-methods
|
|
|
315
322
|
eda_config_yml_path = os.path.join(
|
|
316
323
|
os.getcwd(), 'eda.work', 'oclib_fifo.elab', 'eda_output_config.yml'
|
|
317
324
|
)
|
|
318
|
-
data =
|
|
325
|
+
data = yaml_safe_load(eda_config_yml_path)
|
|
319
326
|
assert 'args' in data
|
|
320
327
|
assert data['args'].get('top', '') == 'oclib_fifo'
|
|
321
328
|
assert 'config' in data
|
|
@@ -333,7 +340,7 @@ class TestsRequiresVerilator( # pylint: disable=too-many-public-methods
|
|
|
333
340
|
cmd_list +=' oclib_assert_pkg.sv oclib_pkg.sv oclib_fifo.sv'.split()
|
|
334
341
|
rc = eda.main(*cmd_list)
|
|
335
342
|
print(f'{rc=}')
|
|
336
|
-
assert rc
|
|
343
|
+
assert rc > 1
|
|
337
344
|
|
|
338
345
|
def test_config_reduced_yml(self):
|
|
339
346
|
'''Test using provided EDA --config-yml=eda_config_reduced.yml, confirm installed w/ pip'''
|
|
@@ -360,7 +367,7 @@ class TestsRequiresVerilator( # pylint: disable=too-many-public-methods
|
|
|
360
367
|
assert rc == 0
|
|
361
368
|
eda_config_yml_path = os.path.join(os.getcwd(), 'eda.work', 'oclib_fifo_test.sim',
|
|
362
369
|
'eda_output_config.yml')
|
|
363
|
-
data =
|
|
370
|
+
data = yaml_safe_load(eda_config_yml_path)
|
|
364
371
|
# make sure this config was actually used. We no longer re-add it to args
|
|
365
372
|
# (it won't show up in 'original_args') it will will show up in the config though:
|
|
366
373
|
used_yml_fname = data['config']['config-yml']
|
|
@@ -427,10 +434,10 @@ class TestMissingDepsFileErrorMessages(Helpers):
|
|
|
427
434
|
'''Looks for target_bad0, but there is no DEPS file in .'''
|
|
428
435
|
self.chdir()
|
|
429
436
|
rc = self.log_it(command_str='export target_bad0')
|
|
430
|
-
assert rc
|
|
437
|
+
assert rc > 1
|
|
431
438
|
assert self.is_in_log(
|
|
432
|
-
'Trying to resolve command-line target=./target_bad0:
|
|
433
|
-
'
|
|
439
|
+
'Trying to resolve command-line target=./target_bad0:'
|
|
440
|
+
' but path ./ has no DEPS markup file',
|
|
434
441
|
windows_path_support=True
|
|
435
442
|
)
|
|
436
443
|
|
|
@@ -478,7 +485,7 @@ class TestDepsResolveErrorMessages(Helpers):
|
|
|
478
485
|
'''Tests missing file in DEPS target using implicit deps str style'''
|
|
479
486
|
self.chdir()
|
|
480
487
|
rc = self.log_it(command_str='export target_bad0')
|
|
481
|
-
assert rc
|
|
488
|
+
assert rc > 1
|
|
482
489
|
assert self.is_in_log(
|
|
483
490
|
"target=./missing0.sv (file?): called from ./DEPS.yml::target_bad0::line=20,",
|
|
484
491
|
"File=missing0.sv not found in directory=.",
|
|
@@ -489,7 +496,7 @@ class TestDepsResolveErrorMessages(Helpers):
|
|
|
489
496
|
'''Tests missing file in DEPS target using implicit deps list style'''
|
|
490
497
|
self.chdir()
|
|
491
498
|
rc = self.log_it(command_str='export target_bad1')
|
|
492
|
-
assert rc
|
|
499
|
+
assert rc > 1
|
|
493
500
|
assert self.is_in_log(
|
|
494
501
|
"target=./missing1.sv (file?): called from ./DEPS.yml::target_bad1::line=24,",
|
|
495
502
|
"File=missing1.sv not found in directory=.",
|
|
@@ -500,7 +507,7 @@ class TestDepsResolveErrorMessages(Helpers):
|
|
|
500
507
|
'''Tests missing file in DEPS target using deps as str style'''
|
|
501
508
|
self.chdir()
|
|
502
509
|
rc = self.log_it(command_str='export target_bad2')
|
|
503
|
-
assert rc
|
|
510
|
+
assert rc > 1
|
|
504
511
|
assert self.is_in_log(
|
|
505
512
|
"target=./missing2.sv (file?): called from ./DEPS.yml::target_bad2::line=28,",
|
|
506
513
|
"File=missing2.sv not found in directory=.",
|
|
@@ -511,7 +518,7 @@ class TestDepsResolveErrorMessages(Helpers):
|
|
|
511
518
|
'''Tests missing file in DEPS target using deps as list style'''
|
|
512
519
|
self.chdir()
|
|
513
520
|
rc = self.log_it(command_str='export target_bad3')
|
|
514
|
-
assert rc
|
|
521
|
+
assert rc > 1
|
|
515
522
|
assert self.is_in_log(
|
|
516
523
|
"target=./missing3.sv (file?): called from ./DEPS.yml::target_bad3::line=33,",
|
|
517
524
|
"File=missing3.sv not found in directory=.",
|
|
@@ -522,7 +529,7 @@ class TestDepsResolveErrorMessages(Helpers):
|
|
|
522
529
|
'''EDA on a bad target (bad target within deps of 'target_bad4'), explicit deps str'''
|
|
523
530
|
self.chdir()
|
|
524
531
|
rc = self.log_it(command_str='export target_bad4')
|
|
525
|
-
assert rc
|
|
532
|
+
assert rc > 1
|
|
526
533
|
assert self.is_in_log(
|
|
527
534
|
"target=./missing_target4: called from ./DEPS.yml::target_bad4::line=39,",
|
|
528
535
|
"Target not found in deps_file=./DEPS.yml",
|
|
@@ -533,7 +540,7 @@ class TestDepsResolveErrorMessages(Helpers):
|
|
|
533
540
|
'''EDA on a bad target (bad target within deps of 'target_bad4'), explicit deps list'''
|
|
534
541
|
self.chdir()
|
|
535
542
|
rc = self.log_it(command_str='export target_bad5')
|
|
536
|
-
assert rc
|
|
543
|
+
assert rc > 1
|
|
537
544
|
assert self.is_in_log(
|
|
538
545
|
"target=./missing_target5: called from ./DEPS.yml::target_bad5::line=43,",
|
|
539
546
|
"Target not found in deps_file=./DEPS.yml",
|
|
@@ -544,7 +551,7 @@ class TestDepsResolveErrorMessages(Helpers):
|
|
|
544
551
|
'''EDA on a bad target (bad target within deps of 'target_bad4'), deps str'''
|
|
545
552
|
self.chdir()
|
|
546
553
|
rc = self.log_it(command_str='export target_bad6')
|
|
547
|
-
assert rc
|
|
554
|
+
assert rc > 1
|
|
548
555
|
assert self.is_in_log(
|
|
549
556
|
"target=./missing_target6: called from ./DEPS.yml::target_bad6::line=47,",
|
|
550
557
|
"Target not found in deps_file=./DEPS.yml",
|
|
@@ -556,7 +563,7 @@ class TestDepsResolveErrorMessages(Helpers):
|
|
|
556
563
|
'''EDA on a bad target (bad target within deps of 'target_bad4'), deps list'''
|
|
557
564
|
self.chdir()
|
|
558
565
|
rc = self.log_it(command_str='export target_bad7')
|
|
559
|
-
assert rc
|
|
566
|
+
assert rc > 1
|
|
560
567
|
assert self.is_in_log(
|
|
561
568
|
"target=./missing_target7: called from ./DEPS.yml::target_bad7::line=52,",
|
|
562
569
|
"Target not found in deps_file=./DEPS.yml",
|
|
@@ -579,7 +586,7 @@ class TestDepsResolveErrorMessages(Helpers):
|
|
|
579
586
|
'''EDA calling a non-existent target in DEPS file'''
|
|
580
587
|
self.chdir()
|
|
581
588
|
rc = self.log_it(command_str='export nope_target0')
|
|
582
|
-
assert rc
|
|
589
|
+
assert rc > 1
|
|
583
590
|
assert self.is_in_log(
|
|
584
591
|
"Trying to resolve command-line target=./nope_target0: was not",
|
|
585
592
|
"found in deps_file=./DEPS.yml, possible targets in deps file = ['foo'",
|
|
@@ -590,7 +597,7 @@ class TestDepsResolveErrorMessages(Helpers):
|
|
|
590
597
|
'''EDA calling a non-existent target in DEPS file, with file that exists.'''
|
|
591
598
|
self.chdir()
|
|
592
599
|
rc = self.log_it(command_str='export foo.sv nope_target1')
|
|
593
|
-
assert rc
|
|
600
|
+
assert rc > 1
|
|
594
601
|
assert self.is_in_log(
|
|
595
602
|
"Trying to resolve command-line target=./nope_target1: was not",
|
|
596
603
|
"found in deps_file=./DEPS.yml, possible targets in deps file = ['foo'",
|
|
@@ -601,7 +608,7 @@ class TestDepsResolveErrorMessages(Helpers):
|
|
|
601
608
|
'''EDA calling a non-existent file w/out DEPS'''
|
|
602
609
|
self.chdir()
|
|
603
610
|
rc = self.log_it(command_str='export nope_file0.sv')
|
|
604
|
-
assert rc
|
|
611
|
+
assert rc > 1
|
|
605
612
|
assert self.is_in_log(
|
|
606
613
|
"Trying to resolve command-line target=./nope_file0.sv",
|
|
607
614
|
"(file?): File=nope_file0.sv not found in directory=.",
|
|
@@ -612,7 +619,7 @@ class TestDepsResolveErrorMessages(Helpers):
|
|
|
612
619
|
'''EDA calling a non-existent file w/out DEPS, and a file that does exist.'''
|
|
613
620
|
self.chdir()
|
|
614
621
|
rc = self.log_it(command_str='export foo2.sv nope_file1.sv')
|
|
615
|
-
assert rc
|
|
622
|
+
assert rc > 1
|
|
616
623
|
assert self.is_in_log(
|
|
617
624
|
"Trying to resolve command-line target=./nope_file1.sv",
|
|
618
625
|
"(file?): File=nope_file1.sv not found in directory=.",
|
|
@@ -680,14 +687,14 @@ class TestDepsReqs:
|
|
|
680
687
|
chdir_remove_work_dir('deps_files/non_sv_reqs')
|
|
681
688
|
cmd_list = 'sim should_fail_foo_test5'.split()
|
|
682
689
|
rc = eda.main(*cmd_list)
|
|
683
|
-
assert rc
|
|
690
|
+
assert rc > 1
|
|
684
691
|
|
|
685
692
|
def test_deps_reqs6(self):
|
|
686
693
|
'''Test that should fail due bad file in deps section (none in reqs)'''
|
|
687
694
|
chdir_remove_work_dir('deps_files/non_sv_reqs')
|
|
688
695
|
cmd_list = 'sim should_fail_foo_test6'.split()
|
|
689
696
|
rc = eda.main(*cmd_list)
|
|
690
|
-
assert rc
|
|
697
|
+
assert rc > 1
|
|
691
698
|
|
|
692
699
|
|
|
693
700
|
@pytest.mark.parametrize("command", ['sim', 'shell'])
|
|
@@ -815,19 +822,19 @@ class TestDepsNoFilesTargets(Helpers):
|
|
|
815
822
|
# Using this b/c DEPS.toml has single target.
|
|
816
823
|
chdir_remove_work_dir('./deps_files/test_deps_toml')
|
|
817
824
|
rc = eda_wrap('sim', '--tool', 'verilator', 'target_whoops')
|
|
818
|
-
assert rc
|
|
825
|
+
assert rc > 1
|
|
819
826
|
|
|
820
827
|
def test_eda_sim__no_files_or_targets_shouldfail(self):
|
|
821
828
|
'''This test should fail, there is DEPS.yml (empty, no implicit target), or missing file'''
|
|
822
829
|
chdir_remove_work_dir('./deps_files/no_deps_here')
|
|
823
830
|
rc = eda_wrap('sim', '--tool', 'verilator')
|
|
824
|
-
assert rc
|
|
831
|
+
assert rc > 1
|
|
825
832
|
|
|
826
833
|
def test_eda_sim__no_files_or_targets_with_top_shouldfail(self):
|
|
827
834
|
'''This test should fail, there is DEPS.yml (empty, no implicit target), or missing file'''
|
|
828
835
|
chdir_remove_work_dir('./deps_files/no_deps_here')
|
|
829
836
|
rc = eda_wrap('sim', '--tool', 'verilator', '--top', 'empty_file')
|
|
830
|
-
assert rc
|
|
837
|
+
assert rc > 1
|
|
831
838
|
|
|
832
839
|
|
|
833
840
|
class TestDepsTags(Helpers):
|
opencos/tests/test_eda_elab.py
CHANGED
|
@@ -22,7 +22,8 @@ list_of_elab_tools = [
|
|
|
22
22
|
'slang',
|
|
23
23
|
'verilator',
|
|
24
24
|
'vivado',
|
|
25
|
-
'modelsim_ase'
|
|
25
|
+
'modelsim_ase'
|
|
26
|
+
'questa_fse',
|
|
26
27
|
'invio',
|
|
27
28
|
'surelog',
|
|
28
29
|
'invio_yosys',
|
|
@@ -80,7 +81,9 @@ def test_elab_tool_cant_run_sim(tool):
|
|
|
80
81
|
rc = 0
|
|
81
82
|
try:
|
|
82
83
|
rc = eda_wrap('sim', '--tool', tool, 'oclib_fifo')
|
|
84
|
+
print(f'{rc=}')
|
|
85
|
+
assert rc > 1
|
|
83
86
|
except NotImplementedError:
|
|
84
|
-
rc =
|
|
85
|
-
|
|
86
|
-
assert rc
|
|
87
|
+
rc = 3
|
|
88
|
+
print(f'{rc=} (forced to 3 for NotImplementedError)')
|
|
89
|
+
assert rc > 1
|
opencos/tests/test_eda_synth.py
CHANGED
opencos/tests/test_oc_cli.py
CHANGED
opencos/tests/test_tools.py
CHANGED
|
@@ -6,12 +6,13 @@ import os
|
|
|
6
6
|
import sys
|
|
7
7
|
import pytest
|
|
8
8
|
|
|
9
|
-
from opencos import eda,
|
|
9
|
+
from opencos import eda, eda_tool_helper, eda_base
|
|
10
10
|
|
|
11
11
|
from opencos.tools.verilator import ToolVerilator
|
|
12
12
|
from opencos.tools.vivado import ToolVivado
|
|
13
13
|
from opencos.tests import helpers
|
|
14
14
|
from opencos.tests.helpers import eda_wrap
|
|
15
|
+
from opencos.utils.markup_helpers import yaml_safe_load
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
thispath = os.path.dirname(__file__)
|
|
@@ -72,6 +73,7 @@ list_of_tools = [
|
|
|
72
73
|
'verilator',
|
|
73
74
|
'vivado',
|
|
74
75
|
'modelsim_ase',
|
|
76
|
+
'questa_fse',
|
|
75
77
|
]
|
|
76
78
|
|
|
77
79
|
list_of_deps_targets = [
|
|
@@ -129,7 +131,7 @@ def test_vivado_tool_defines():
|
|
|
129
131
|
os.getcwd(), 'eda.work', 'oclib_fifo.elab', 'eda_output_config.yml'
|
|
130
132
|
)
|
|
131
133
|
|
|
132
|
-
data =
|
|
134
|
+
data = yaml_safe_load(eda_config_yml_path)
|
|
133
135
|
assert 'args' in data
|
|
134
136
|
assert data['args'].get('top', '') == 'oclib_fifo'
|
|
135
137
|
assert 'config' in data
|
opencos/tools/iverilog.py
CHANGED
|
@@ -7,9 +7,9 @@ import shutil
|
|
|
7
7
|
import subprocess
|
|
8
8
|
|
|
9
9
|
from opencos import util
|
|
10
|
-
from opencos.util import sanitize_defines_for_sh
|
|
11
10
|
from opencos.eda_base import Tool
|
|
12
11
|
from opencos.commands import CommandSim
|
|
12
|
+
from opencos.utils.str_helpers import sanitize_defines_for_sh
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class ToolIverilog(Tool):
|
|
@@ -108,7 +108,7 @@ class CommandSimIverilog(CommandSim, ToolIverilog):
|
|
|
108
108
|
]
|
|
109
109
|
)
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
self.write_eda_config_and_args()
|
|
112
112
|
|
|
113
113
|
def compile(self):
|
|
114
114
|
if self.args['stop-before-compile']:
|