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.
Files changed (58) hide show
  1. opencos/__init__.py +4 -2
  2. opencos/_version.py +10 -7
  3. opencos/commands/flist.py +8 -7
  4. opencos/commands/multi.py +14 -15
  5. opencos/commands/sim.py +5 -0
  6. opencos/commands/sweep.py +3 -2
  7. opencos/deps/__init__.py +0 -0
  8. opencos/deps/defaults.py +69 -0
  9. opencos/deps/deps_commands.py +419 -0
  10. opencos/deps/deps_file.py +326 -0
  11. opencos/deps/deps_processor.py +670 -0
  12. opencos/deps_schema.py +7 -8
  13. opencos/eda.py +84 -64
  14. opencos/eda_base.py +585 -316
  15. opencos/eda_config.py +85 -14
  16. opencos/eda_config_defaults.yml +36 -4
  17. opencos/eda_extract_targets.py +22 -14
  18. opencos/eda_tool_helper.py +33 -7
  19. opencos/export_helper.py +166 -86
  20. opencos/export_json_convert.py +31 -23
  21. opencos/files.py +2 -1
  22. opencos/hw/__init__.py +0 -0
  23. opencos/{oc_cli.py → hw/oc_cli.py} +9 -4
  24. opencos/names.py +0 -4
  25. opencos/peakrdl_cleanup.py +13 -7
  26. opencos/seed.py +19 -11
  27. opencos/tests/helpers.py +3 -2
  28. opencos/tests/test_deps_helpers.py +35 -32
  29. opencos/tests/test_eda.py +36 -29
  30. opencos/tests/test_eda_elab.py +7 -4
  31. opencos/tests/test_eda_synth.py +1 -1
  32. opencos/tests/test_oc_cli.py +1 -1
  33. opencos/tests/test_tools.py +4 -2
  34. opencos/tools/iverilog.py +2 -2
  35. opencos/tools/modelsim_ase.py +24 -2
  36. opencos/tools/questa.py +5 -3
  37. opencos/tools/questa_fse.py +57 -0
  38. opencos/tools/riviera.py +1 -1
  39. opencos/tools/slang.py +9 -3
  40. opencos/tools/surelog.py +1 -1
  41. opencos/tools/verilator.py +26 -1
  42. opencos/tools/vivado.py +34 -27
  43. opencos/tools/yosys.py +4 -3
  44. opencos/util.py +532 -474
  45. opencos/utils/__init__.py +0 -0
  46. opencos/utils/markup_helpers.py +98 -0
  47. opencos/utils/str_helpers.py +111 -0
  48. opencos/utils/subprocess_helpers.py +108 -0
  49. {opencos_eda-0.2.48.dist-info → opencos_eda-0.2.50.dist-info}/METADATA +1 -1
  50. opencos_eda-0.2.50.dist-info/RECORD +89 -0
  51. {opencos_eda-0.2.48.dist-info → opencos_eda-0.2.50.dist-info}/entry_points.txt +1 -1
  52. opencos/deps_helpers.py +0 -1346
  53. opencos_eda-0.2.48.dist-info/RECORD +0 -79
  54. /opencos/{pcie.py → hw/pcie.py} +0 -0
  55. {opencos_eda-0.2.48.dist-info → opencos_eda-0.2.50.dist-info}/WHEEL +0 -0
  56. {opencos_eda-0.2.48.dist-info → opencos_eda-0.2.50.dist-info}/licenses/LICENSE +0 -0
  57. {opencos_eda-0.2.48.dist-info → opencos_eda-0.2.50.dist-info}/licenses/LICENSE.spdx +0 -0
  58. {opencos_eda-0.2.48.dist-info → opencos_eda-0.2.50.dist-info}/top_level.txt +0 -0
@@ -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
- def run(file_in, file_out):
7
- with open(file_in) as f:
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 = sys.argv[1]
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 = list()
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
- def get_seed(style : str = "", limit_31bit=True, avoid_zero=True):
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 int(time.time())
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
- seed = int(time.time())
25
+ # use the float value fractional portion
26
+ seed = time.time_ns() & 0xFFFF_FFFF
19
27
  else:
20
- seed = random.randint(0, 0xFFFFFFFF)
28
+ seed = random.randint(0, 0xFFFF_FFFF)
21
29
 
22
- if limit_31bit and seed >> 31:
23
- seed >>= 1
30
+ if limit_31bit:
31
+ seed &= 0x7FFF_FFFF
24
32
  if avoid_zero and seed == 0:
25
- seed += 1
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, util
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 = util.yaml_safe_load(filepath)
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.deps_helpers'''
1
+ '''pytests for opencos.deps modules'''
2
2
 
3
- # TODO(drew): these need to be refactored if we cleanup deps_helpers.py, this still
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, deps_helpers
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 deps_helpers.get_all_targets(filter_str:str) works'''
24
+ '''Makes sure that deps_file.get_all_targets(filter_str:str) works'''
23
25
 
