opencos-eda 0.2.52__tar.gz → 0.2.54__tar.gz
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_eda-0.2.52/opencos_eda.egg-info → opencos_eda-0.2.54}/PKG-INFO +1 -1
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/commands/__init__.py +2 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/commands/build.py +1 -1
- opencos_eda-0.2.54/opencos/commands/deps_help.py +259 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/commands/export.py +1 -1
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/commands/flist.py +4 -1
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/commands/lec.py +1 -1
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/commands/open.py +2 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/commands/proj.py +1 -1
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/commands/shell.py +1 -1
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/commands/sim.py +76 -8
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/commands/synth.py +1 -1
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/commands/upload.py +3 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/commands/waves.py +1 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/deps/defaults.py +1 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/deps/deps_file.py +30 -4
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/deps/deps_processor.py +72 -2
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/deps_schema.py +3 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/eda.py +50 -26
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/eda_base.py +177 -33
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/eda_config.py +1 -1
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/eda_config_defaults.yml +49 -3
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/eda_extract_targets.py +1 -58
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tests/helpers.py +16 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tests/test_eda.py +14 -3
- opencos_eda-0.2.54/opencos/tests/test_tools.py +377 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tools/cocotb.py +15 -14
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tools/iverilog.py +4 -24
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tools/modelsim_ase.py +70 -57
- opencos_eda-0.2.54/opencos/tools/quartus.py +680 -0
- opencos_eda-0.2.54/opencos/tools/questa.py +273 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tools/questa_fse.py +10 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tools/riviera.py +1 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tools/verilator.py +9 -15
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tools/vivado.py +30 -23
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/util.py +89 -15
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/utils/status_constants.py +1 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/utils/str_helpers.py +85 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54/opencos_eda.egg-info}/PKG-INFO +1 -1
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos_eda.egg-info/SOURCES.txt +2 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/pyproject.toml +1 -1
- opencos_eda-0.2.52/opencos/tests/test_tools.py +0 -350
- opencos_eda-0.2.52/opencos/tools/questa.py +0 -205
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/LICENSE +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/LICENSE.spdx +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/README.md +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/__init__.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/_version.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/_waves_pkg.sv +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/commands/elab.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/commands/multi.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/commands/sweep.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/commands/targets.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/deps/__init__.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/deps/deps_commands.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/eda_config_max_verilator_waivers.yml +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/eda_config_reduced.yml +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/eda_deps_bash_completion.bash +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/eda_deps_sanitize.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/eda_tool_helper.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/export_helper.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/export_json_convert.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/files.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/hw/__init__.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/hw/oc_cli.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/hw/pcie.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/names.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/peakrdl_cleanup.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/seed.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tests/__init__.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tests/custom_config.yml +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tests/deps_files/command_order/DEPS.yml +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tests/deps_files/error_msgs/DEPS.yml +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tests/deps_files/iverilog_test/DEPS.yml +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tests/deps_files/no_deps_here/DEPS.yml +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tests/deps_files/non_sv_reqs/DEPS.yml +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tests/deps_files/tags_with_tools/DEPS.yml +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tests/deps_files/test_err_fatal/DEPS.yml +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tests/test_build.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tests/test_deps_helpers.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tests/test_deps_schema.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tests/test_eda_elab.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tests/test_eda_synth.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tests/test_oc_cli.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tools/__init__.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tools/invio.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tools/invio_helpers.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tools/invio_yosys.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tools/slang.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tools/slang_yosys.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tools/surelog.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tools/tabbycad_yosys.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/tools/yosys.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/utils/__init__.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/utils/markup_helpers.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/utils/subprocess_helpers.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/utils/vscode_helper.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos/utils/vsim_helper.py +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos_eda.egg-info/dependency_links.txt +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos_eda.egg-info/entry_points.txt +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos_eda.egg-info/requires.txt +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/opencos_eda.egg-info/top_level.txt +0 -0
- {opencos_eda-0.2.52 → opencos_eda-0.2.54}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opencos-eda
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.54
|
|
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
|
|
@@ -20,6 +20,7 @@ from .waves import CommandWaves
|
|
|
20
20
|
from .shell import CommandShell
|
|
21
21
|
from .targets import CommandTargets
|
|
22
22
|
from .lec import CommandLec
|
|
23
|
+
from .deps_help import CommandDepsHelp
|
|
23
24
|
|
|
24
25
|
__all__ = [
|
|
25
26
|
'CommandBuild',
|
|
@@ -38,4 +39,5 @@ __all__ = [
|
|
|
38
39
|
'CommandShell',
|
|
39
40
|
'CommandTargets',
|
|
40
41
|
'CommandLec',
|
|
42
|
+
'CommandDepsHelp',
|
|
41
43
|
]
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
'''opencos.commands.deps_help - command handler for: eda deps_help [args]
|
|
2
|
+
|
|
3
|
+
Note this command is handled differently than others (such as CommandSim),
|
|
4
|
+
it is generally run as simply
|
|
5
|
+
|
|
6
|
+
> eda deps_help
|
|
7
|
+
> eda deps_help --verbose
|
|
8
|
+
> eda deps_help --help
|
|
9
|
+
|
|
10
|
+
uses no tools and will print a help text regarding DEPS markup files to stdout.
|
|
11
|
+
'''
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
import os
|
|
15
|
+
|
|
16
|
+
from opencos.eda_base import Command
|
|
17
|
+
from opencos import util
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
BASIC_DEPS_HELP = '''
|
|
21
|
+
|
|
22
|
+
--------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
What is a DEPS.yml file and why does `eda` use this?
|
|
25
|
+
- DEPS.yml is a fancy filelist.
|
|
26
|
+
- Used to organize a project into "targets", a tool can run on a "target".
|
|
27
|
+
- Allows for more than just source files attached to a "target".
|
|
28
|
+
-- incdirs, defines, and args can be applied to a "target".
|
|
29
|
+
|
|
30
|
+
--------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
Hello World example:
|
|
33
|
+
|
|
34
|
+
The following example is a DEPS.yml file example for a SystemVerilog simulation of
|
|
35
|
+
hello_world_tb.sv. DEPS.yml is, in short, a fancy filelist. We use them in the `eda`
|
|
36
|
+
app to organize projects.
|
|
37
|
+
|
|
38
|
+
--- DEPS.yml: ---
|
|
39
|
+
|
|
40
|
+
hello-world: # <-- this is a named target that will be run
|
|
41
|
+
|
|
42
|
+
deps: # <-- 'deps' is a list of SV, Verilog, VHDL files in compile order
|
|
43
|
+
- hello_world_tb.sv
|
|
44
|
+
|
|
45
|
+
top: hello_world_tb # <-- For testbenches, it is good practice to specifiy the topmost
|
|
46
|
+
# module using using 'top'. This is not necessary for design
|
|
47
|
+
# files.
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
--- hello_world_tb.sv: ---
|
|
51
|
+
|
|
52
|
+
module hello_world_tb;
|
|
53
|
+
|
|
54
|
+
initial begin
|
|
55
|
+
#10ns;
|
|
56
|
+
$display("%t %m: Hello World!", $realtime);
|
|
57
|
+
$display("%t %m: Test finished", $realtime);
|
|
58
|
+
$finish;
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
endmodule : hello_world_tb
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
hello-world:
|
|
67
|
+
The target name in the DEPS.yml we named is hello-world. That is a valid target
|
|
68
|
+
that `eda` can use. Such as:
|
|
69
|
+
|
|
70
|
+
eda sim --tool=verilator hello-world
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
--------------------------------------------------------------------
|
|
74
|
+
|
|
75
|
+
Beyond Hello World example:
|
|
76
|
+
|
|
77
|
+
The following example is a DEPS.yml file for a more complex module simulation.
|
|
78
|
+
It has two files in ./DEPS.yml and ./lib/DEPS.yml.
|
|
79
|
+
|
|
80
|
+
--- ./DEPS.yml: ---
|
|
81
|
+
|
|
82
|
+
my_fifo: # <-- this is a design
|
|
83
|
+
incdirs: . lib # <-- 'incdirs' define the paths searched to find `include files
|
|
84
|
+
defines:
|
|
85
|
+
FIFO_DEBUG # add a basic define
|
|
86
|
+
FIFO_IMPLEMENTATION=uram # add a define with a value
|
|
87
|
+
deps: # <-- 'deps' is a list of SV, Verilog, VHDL files in compile order
|
|
88
|
+
- my_fifo.sv # an SV file pulled in directly
|
|
89
|
+
- lib/bin_to_gray # a target, in a subdirectory that has it's own DEPS
|
|
90
|
+
|
|
91
|
+
my_fifo_test: # <-- this is a TEST
|
|
92
|
+
top: my_fifo_test # the top will default to whatever target is provided
|
|
93
|
+
# by the user, so this could be optional
|
|
94
|
+
deps:
|
|
95
|
+
- my_fifo # the target that is defined above
|
|
96
|
+
- my_fifo_tb.sv # an SV file pulled in directly
|
|
97
|
+
|
|
98
|
+
my_fifo_stress_test: # <-- this is another TEST
|
|
99
|
+
top: my_fifo_test # not optional because top is not "my_fifo_stress_test"
|
|
100
|
+
defines:
|
|
101
|
+
STRESS_TEST # configures my_fifo_test to be more stressful
|
|
102
|
+
deps:
|
|
103
|
+
- my_fifo_test # aside from the define, this is same as "my_fifo_test"
|
|
104
|
+
|
|
105
|
+
--- lib/DEPS.yml: ---
|
|
106
|
+
|
|
107
|
+
lib_pkg: # <-- this is a package required by bin_to_gray below
|
|
108
|
+
deps:
|
|
109
|
+
- assert_pkg.sv # an SV package pulled in directly, before it's needed below
|
|
110
|
+
- lib_pkg.sv # an SV package pulled in directly
|
|
111
|
+
|
|
112
|
+
bin_to_gray: # <-- this is the target that was required by ../my_fifo
|
|
113
|
+
deps:
|
|
114
|
+
- lib_pkg # a target package, listed first as SV requires packages
|
|
115
|
+
# to be read before the code that uses them
|
|
116
|
+
- bin_to_gray.sv # an SV module pulled in directly
|
|
117
|
+
|
|
118
|
+
--------------------------------------------------------------------
|
|
119
|
+
'''
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
FULL_DEPS_HELP = '''
|
|
123
|
+
|
|
124
|
+
--------------------------------------------------------------------
|
|
125
|
+
|
|
126
|
+
Full DEPS.yml schema:
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
DEFAULTS: # <table> defaults applied to ALL targets in this file, local targets ** override ** the defaults.
|
|
130
|
+
|
|
131
|
+
METADATA: # <table> unstructured data, any UPPERCASE first level key is not considered a target.
|
|
132
|
+
|
|
133
|
+
target-spec:
|
|
134
|
+
|
|
135
|
+
args: # <array or | separated str>
|
|
136
|
+
- --waves
|
|
137
|
+
- --sim_plusargs="+info=500"
|
|
138
|
+
|
|
139
|
+
defines: # <table>
|
|
140
|
+
SOME_DEFINE: value
|
|
141
|
+
SOME_DEFINE_NO_VALUE: # we just leave this blank, or use nil (yaml's None)
|
|
142
|
+
|
|
143
|
+
incdirs: # <array>
|
|
144
|
+
- some/relative/path
|
|
145
|
+
|
|
146
|
+
top: # <string>
|
|
147
|
+
|
|
148
|
+
deps: # <array or | space separated string>
|
|
149
|
+
- some_relative_target # <string> aka, a target
|
|
150
|
+
- some_file.sv # <string> aka, a file
|
|
151
|
+
- sv@some_file.txt # <string> aka, ext@file where we'd like a file not ending in .sv to be
|
|
152
|
+
# treated as a .sv file for tools.
|
|
153
|
+
# Supported for sv@, v@, vhdl@, cpp@
|
|
154
|
+
- commands: # <table> with key 'commands' for a <array>: support for built-in commands
|
|
155
|
+
# Note this cannot be confused for other targets or files.
|
|
156
|
+
- shell: # <string>
|
|
157
|
+
var-subst-args: # <bool> default false. If true, substitute vars in commands, such as {fpga}
|
|
158
|
+
# substituted from eda arg --fpga=SomeFpga, such that {fpga} becomes SomeFpga
|
|
159
|
+
var-subst-os-env: #<bool> default false. If true, substitute vars in commands using os.environ vars,
|
|
160
|
+
# such as {FPGA} could get substituted by env value for $FPGA
|
|
161
|
+
tee: # <string> optional filename, otherwise shell commands write to {target-spec}__shell_0.log
|
|
162
|
+
run-from-work-dir: #<bool> default true. If false, runs from the directory of this DEPS file.
|
|
163
|
+
filepath-subst-target-dir: #<bool> default true. If false, disables shell file path
|
|
164
|
+
substituion on this target's directory (this DEPS file dir).
|
|
165
|
+
dirpath-subst-target-dir: #<bool> default false. If true, enables shell directory path
|
|
166
|
+
substituion on this target's directory (this DEPS file dir).
|
|
167
|
+
- shell: echo "Hello World!"
|
|
168
|
+
- work-dir-add-sources: # <array or | space separated string>, this is how to add generated files
|
|
169
|
+
# to compile order list.
|
|
170
|
+
- peakrdl: # <string> ## peakrdl command to generate CSRs
|
|
171
|
+
|
|
172
|
+
reqs: # <array or | space separated string>
|
|
173
|
+
- some_file.mem # <string> aka, a non-source file required for this target.
|
|
174
|
+
# This file is checked for existence prior to invoking the tool involved, for example,
|
|
175
|
+
# in a simulation this would be done prior to a compile step.
|
|
176
|
+
|
|
177
|
+
multi:
|
|
178
|
+
ignore-this-target: # <array of tables> eda commands to be ignored in `eda multi <command>` for this target only
|
|
179
|
+
# this is checked in the matching multi targets list, and is not inherited through dependencies.
|
|
180
|
+
- commands: synth # space separated strings
|
|
181
|
+
tools: vivado # space separated strings
|
|
182
|
+
|
|
183
|
+
- commands: sim # omit tools, ignores 'sim' commands for all tools, for this target only, when this target
|
|
184
|
+
# is in the target list called by `eda multi`.
|
|
185
|
+
|
|
186
|
+
- tools: vivado # omit commands, ignores all commands if tool is vivado, for this target only, when this target
|
|
187
|
+
# is in the target list called by `eda multi`.
|
|
188
|
+
|
|
189
|
+
args: # <array> additional args added to all multi commands of this target.
|
|
190
|
+
# Note that all args are POSIX with dashes, --sim-plusargs=value, etc.
|
|
191
|
+
|
|
192
|
+
<eda-command>: # key is one of sim, flist, build, synth, etc.
|
|
193
|
+
# can be used instead of 'tags' to support different args or deps.
|
|
194
|
+
disable-tools: # Note: not implemented yet.
|
|
195
|
+
only-tools: # Note: not implemented yet.
|
|
196
|
+
args: # <array or | space separated string>
|
|
197
|
+
deps: # <array or | space separated string> # Note: not implemented yet
|
|
198
|
+
defines: ## <table>
|
|
199
|
+
incdirs: ## <array>
|
|
200
|
+
|
|
201
|
+
tags: # <table> this is the currently support tags features in a target.
|
|
202
|
+
<tag-name>: # <string> key for table, can be anything, name is not used.
|
|
203
|
+
with-tools: <array or | space separated string>
|
|
204
|
+
# If using one of these tools, apply these values.
|
|
205
|
+
# entries can be in the form: vivado, or vivado:2024.1
|
|
206
|
+
with-commands: <array or | space separated string>
|
|
207
|
+
# apply if this was the `eda` command, such as: sim
|
|
208
|
+
with-args: # <table> (optional) arg key/value pairs to match for this tag.
|
|
209
|
+
# this would be an alternative to running eda with --tags=value
|
|
210
|
+
# The existence of an argument with correct value would enable a tag.
|
|
211
|
+
# And example would be:
|
|
212
|
+
# with-args:
|
|
213
|
+
# waves: true
|
|
214
|
+
args: <array or | space separated string> # args to be applied if this target is used, with a matching
|
|
215
|
+
# tool in 'with-tools'.
|
|
216
|
+
deps: <array or | space separated string, applied with tag>
|
|
217
|
+
defines: <table, applied with tag>
|
|
218
|
+
incdirs: <array, applied with tag>
|
|
219
|
+
replace-config-tools: <table> # spec matching eda_config_defaults.yml::tools.<tool> (replace merge strategy)
|
|
220
|
+
additive-config-tools: <table> # spec matching eda_config_defaults.yml::tools.<tool> (additive merge strategy)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
```
|
|
224
|
+
'''
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
class CommandDepsHelp:
|
|
228
|
+
'''command handler for: eda deps-help'''
|
|
229
|
+
|
|
230
|
+
command_name = 'deps-help'
|
|
231
|
+
|
|
232
|
+
def __init__(self, config: dict):
|
|
233
|
+
# We don't inherit opencos.eda_base.Command, so we have to set a few
|
|
234
|
+
# member vars for Command.help to work.
|
|
235
|
+
self.args = {}
|
|
236
|
+
self.args_help = {}
|
|
237
|
+
self.config = config
|
|
238
|
+
self.status = 0
|
|
239
|
+
|
|
240
|
+
def process_tokens( # pylint: disable=unused-argument
|
|
241
|
+
self, tokens: list, process_all: bool = True,
|
|
242
|
+
pwd: str = os.getcwd()
|
|
243
|
+
) -> list:
|
|
244
|
+
'''This is effectively our 'run' method, entrypoint from opencos.eda.main'''
|
|
245
|
+
|
|
246
|
+
print(BASIC_DEPS_HELP)
|
|
247
|
+
if util.args['verbose'] or util.args['debug']:
|
|
248
|
+
print()
|
|
249
|
+
print(FULL_DEPS_HELP)
|
|
250
|
+
|
|
251
|
+
return []
|
|
252
|
+
|
|
253
|
+
def help(self, tokens: list) -> None:
|
|
254
|
+
'''Since we don't inherit from opencos.eda_base.Command, need our own help
|
|
255
|
+
method
|
|
256
|
+
'''
|
|
257
|
+
Command.help(self, tokens=tokens, no_targets=True)
|
|
258
|
+
print()
|
|
259
|
+
print(FULL_DEPS_HELP)
|
|
@@ -40,7 +40,7 @@ class CommandExport(CommandDesign):
|
|
|
40
40
|
unparsed = CommandDesign.process_tokens(
|
|
41
41
|
self, tokens=tokens, process_all=process_all, pwd=pwd
|
|
42
42
|
)
|
|
43
|
-
if self.
|
|
43
|
+
if self.stop_process_tokens_before_do_it():
|
|
44
44
|
return unparsed
|
|
45
45
|
if self.args['top']:
|
|
46
46
|
# create our work dir, b/c top is set. We do this so any shell or peakrdl style
|
|
@@ -63,6 +63,9 @@ class CommandFList(CommandDesign):
|
|
|
63
63
|
unparsed = CommandDesign.process_tokens(
|
|
64
64
|
self, tokens=tokens, process_all=process_all, pwd=pwd
|
|
65
65
|
)
|
|
66
|
+
if self.stop_process_tokens_before_do_it():
|
|
67
|
+
return unparsed
|
|
68
|
+
|
|
66
69
|
self.do_it()
|
|
67
70
|
return unparsed
|
|
68
71
|
|
|
@@ -211,6 +214,6 @@ class CommandFList(CommandDesign):
|
|
|
211
214
|
print() # don't need to close fo (None)
|
|
212
215
|
else:
|
|
213
216
|
fo.close()
|
|
214
|
-
util.info(f"Created {self.args['out']}")
|
|
217
|
+
util.info(f"Created file: {self.args['out']}")
|
|
215
218
|
|
|
216
219
|
self.write_eda_config_and_args()
|
|
@@ -72,6 +72,8 @@ class CommandSim(CommandDesign):
|
|
|
72
72
|
'waves': 'Include waveforms, if possible for tool',
|
|
73
73
|
'waves-start': 'Starting time of waveform capture, if possible for tool',
|
|
74
74
|
'work-dir': 'Optional override for working directory, defaults to ./eda.work/<top>.sim',
|
|
75
|
+
'test-mode': ('stops the command early without executing, if --gui is present will'
|
|
76
|
+
' instead test without spawning gui')
|
|
75
77
|
|
|
76
78
|
})
|
|
77
79
|
|
|
@@ -97,7 +99,7 @@ class CommandSim(CommandDesign):
|
|
|
97
99
|
self, tokens=tokens, process_all=process_all, pwd=pwd
|
|
98
100
|
)
|
|
99
101
|
|
|
100
|
-
if self.
|
|
102
|
+
if self.stop_process_tokens_before_do_it():
|
|
101
103
|
return unparsed
|
|
102
104
|
|
|
103
105
|
# add defines for this job type
|
|
@@ -176,8 +178,13 @@ class CommandSim(CommandDesign):
|
|
|
176
178
|
)
|
|
177
179
|
|
|
178
180
|
if check_logs and log_fname:
|
|
181
|
+
# Note this call will check on stdout if not GUI, not opening the log_fname,
|
|
182
|
+
# but if this is GUI we normally lose stdout and have to open the log.
|
|
183
|
+
gui_mode = self.args.get('gui', False)
|
|
184
|
+
file_contents_str = '' if gui_mode else stdout
|
|
179
185
|
self.check_logs_for_errors(
|
|
180
|
-
filename='',
|
|
186
|
+
filename=os.path.join(self.args['work-dir'], log_fname),
|
|
187
|
+
file_contents_str=file_contents_str,
|
|
181
188
|
bad_strings=bad_strings, must_strings=must_strings,
|
|
182
189
|
use_bad_strings=use_bad_strings, use_must_strings=use_must_strings
|
|
183
190
|
)
|
|
@@ -285,6 +292,9 @@ class CommandSim(CommandDesign):
|
|
|
285
292
|
'''Returns None, checks logs using args bad_strings, must_strings,
|
|
286
293
|
|
|
287
294
|
and internals self.args["log-[bad|must]-strings"] (lists).
|
|
295
|
+
|
|
296
|
+
file_contents_str will take precedence over opening filename, but filename is still
|
|
297
|
+
used in messaging.
|
|
288
298
|
'''
|
|
289
299
|
|
|
290
300
|
_bad_strings = bad_strings
|
|
@@ -304,13 +314,27 @@ class CommandSim(CommandDesign):
|
|
|
304
314
|
hit_must_string_dict = dict.fromkeys(_must_strings)
|
|
305
315
|
|
|
306
316
|
lines = []
|
|
307
|
-
|
|
317
|
+
|
|
318
|
+
log_fpath = ''
|
|
319
|
+
if os.path.exists(filename):
|
|
320
|
+
log_fpath = filename
|
|
321
|
+
|
|
308
322
|
if file_contents_str:
|
|
309
323
|
lines = file_contents_str.split('\n')
|
|
324
|
+
log_fname = log_fpath + '(STDOUT)'
|
|
325
|
+
util.debug(f'Checking log for errors: {log_fpath=} but checking from STDOUT string...')
|
|
310
326
|
elif filename:
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
327
|
+
log_fname = log_fpath
|
|
328
|
+
util.debug(f'Checking log for errors: {log_fpath=} opening file...')
|
|
329
|
+
if not os.path.exists(log_fname):
|
|
330
|
+
self.error(f'sim.check_logs_for_errors: log {log_fpath} does not exist, cannot',
|
|
331
|
+
'check it for errors or passing strings')
|
|
332
|
+
return
|
|
333
|
+
with open(log_fpath, 'r', encoding='utf-8') as f:
|
|
334
|
+
lines = f.read().splitlines()
|
|
335
|
+
else:
|
|
336
|
+
self.error(f'sim.check_logs_for_errors: {log_fpath=} does not exist, and no',
|
|
337
|
+
'file_contents_str exists to check')
|
|
314
338
|
|
|
315
339
|
if lines:
|
|
316
340
|
for lineno, line in enumerate(lines):
|
|
@@ -320,17 +344,61 @@ class CommandSim(CommandDesign):
|
|
|
320
344
|
hit_must_string_dict[k] = True
|
|
321
345
|
if any(bad_str in line for bad_str in _bad_strings):
|
|
322
346
|
self.error(
|
|
323
|
-
f"log {
|
|
347
|
+
f"log {log_fname}:{lineno} contains one of {_bad_strings=}",
|
|
324
348
|
error_code=status_constants.EDA_SIM_LOG_HAS_BAD_STRING
|
|
325
349
|
)
|
|
326
350
|
|
|
327
351
|
if any(x is None for x in hit_must_string_dict.values()):
|
|
328
352
|
self.error(
|
|
329
|
-
f"Didn't get all passing patterns in log {
|
|
353
|
+
f"Didn't get all passing patterns in log {log_fname}: {_must_strings=}",
|
|
330
354
|
f" {hit_must_string_dict=}",
|
|
331
355
|
error_code=status_constants.EDA_SIM_LOG_MISSING_MUST_STRING
|
|
332
356
|
)
|
|
333
357
|
|
|
358
|
+
def write_sh_scripts_to_work_dir(
|
|
359
|
+
self, compile_lists: list, elaborate_lists: list, simulate_lists: list,
|
|
360
|
+
compile_line_breaks: bool = True,
|
|
361
|
+
elaborate_line_breaks: bool = False,
|
|
362
|
+
simulate_line_breaks: bool = False,
|
|
363
|
+
simulate_sh_fname: str = 'simulate.sh'
|
|
364
|
+
) -> None:
|
|
365
|
+
'''Writes compile.sh, elaborate.sh, simulate.sh (if present), all.sh to work-dir
|
|
366
|
+
|
|
367
|
+
Will include the pre_compile_dep_shell_commands.sh if those are present.
|
|
368
|
+
compile_line_breaks defaults to True (one word per line w/ line breaks added)
|
|
369
|
+
'''
|
|
370
|
+
|
|
371
|
+
all_lists = [] # list - of - (command-list)
|
|
372
|
+
if self.has_dep_shell_commands:
|
|
373
|
+
all_lists = [
|
|
374
|
+
['./pre_compile_dep_shell_commands.sh']
|
|
375
|
+
]
|
|
376
|
+
|
|
377
|
+
if compile_lists:
|
|
378
|
+
util.write_shell_command_file(dirpath=self.args['work-dir'], filename='compile.sh',
|
|
379
|
+
command_lists=compile_lists,
|
|
380
|
+
line_breaks=compile_line_breaks)
|
|
381
|
+
all_lists.append(['./compile.sh'])
|
|
382
|
+
|
|
383
|
+
if elaborate_lists:
|
|
384
|
+
util.write_shell_command_file(dirpath=self.args['work-dir'], filename='elaborate.sh',
|
|
385
|
+
command_lists=elaborate_lists,
|
|
386
|
+
line_breaks=elaborate_line_breaks)
|
|
387
|
+
all_lists.append(['./elaborate.sh'])
|
|
388
|
+
|
|
389
|
+
if simulate_lists:
|
|
390
|
+
util.write_shell_command_file(dirpath=self.args['work-dir'], filename=simulate_sh_fname,
|
|
391
|
+
command_lists=simulate_lists,
|
|
392
|
+
line_breaks=simulate_line_breaks)
|
|
393
|
+
all_lists.append(['./' + simulate_sh_fname])
|
|
394
|
+
|
|
395
|
+
util.write_shell_command_file(dirpath=self.args['work-dir'], filename='all.sh',
|
|
396
|
+
command_lists=all_lists)
|
|
397
|
+
|
|
398
|
+
self.write_eda_config_and_args()
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
|
|
334
402
|
# Methods that derived classes must override:
|
|
335
403
|
|
|
336
404
|
def compile(self) -> None:
|
|
@@ -95,6 +95,7 @@ class CommandWaves(CommandDesign):
|
|
|
95
95
|
self.error(f"Was already given {wave_file=}, not sure what",
|
|
96
96
|
f"to do with {tokens[0]}")
|
|
97
97
|
wave_dirs.append(tokens[0])
|
|
98
|
+
self.warning_show_known_args()
|
|
98
99
|
self.error(f"Didn't understand command arg/token: '{tokens[0]}'",
|
|
99
100
|
"in CommandWaves")
|
|
100
101
|
|
|
@@ -15,7 +15,8 @@ from opencos.deps.defaults import DEPS_FILE_EXTS, ROOT_TABLE_KEYS_NOT_TARGETS
|
|
|
15
15
|
from opencos.util import debug, error
|
|
16
16
|
from opencos.utils.markup_helpers import yaml_safe_load, toml_load_only_root_line_numbers, \
|
|
17
17
|
markup_writer, markup_dumper
|
|
18
|
-
from opencos.utils.str_helpers import fnmatch_or_re, dep_str2list
|
|
18
|
+
from opencos.utils.str_helpers import fnmatch_or_re, dep_str2list, pretty_list_columns_manual, \
|
|
19
|
+
is_valid_target_name, VALID_TARGET_INFO_STR
|
|
19
20
|
from opencos.utils.subprocess_helpers import subprocess_run_background
|
|
20
21
|
from opencos.utils.status_constants import EDA_DEPS_FILE_NOT_FOUND, EDA_DEPS_TARGET_NOT_FOUND
|
|
21
22
|
|
|
@@ -24,7 +25,8 @@ def deps_data_get_all_targets(data: dict) -> list:
|
|
|
24
25
|
'''Given extracted DEPS data (dict) get all the root level keys that aren't defaults'''
|
|
25
26
|
if data is None:
|
|
26
27
|
return []
|
|
27
|
-
return [x for x in data.keys() if x not in ROOT_TABLE_KEYS_NOT_TARGETS
|
|
28
|
+
return [x for x in data.keys() if (x not in ROOT_TABLE_KEYS_NOT_TARGETS and
|
|
29
|
+
is_valid_target_name(x))]
|
|
28
30
|
|
|
29
31
|
|
|
30
32
|
def get_deps_markup_file(base_path: str) -> str:
|
|
@@ -272,6 +274,19 @@ class DepsFile:
|
|
|
272
274
|
self.get_approx_line_number_str(target)
|
|
273
275
|
])
|
|
274
276
|
|
|
277
|
+
|
|
278
|
+
def warning_show_available_targets(self) -> None:
|
|
279
|
+
'''call warning showing available targets (pretty column printed)'''
|
|
280
|
+
if not self.data or not self.rel_deps_file:
|
|
281
|
+
return
|
|
282
|
+
pretty_possible_targets = pretty_list_columns_manual(
|
|
283
|
+
data=deps_data_get_all_targets(self.data)
|
|
284
|
+
)
|
|
285
|
+
targets_str = " " + "\n ".join(pretty_possible_targets).strip()
|
|
286
|
+
util.warning((f'Targets available in deps_file={self.rel_deps_file}:\n'
|
|
287
|
+
f'{targets_str}'))
|
|
288
|
+
|
|
289
|
+
|
|
275
290
|
def lookup(self, target_node: str, caller_info: str) -> bool:
|
|
276
291
|
'''Returns True if the target_node is in the DEPS markup file. If not, error with
|
|
277
292
|
|
|
@@ -284,6 +299,15 @@ class DepsFile:
|
|
|
284
299
|
t_path = os.path.relpath(self.target_path) + os.path.sep
|
|
285
300
|
t_node = target_node
|
|
286
301
|
t_full = os.path.join(t_path, t_node)
|
|
302
|
+
|
|
303
|
+
if target_node.startswith('-'):
|
|
304
|
+
# likely an unparsed arg that made it this far.
|
|
305
|
+
util.warning(f"Ignoring unparsed argument '{target_node}'")
|
|
306
|
+
return False
|
|
307
|
+
|
|
308
|
+
if not is_valid_target_name(target_node):
|
|
309
|
+
util.warning(f"In file {self.rel_deps_file}, {target_node} {VALID_TARGET_INFO_STR}")
|
|
310
|
+
|
|
287
311
|
if not caller_info:
|
|
288
312
|
# If we don't have caller_info, likely came from command line (or DEPS JSON data):
|
|
289
313
|
if '.' in target_node:
|
|
@@ -297,10 +321,11 @@ class DepsFile:
|
|
|
297
321
|
f'but path {t_path} has no DEPS markup file (DEPS.yml)',
|
|
298
322
|
error_code=EDA_DEPS_FILE_NOT_FOUND)
|
|
299
323
|
else:
|
|
324
|
+
self.warning_show_available_targets()
|
|
300
325
|
self.error(f'Trying to resolve command-line target={t_full}:',
|
|
301
|
-
f'was not found in deps_file={self.rel_deps_file}
|
|
302
|
-
f'possible targets in deps file = {list(self.data.keys())}',
|
|
326
|
+
f'was not found in deps_file={self.rel_deps_file}',
|
|
303
327
|
error_code=EDA_DEPS_TARGET_NOT_FOUND)
|
|
328
|
+
|
|
304
329
|
else:
|
|
305
330
|
# If we have caller_info, then this was a recursive call from another
|
|
306
331
|
# DEPS file. It should already have the useful error messaging:
|
|
@@ -318,6 +343,7 @@ class DepsFile:
|
|
|
318
343
|
f'but {t_path} has no DEPS markup file (DEPS.yml)',
|
|
319
344
|
error_code=EDA_DEPS_FILE_NOT_FOUND)
|
|
320
345
|
else:
|
|
346
|
+
self.warning_show_available_targets()
|
|
321
347
|
self.error(f'Trying to resolve target={t_full}:',
|
|
322
348
|
f'called from {caller_info},',
|
|
323
349
|
f'Target not found in deps_file={self.rel_deps_file}',
|