devlab-fpga 0.1.0__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.
- devlab_fpga-0.1.0/LICENSE +21 -0
- devlab_fpga-0.1.0/MANIFEST.in +2 -0
- devlab_fpga-0.1.0/PKG-INFO +188 -0
- devlab_fpga-0.1.0/README.md +164 -0
- devlab_fpga-0.1.0/devlab/__init__.py +6 -0
- devlab_fpga-0.1.0/devlab/__main__.py +5 -0
- devlab_fpga-0.1.0/devlab/cli.py +170 -0
- devlab_fpga-0.1.0/devlab/errors.py +3 -0
- devlab_fpga-0.1.0/devlab/platforms.py +40 -0
- devlab_fpga-0.1.0/devlab/project.py +430 -0
- devlab_fpga-0.1.0/devlab/toolchain.py +242 -0
- devlab_fpga-0.1.0/devlab_fpga.egg-info/PKG-INFO +188 -0
- devlab_fpga-0.1.0/devlab_fpga.egg-info/SOURCES.txt +18 -0
- devlab_fpga-0.1.0/devlab_fpga.egg-info/dependency_links.txt +1 -0
- devlab_fpga-0.1.0/devlab_fpga.egg-info/entry_points.txt +2 -0
- devlab_fpga-0.1.0/devlab_fpga.egg-info/requires.txt +3 -0
- devlab_fpga-0.1.0/devlab_fpga.egg-info/top_level.txt +1 -0
- devlab_fpga-0.1.0/pyproject.toml +39 -0
- devlab_fpga-0.1.0/setup.cfg +4 -0
- devlab_fpga-0.1.0/setup.py +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mrju10
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: devlab-fpga
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: FPGA development helper for installing OSS CAD Suite and running build/flash flows.
|
|
5
|
+
Author-email: Mrju10 <name@email.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/unit-electronics/unit_devlab_lib
|
|
8
|
+
Project-URL: Source, https://github.com/unit-electronics/unit_devlab_lib
|
|
9
|
+
Keywords: fpga,yosys,oss-cad-suite,openfpgaloader,devlab,devlab-fpga
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Operating System :: MacOS
|
|
14
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
15
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: tomli>=2.0.1; python_version < "3.11"
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# devlab
|
|
26
|
+
|
|
27
|
+
`devlab` is a Python CLI package for FPGA development. It installs the
|
|
28
|
+
matching OSS CAD Suite build for the current operating system, creates a small
|
|
29
|
+
FPGA project, and runs build/flash commands from `devlab.toml`.
|
|
30
|
+
|
|
31
|
+
## Install
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install devlab-fpga
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
For local development from this repository:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install -e .
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Commands
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
devlab doctor
|
|
47
|
+
devlab install
|
|
48
|
+
devlab new blink
|
|
49
|
+
devlab new blink-vhdl --hdl vhdl
|
|
50
|
+
cd blink
|
|
51
|
+
devlab build
|
|
52
|
+
devlab flash
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`devlab install` downloads OSS CAD Suite release `2026-07-06` from
|
|
56
|
+
YosysHQ. The installer selects the correct asset for:
|
|
57
|
+
|
|
58
|
+
- Linux x64
|
|
59
|
+
- Linux arm64
|
|
60
|
+
- macOS x64
|
|
61
|
+
- macOS arm64
|
|
62
|
+
- Windows x64
|
|
63
|
+
|
|
64
|
+
The default install location is `~/.devlab`. Set `DEVLAB_HOME` to use a
|
|
65
|
+
different directory.
|
|
66
|
+
|
|
67
|
+
## OSS CAD Suite Source
|
|
68
|
+
|
|
69
|
+
Default release:
|
|
70
|
+
|
|
71
|
+
https://github.com/YosysHQ/oss-cad-suite-build/releases/tag/2026-07-06
|
|
72
|
+
|
|
73
|
+
Example assets:
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
https://github.com/YosysHQ/oss-cad-suite-build/releases/download/2026-07-06/oss-cad-suite-linux-arm64-20260706.tgz
|
|
77
|
+
https://github.com/YosysHQ/oss-cad-suite-build/releases/download/2026-07-06/oss-cad-suite-windows-x64-20260706.exe
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Downloaded archives are verified with the SHA-256 digest published by the
|
|
81
|
+
GitHub release API.
|
|
82
|
+
|
|
83
|
+
## Project Format
|
|
84
|
+
|
|
85
|
+
`devlab new blink` creates:
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
blink/
|
|
89
|
+
devlab.toml
|
|
90
|
+
pins.cst
|
|
91
|
+
src/top.v
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Use `--hdl vhdl` to create `src/top.vhd` instead:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
devlab new blink-vhdl --hdl vhdl
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Default `devlab.toml`:
|
|
101
|
+
|
|
102
|
+
```toml
|
|
103
|
+
[fpga]
|
|
104
|
+
family = "GW1N-9C"
|
|
105
|
+
device = "GW1NR-LV9QN88PC6/I5"
|
|
106
|
+
cst = "pins.cst"
|
|
107
|
+
|
|
108
|
+
[build]
|
|
109
|
+
top = "top"
|
|
110
|
+
sources = ["src/top.v"]
|
|
111
|
+
constraints = "pins.cst"
|
|
112
|
+
build_dir = "build"
|
|
113
|
+
|
|
114
|
+
[flash]
|
|
115
|
+
board = "tangnano9k"
|
|
116
|
+
mode = "sram"
|
|
117
|
+
verify = false
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
For Gowin, `family` is the FPGA series used by the packer and place-and-route
|
|
121
|
+
flow, for example `GW1N-9C`. `device` is the complete part number, for example
|
|
122
|
+
`GW1NR-LV9QN88PC6/I5`. `pins.cst` is the Gowin constraints file.
|
|
123
|
+
|
|
124
|
+
Update `pins.cst` and `[flash].board` for the real FPGA board before building
|
|
125
|
+
and flashing hardware.
|
|
126
|
+
|
|
127
|
+
## Build Flows
|
|
128
|
+
|
|
129
|
+
For Gowin `GW1N-9C` / `GW1NR-LV9QN88PC6/I5`, `devlab build` runs:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
yosys
|
|
133
|
+
nextpnr-himbaechel
|
|
134
|
+
gowin_pack
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
The iCE40 and ECP5 flows are still available by setting `family = "ice40"` or
|
|
138
|
+
`family = "ecp5"` in `devlab.toml`.
|
|
139
|
+
|
|
140
|
+
For iCE40, it runs:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
yosys
|
|
144
|
+
nextpnr-ice40
|
|
145
|
+
icepack
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
`devlab flash` uses `openFPGALoader`. By default it writes SRAM, so the FPGA
|
|
149
|
+
loses the design after power cycling. Use flash mode to write the bitstream to
|
|
150
|
+
non-volatile memory:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
devlab flash --mode flash
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Before writing flash on board variants where flash may or may not be populated,
|
|
157
|
+
run detection:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
devlab flash --detect
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Persistent flash can also be configured in `devlab.toml`:
|
|
164
|
+
|
|
165
|
+
```toml
|
|
166
|
+
[flash]
|
|
167
|
+
board = "tangnano9k"
|
|
168
|
+
mode = "flash"
|
|
169
|
+
verify = false
|
|
170
|
+
# external_flash = true
|
|
171
|
+
# offset = "0"
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
For Tang Nano 9K/Gowin, flash write verification may print
|
|
175
|
+
`writing verification not supported` and fail the CRC check even when the flash
|
|
176
|
+
write completed. Keep `verify = false` unless the selected board/programming
|
|
177
|
+
path explicitly supports flash verification.
|
|
178
|
+
|
|
179
|
+
When sources end in `.vhd` or `.vhdl`, `devlab build` runs Yosys with the
|
|
180
|
+
GHDL plugin before synthesis. OSS CAD Suite is expected to provide that plugin.
|
|
181
|
+
|
|
182
|
+
Use `--dry-run` to print the commands without executing them:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
devlab build --dry-run
|
|
186
|
+
devlab flash --dry-run --board tangnano9k
|
|
187
|
+
devlab flash --dry-run --mode flash
|
|
188
|
+
```
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# devlab
|
|
2
|
+
|
|
3
|
+
`devlab` is a Python CLI package for FPGA development. It installs the
|
|
4
|
+
matching OSS CAD Suite build for the current operating system, creates a small
|
|
5
|
+
FPGA project, and runs build/flash commands from `devlab.toml`.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install devlab-fpga
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
For local development from this repository:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install -e .
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Commands
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
devlab doctor
|
|
23
|
+
devlab install
|
|
24
|
+
devlab new blink
|
|
25
|
+
devlab new blink-vhdl --hdl vhdl
|
|
26
|
+
cd blink
|
|
27
|
+
devlab build
|
|
28
|
+
devlab flash
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`devlab install` downloads OSS CAD Suite release `2026-07-06` from
|
|
32
|
+
YosysHQ. The installer selects the correct asset for:
|
|
33
|
+
|
|
34
|
+
- Linux x64
|
|
35
|
+
- Linux arm64
|
|
36
|
+
- macOS x64
|
|
37
|
+
- macOS arm64
|
|
38
|
+
- Windows x64
|
|
39
|
+
|
|
40
|
+
The default install location is `~/.devlab`. Set `DEVLAB_HOME` to use a
|
|
41
|
+
different directory.
|
|
42
|
+
|
|
43
|
+
## OSS CAD Suite Source
|
|
44
|
+
|
|
45
|
+
Default release:
|
|
46
|
+
|
|
47
|
+
https://github.com/YosysHQ/oss-cad-suite-build/releases/tag/2026-07-06
|
|
48
|
+
|
|
49
|
+
Example assets:
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
https://github.com/YosysHQ/oss-cad-suite-build/releases/download/2026-07-06/oss-cad-suite-linux-arm64-20260706.tgz
|
|
53
|
+
https://github.com/YosysHQ/oss-cad-suite-build/releases/download/2026-07-06/oss-cad-suite-windows-x64-20260706.exe
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Downloaded archives are verified with the SHA-256 digest published by the
|
|
57
|
+
GitHub release API.
|
|
58
|
+
|
|
59
|
+
## Project Format
|
|
60
|
+
|
|
61
|
+
`devlab new blink` creates:
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
blink/
|
|
65
|
+
devlab.toml
|
|
66
|
+
pins.cst
|
|
67
|
+
src/top.v
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Use `--hdl vhdl` to create `src/top.vhd` instead:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
devlab new blink-vhdl --hdl vhdl
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Default `devlab.toml`:
|
|
77
|
+
|
|
78
|
+
```toml
|
|
79
|
+
[fpga]
|
|
80
|
+
family = "GW1N-9C"
|
|
81
|
+
device = "GW1NR-LV9QN88PC6/I5"
|
|
82
|
+
cst = "pins.cst"
|
|
83
|
+
|
|
84
|
+
[build]
|
|
85
|
+
top = "top"
|
|
86
|
+
sources = ["src/top.v"]
|
|
87
|
+
constraints = "pins.cst"
|
|
88
|
+
build_dir = "build"
|
|
89
|
+
|
|
90
|
+
[flash]
|
|
91
|
+
board = "tangnano9k"
|
|
92
|
+
mode = "sram"
|
|
93
|
+
verify = false
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
For Gowin, `family` is the FPGA series used by the packer and place-and-route
|
|
97
|
+
flow, for example `GW1N-9C`. `device` is the complete part number, for example
|
|
98
|
+
`GW1NR-LV9QN88PC6/I5`. `pins.cst` is the Gowin constraints file.
|
|
99
|
+
|
|
100
|
+
Update `pins.cst` and `[flash].board` for the real FPGA board before building
|
|
101
|
+
and flashing hardware.
|
|
102
|
+
|
|
103
|
+
## Build Flows
|
|
104
|
+
|
|
105
|
+
For Gowin `GW1N-9C` / `GW1NR-LV9QN88PC6/I5`, `devlab build` runs:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
yosys
|
|
109
|
+
nextpnr-himbaechel
|
|
110
|
+
gowin_pack
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The iCE40 and ECP5 flows are still available by setting `family = "ice40"` or
|
|
114
|
+
`family = "ecp5"` in `devlab.toml`.
|
|
115
|
+
|
|
116
|
+
For iCE40, it runs:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
yosys
|
|
120
|
+
nextpnr-ice40
|
|
121
|
+
icepack
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`devlab flash` uses `openFPGALoader`. By default it writes SRAM, so the FPGA
|
|
125
|
+
loses the design after power cycling. Use flash mode to write the bitstream to
|
|
126
|
+
non-volatile memory:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
devlab flash --mode flash
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Before writing flash on board variants where flash may or may not be populated,
|
|
133
|
+
run detection:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
devlab flash --detect
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Persistent flash can also be configured in `devlab.toml`:
|
|
140
|
+
|
|
141
|
+
```toml
|
|
142
|
+
[flash]
|
|
143
|
+
board = "tangnano9k"
|
|
144
|
+
mode = "flash"
|
|
145
|
+
verify = false
|
|
146
|
+
# external_flash = true
|
|
147
|
+
# offset = "0"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
For Tang Nano 9K/Gowin, flash write verification may print
|
|
151
|
+
`writing verification not supported` and fail the CRC check even when the flash
|
|
152
|
+
write completed. Keep `verify = false` unless the selected board/programming
|
|
153
|
+
path explicitly supports flash verification.
|
|
154
|
+
|
|
155
|
+
When sources end in `.vhd` or `.vhdl`, `devlab build` runs Yosys with the
|
|
156
|
+
GHDL plugin before synthesis. OSS CAD Suite is expected to provide that plugin.
|
|
157
|
+
|
|
158
|
+
Use `--dry-run` to print the commands without executing them:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
devlab build --dry-run
|
|
162
|
+
devlab flash --dry-run --board tangnano9k
|
|
163
|
+
devlab flash --dry-run --mode flash
|
|
164
|
+
```
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import platform
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from . import __version__
|
|
8
|
+
from .errors import DevlabError
|
|
9
|
+
from .platforms import current_platform
|
|
10
|
+
from .project import build_project, create_project, detect_flash, doctor, flash_project
|
|
11
|
+
from .toolchain import (
|
|
12
|
+
OSS_CAD_SUITE_RELEASE_URL,
|
|
13
|
+
archive_path,
|
|
14
|
+
devlab_home,
|
|
15
|
+
install_oss_cad_suite,
|
|
16
|
+
install_path,
|
|
17
|
+
select_asset,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
22
|
+
parser = argparse.ArgumentParser(
|
|
23
|
+
prog="devlab",
|
|
24
|
+
description="Install FPGA toolchains and run local FPGA build flows.",
|
|
25
|
+
)
|
|
26
|
+
parser.add_argument("--version", action="version", version=f"devlab {__version__}")
|
|
27
|
+
|
|
28
|
+
commands = parser.add_subparsers(dest="command", required=True)
|
|
29
|
+
|
|
30
|
+
doctor_parser = commands.add_parser("doctor", help="Check local FPGA tools.")
|
|
31
|
+
doctor_parser.add_argument(
|
|
32
|
+
"--strict",
|
|
33
|
+
action="store_true",
|
|
34
|
+
help="Exit 1 when a tool is missing.",
|
|
35
|
+
)
|
|
36
|
+
doctor_parser.set_defaults(func=_doctor)
|
|
37
|
+
|
|
38
|
+
install_parser = commands.add_parser("install", help="Install OSS CAD Suite.")
|
|
39
|
+
install_parser.add_argument("--force", action="store_true", help="Re-download and reinstall.")
|
|
40
|
+
install_parser.add_argument(
|
|
41
|
+
"--run-installer",
|
|
42
|
+
action="store_true",
|
|
43
|
+
help="On Windows, execute the downloaded OSS CAD Suite installer.",
|
|
44
|
+
)
|
|
45
|
+
install_parser.set_defaults(func=_install)
|
|
46
|
+
|
|
47
|
+
new_parser = commands.add_parser("new", help="Create a new FPGA project.")
|
|
48
|
+
new_parser.add_argument("name", help="Project directory name.")
|
|
49
|
+
new_parser.add_argument("--dir", type=Path, help="Target directory. Defaults to NAME.")
|
|
50
|
+
new_parser.add_argument("--force", action="store_true", help="Overwrite template files.")
|
|
51
|
+
new_parser.add_argument(
|
|
52
|
+
"--hdl",
|
|
53
|
+
choices=("verilog", "vhdl"),
|
|
54
|
+
default="verilog",
|
|
55
|
+
help="Source template language. Defaults to verilog.",
|
|
56
|
+
)
|
|
57
|
+
new_parser.set_defaults(func=_new)
|
|
58
|
+
|
|
59
|
+
build = commands.add_parser("build", help="Build the current FPGA project.")
|
|
60
|
+
build.add_argument("-c", "--config", type=Path, help="Path to devlab.toml.")
|
|
61
|
+
build.add_argument(
|
|
62
|
+
"--dry-run",
|
|
63
|
+
action="store_true",
|
|
64
|
+
help="Print commands without running them.",
|
|
65
|
+
)
|
|
66
|
+
build.set_defaults(func=_build)
|
|
67
|
+
|
|
68
|
+
flash = commands.add_parser("flash", help="Flash the built FPGA bitstream.")
|
|
69
|
+
flash.add_argument("-c", "--config", type=Path, help="Path to devlab.toml.")
|
|
70
|
+
flash.add_argument("--board", help="openFPGALoader board name.")
|
|
71
|
+
flash.add_argument("--artifact", type=Path, help="Bitstream path.")
|
|
72
|
+
flash.add_argument(
|
|
73
|
+
"--mode",
|
|
74
|
+
choices=("sram", "flash"),
|
|
75
|
+
help="Write target. sram is temporary; flash is persistent after reboot.",
|
|
76
|
+
)
|
|
77
|
+
flash.add_argument(
|
|
78
|
+
"--detect",
|
|
79
|
+
action="store_true",
|
|
80
|
+
help="Detect FPGA and flash support without writing a bitstream.",
|
|
81
|
+
)
|
|
82
|
+
flash.add_argument(
|
|
83
|
+
"--verify",
|
|
84
|
+
action="store_true",
|
|
85
|
+
help="Verify flash write when supported by the board/programming path.",
|
|
86
|
+
)
|
|
87
|
+
flash.add_argument(
|
|
88
|
+
"--no-verify",
|
|
89
|
+
action="store_true",
|
|
90
|
+
help="Skip flash verification when using --mode flash.",
|
|
91
|
+
)
|
|
92
|
+
flash.add_argument(
|
|
93
|
+
"--external-flash",
|
|
94
|
+
action="store_true",
|
|
95
|
+
help="Use external flash when the device has internal and external storage.",
|
|
96
|
+
)
|
|
97
|
+
flash.add_argument("--offset", help="Flash offset in bytes.")
|
|
98
|
+
flash.add_argument("--dry-run", action="store_true", help="Print command without running it.")
|
|
99
|
+
flash.set_defaults(func=_flash)
|
|
100
|
+
|
|
101
|
+
return parser
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def main(argv: list[str] | None = None) -> int:
|
|
105
|
+
parser = build_parser()
|
|
106
|
+
args = parser.parse_args(argv)
|
|
107
|
+
try:
|
|
108
|
+
return args.func(args)
|
|
109
|
+
except DevlabError as exc:
|
|
110
|
+
parser.exit(2, f"devlab: error: {exc}\n")
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _doctor(args: argparse.Namespace) -> int:
|
|
114
|
+
platform_id = current_platform()
|
|
115
|
+
asset = select_asset(platform_id)
|
|
116
|
+
print(f"devlab: {__version__}")
|
|
117
|
+
print(f"python: {platform.python_version()} ({platform.python_implementation()})")
|
|
118
|
+
print(f"platform: {platform_id.key}")
|
|
119
|
+
print(f"home: {devlab_home()}")
|
|
120
|
+
print(f"release: {OSS_CAD_SUITE_RELEASE_URL}")
|
|
121
|
+
print(f"asset: {asset.name}")
|
|
122
|
+
print(f"archive: {archive_path(asset)}")
|
|
123
|
+
print(f"toolchain: {install_path(asset)}")
|
|
124
|
+
return doctor(strict=args.strict)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def _install(args: argparse.Namespace) -> int:
|
|
128
|
+
destination = install_oss_cad_suite(
|
|
129
|
+
force=args.force,
|
|
130
|
+
run_windows_installer=args.run_installer,
|
|
131
|
+
)
|
|
132
|
+
print(f"OSS CAD Suite installed at {destination}")
|
|
133
|
+
return 0
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _new(args: argparse.Namespace) -> int:
|
|
137
|
+
root = create_project(args.name, directory=args.dir, force=args.force, hdl=args.hdl)
|
|
138
|
+
print(f"Created FPGA project at {root}")
|
|
139
|
+
return 0
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def _build(args: argparse.Namespace) -> int:
|
|
143
|
+
artifact = build_project(config_path=args.config, dry_run=args.dry_run)
|
|
144
|
+
print(f"Build artifact: {artifact}")
|
|
145
|
+
return 0
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def _flash(args: argparse.Namespace) -> int:
|
|
149
|
+
if args.verify and args.no_verify:
|
|
150
|
+
raise DevlabError("--verify and --no-verify cannot be used together.")
|
|
151
|
+
|
|
152
|
+
if args.detect:
|
|
153
|
+
detect_flash(
|
|
154
|
+
config_path=args.config,
|
|
155
|
+
board=args.board,
|
|
156
|
+
dry_run=args.dry_run,
|
|
157
|
+
)
|
|
158
|
+
return 0
|
|
159
|
+
|
|
160
|
+
flash_project(
|
|
161
|
+
config_path=args.config,
|
|
162
|
+
board=args.board,
|
|
163
|
+
artifact=args.artifact,
|
|
164
|
+
mode=args.mode,
|
|
165
|
+
verify=True if args.verify else False if args.no_verify else None,
|
|
166
|
+
external_flash=True if args.external_flash else None,
|
|
167
|
+
offset=args.offset,
|
|
168
|
+
dry_run=args.dry_run,
|
|
169
|
+
)
|
|
170
|
+
return 0
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import platform
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from .errors import DevlabError
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass(frozen=True)
|
|
10
|
+
class PlatformId:
|
|
11
|
+
os_name: str
|
|
12
|
+
arch: str
|
|
13
|
+
|
|
14
|
+
@property
|
|
15
|
+
def key(self) -> str:
|
|
16
|
+
return f"{self.os_name}-{self.arch}"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def current_platform() -> PlatformId:
|
|
20
|
+
system = platform.system().lower()
|
|
21
|
+
machine = platform.machine().lower()
|
|
22
|
+
|
|
23
|
+
if system == "linux":
|
|
24
|
+
os_name = "linux"
|
|
25
|
+
elif system == "darwin":
|
|
26
|
+
os_name = "darwin"
|
|
27
|
+
elif system in {"windows", "msys", "cygwin"}:
|
|
28
|
+
os_name = "windows"
|
|
29
|
+
else:
|
|
30
|
+
raise DevlabError(f"Unsupported operating system: {platform.system()}")
|
|
31
|
+
|
|
32
|
+
if machine in {"x86_64", "amd64"}:
|
|
33
|
+
arch = "x64"
|
|
34
|
+
elif machine in {"aarch64", "arm64"}:
|
|
35
|
+
arch = "arm64"
|
|
36
|
+
else:
|
|
37
|
+
raise DevlabError(f"Unsupported CPU architecture: {platform.machine()}")
|
|
38
|
+
|
|
39
|
+
return PlatformId(os_name=os_name, arch=arch)
|
|
40
|
+
|