24
- targets = deps_helpers.get_all_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 deps_helpers.get_all_targets(filter_using_mult:str) works'''
47
+ '''Makes sure that deps_file.get_all_targets(filter_using_mult:str) works'''
46
48
 
47
- targets = deps_helpers.get_all_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 = deps_helpers.parse_deps_shell_str(line, '', '')
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 = deps_helpers.parse_deps_shell_str(line, '', '')
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 = deps_helpers.parse_deps_shell_str(line, '', '')
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 = deps_helpers.parse_deps_shell_str(line, '', '')
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 = deps_helpers.parse_deps_shell_str(line, '', '')
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 ../deps_helpers.py foo.py'
89
- d = deps_helpers.parse_deps_shell_str(line, target_path='./', target_node='foo_target')
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
- assert d['exec_list'] == ['cp', os.path.abspath('../deps_helpers.py'), 'foo.py'], f'{d=}'
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 ../deps_helpers.py foo.py'
100
- d = deps_helpers.parse_deps_shell_str(line, target_path='./', target_node='foo_target',
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', '../deps_helpers.py', 'foo.py'], f'{d=}'
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 = deps_helpers.parse_deps_shell_str(line, target_path='./', target_node='foo_target',
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 = deps_helpers.parse_deps_shell_str(line, target_path='./', target_node='foo_target')
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 = deps_helpers.parse_deps_work_dir_add_srcs(line, '', '')
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 = deps_helpers.parse_deps_work_dir_add_srcs(line, '', '')
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 = deps_helpers.parse_deps_work_dir_add_srcs(line, '', '')
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 = deps_helpers.parse_deps_work_dir_add_srcs(line, '', '')
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 = deps_helpers.parse_deps_work_dir_add_srcs(line, '', '')
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 = deps_helpers.parse_deps_peakrdl(line, '', '')
165
+ d = deps_commands.parse_deps_peakrdl(line, '', '')
163
166
  assert not d, f'{d=}'
164
167
 
165
168
  line = 'some_target:'
166
- d = deps_helpers.parse_deps_peakrdl(line, '', '')
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 = deps_helpers.parse_deps_peakrdl(line, '', '')
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 = deps_helpers.parse_deps_peakrdl(line, '', '')
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 = deps_helpers.parse_deps_peakrdl(line, '', '')
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 = deps_helpers.parse_deps_peakrdl(line, '', '')
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, util, eda_tool_helper
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 != 0
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 != 0
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 != 0
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 != 0
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 = util.yaml_safe_load(eda_config_yml_path)
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 = util.yaml_safe_load(eda_config_yml_path)
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 != 0
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 = util.yaml_safe_load(eda_config_yml_path)
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 != 0
437
+ assert rc > 1
431
438
  assert self.is_in_log(
432
- 'Trying to resolve command-line target=./target_bad0: was not found',
433
- 'in deps_file=None, possible targets in deps file = []',
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 != 0
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 != 0
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 != 0
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 != 0
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 != 0
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 != 0
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 != 0
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 != 0
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 != 0
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 != 0
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 != 0
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 != 0
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 != 0
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 != 0
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 == 1
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 == 1
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 == 1
837
+ assert rc > 1
831
838
 
832
839
 
833
840
  class TestDepsTags(Helpers):
@@ -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 = 1
85
- print(f'{rc=}')
86
- assert rc != 0
87
+ rc = 3
88
+ print(f'{rc=} (forced to 3 for NotImplementedError)')
89
+ assert rc > 1
@@ -53,7 +53,7 @@ class Tests:
53
53
  ' target_doesnt_exist*').split()
54
54
  rc = eda.main(*cmdlist)
55
55
  print(f'{rc=}')
56
- assert rc != 0
56
+ assert rc > 1
57
57
 
58
58
  def test_args_multi_synth_oclib_fifos(self, tool, command):
59
59
  '''This should be 4 jobs and takes ~15 seconds for synth.'''
@@ -6,7 +6,7 @@ If you want to run this, consider running from the root of opencos repo:
6
6
  which avoids using any pip installed opencos.eda
7
7
  '''
8
8
 
9
- from opencos import oc_cli
9
+ from opencos.hw import oc_cli
10
10
 
11
11
  def test_args_help():
12
12
  '''simple test for: oc_cli --help'''
@@ -6,12 +6,13 @@ import os
6
6
  import sys
7
7
  import pytest
8
8
 
9
- from opencos import eda, util, eda_tool_helper, eda_base
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 = util.yaml_safe_load(eda_config_yml_path)
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
- util.write_eda_config_and_args(dirpath=self.args['work-dir'], command_obj_ref=self)
111
+ self.write_eda_config_and_args()
112
112
 
113
113
  def compile(self):
114
114
  if self.args['stop-before-compile']: