openspacehdl 0.0.1__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.
@@ -0,0 +1,3 @@
1
+ """Open Space HDL: open-source VHDL IP cores for spacecraft on-board data handling."""
2
+
3
+ __version__ = "0.0.1"
@@ -0,0 +1,7 @@
1
+ """Entry point of python -m openspacehdl."""
2
+
3
+ import sys
4
+
5
+ from openspacehdl.cli import main
6
+
7
+ sys.exit(main())
openspacehdl/cli.py ADDED
@@ -0,0 +1,75 @@
1
+ """Command line of openspacehdl."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import sys
7
+ import textwrap
8
+
9
+ from openspacehdl import __version__
10
+ from openspacehdl.family import Family, Project, load
11
+
12
+ WIDTH = 100
13
+ INDENT = " "
14
+
15
+
16
+ def _wrap(text: str, indent: str) -> list[str]:
17
+ return textwrap.wrap(text, WIDTH, initial_indent=indent, subsequent_indent=indent)
18
+
19
+
20
+ def _project_lines(family: Family, p: Project) -> list[str]:
21
+ state = "Coming soon" if not p.public else (f"TRL {p.trl}" if p.trl else "")
22
+ head = " ".join(x for x in (p.name, state) if x)
23
+ lines = [f" {head}"]
24
+ if p.tagline:
25
+ lines.append(f"{INDENT}{', '.join(p.tagline)}")
26
+ lines += _wrap(p.summary, INDENT)
27
+ if p.public:
28
+ if p.trl and p.trl_status:
29
+ lines += _wrap(f"Status: {p.trl_status}", INDENT)
30
+ docs = family.docs_url(p)
31
+ if docs:
32
+ lines.append(f"{INDENT}Documentation: {docs}")
33
+ lines.append(f"{INDENT}Source: {family.source_url(p)}")
34
+ return lines
35
+
36
+
37
+ def info(family: Family, name: str | None) -> int:
38
+ if name is not None:
39
+ p = family.find(name)
40
+ if p is None:
41
+ names = ", ".join(x.name for x in family.projects)
42
+ print(f"openspacehdl: no project named {name!r}; the family has {names}", file=sys.stderr)
43
+ return 2
44
+ print("\n".join(_project_lines(family, p)))
45
+ return 0
46
+
47
+ out = ["Open Space HDL: open-source VHDL IP cores for spacecraft on-board data handling", family.site]
48
+ for g in family.groups:
49
+ members = family.members(g)
50
+ if not members:
51
+ continue
52
+ out += ["", g.title, *_wrap(g.summary, " ")]
53
+ for p in members:
54
+ out += ["", *_project_lines(family, p)]
55
+ print("\n".join(out))
56
+ return 0
57
+
58
+
59
+ def main(argv: list[str] | None = None) -> int:
60
+ if hasattr(sys.stdout, "reconfigure"):
61
+ sys.stdout.reconfigure(errors="replace")
62
+ parser = argparse.ArgumentParser(
63
+ prog="openspacehdl",
64
+ description="Open Space HDL: open-source VHDL IP cores for spacecraft on-board data handling.",
65
+ )
66
+ parser.add_argument("--version", action="version", version=f"openspacehdl {__version__}")
67
+ sub = parser.add_subparsers(dest="command", metavar="<command>")
68
+ p_info = sub.add_parser("info", help="list the projects of the family, as the website shows them")
69
+ p_info.add_argument("project", nargs="?", help="show only this project (name or repository)")
70
+ args = parser.parse_args(argv)
71
+
72
+ if args.command == "info":
73
+ return info(load(), args.project)
74
+ parser.print_help()
75
+ return 0
@@ -0,0 +1,158 @@
1
+ {
2
+ "source": {
3
+ "repository": "open-space-hdl/open-space-hdl.github.io",
4
+ "commit": "1b3d619cb4b4cef3fe7a3893a0d0040c1d4049bb"
5
+ },
6
+ "site": "https://openspacehdl.org",
7
+ "github": "https://github.com/open-space-hdl",
8
+ "groups": [
9
+ {
10
+ "id": "interfaces-protocols",
11
+ "title": "Interfaces & Protocols",
12
+ "summary": "SpaceWire and SpaceFibre links, CAN and 1553 buses, and the protocols that run over them."
13
+ },
14
+ {
15
+ "id": "processing-modules",
16
+ "title": "Processing Modules",
17
+ "summary": "Cores that process payload data on board, such as image compression and encryption."
18
+ },
19
+ {
20
+ "id": "system-infrastructure",
21
+ "title": "System Infrastructure",
22
+ "summary": "Cores that move data between the memories and the peripherals of an on-board system."
23
+ },
24
+ {
25
+ "id": "building-blocks",
26
+ "title": "Building Blocks",
27
+ "summary": "The fault-tolerant Open Logic entities that every core is built on."
28
+ }
29
+ ],
30
+ "projects": [
31
+ {
32
+ "name": "OpenWire",
33
+ "group": "interfaces-protocols",
34
+ "tagline": [
35
+ "ECSS-E-ST-50-12C Rev.1"
36
+ ],
37
+ "summary": "SpaceWire port with node interface: Data-Strobe encoding, link control, packets, time-codes and distributed interrupts.",
38
+ "public": true,
39
+ "repo": "openwire",
40
+ "docs": true,
41
+ "trl": 3,
42
+ "trl_status": "Fully verified by simulation. Not yet tested on hardware, no flight heritage."
43
+ },
44
+ {
45
+ "name": "OpenFibre",
46
+ "group": "interfaces-protocols",
47
+ "tagline": [
48
+ "ECSS-E-ST-50-11C"
49
+ ],
50
+ "summary": "SpaceFibre port with 1 to 4 lanes, up to 32 virtual channels, quality of service, broadcast and error recovery.",
51
+ "public": true,
52
+ "repo": "openfibre",
53
+ "docs": true,
54
+ "trl": 3,
55
+ "trl_status": "Fully verified by simulation. Not yet tested on hardware, no flight heritage."
56
+ },
57
+ {
58
+ "name": "OpenRMAP",
59
+ "group": "interfaces-protocols",
60
+ "tagline": [
61
+ "ECSS-E-ST-50-52C"
62
+ ],
63
+ "summary": "RMAP target and initiator for reading and writing remote memory over SpaceWire and SpaceFibre networks.",
64
+ "public": true,
65
+ "repo": "openrmap",
66
+ "docs": true,
67
+ "trl": 3,
68
+ "trl_status": "Fully verified by simulation. Not yet tested on hardware, no flight heritage."
69
+ },
70
+ {
71
+ "name": "OpenSPP",
72
+ "group": "interfaces-protocols",
73
+ "tagline": [
74
+ "CCSDS 133.0-B-2"
75
+ ],
76
+ "summary": "Space Packet service with APID routing and loss detection for up to 16 send and 16 receive ports, over SpaceWire, SpaceFibre or other links.",
77
+ "public": true,
78
+ "repo": "openspp",
79
+ "docs": true,
80
+ "trl": 3,
81
+ "trl_status": "Fully verified by simulation. Not yet tested on hardware, no flight heritage."
82
+ },
83
+ {
84
+ "name": "OpenCAN",
85
+ "group": "interfaces-protocols",
86
+ "tagline": [
87
+ "ECSS-E-ST-50-15C"
88
+ ],
89
+ "summary": "CAN network core with nominal and redundant bus, bus redundancy management, CANopen services and time distribution.",
90
+ "public": false
91
+ },
92
+ {
93
+ "name": "Open1553",
94
+ "group": "interfaces-protocols",
95
+ "tagline": [
96
+ "ECSS-E-ST-50-13C"
97
+ ],
98
+ "summary": "Bus controller, remote terminal and bus monitor for the dual-redundant 1553 data bus, with the Manchester II codec in the core.",
99
+ "public": false
100
+ },
101
+ {
102
+ "name": "OpenCompact",
103
+ "group": "processing-modules",
104
+ "tagline": [
105
+ "CCSDS 123.0-B-2"
106
+ ],
107
+ "summary": "Lossless and near-lossless compressor for multispectral and hyperspectral images, with all predictors and entropy coders of the standard.",
108
+ "public": true,
109
+ "repo": "opencompact",
110
+ "docs": true,
111
+ "trl": 3,
112
+ "trl_status": "Fully verified by simulation. Not yet tested on hardware, no flight heritage."
113
+ },
114
+ {
115
+ "name": "OpenCrypto",
116
+ "group": "processing-modules",
117
+ "tagline": [
118
+ "CCSDS 352.0-B-2"
119
+ ],
120
+ "summary": "Authenticated encryption and decryption of real-time data streams with AES-GCM, key table and IV generation.",
121
+ "public": true,
122
+ "repo": "opencrypto",
123
+ "docs": true,
124
+ "trl": 3,
125
+ "trl_status": "Fully verified by simulation. Not yet tested on hardware, no flight heritage."
126
+ },
127
+ {
128
+ "name": "OpenDMA",
129
+ "group": "system-infrastructure",
130
+ "tagline": [
131
+ "AXI4",
132
+ "AXI4-Stream",
133
+ "Scatter/Gather"
134
+ ],
135
+ "summary": "DMA core between AXI4 memory and AXI4-Stream peripherals, register-compatible with the AMD AXI DMA so that its drivers run unchanged.",
136
+ "public": true,
137
+ "repo": "opendma",
138
+ "docs": true,
139
+ "trl": 3,
140
+ "trl_status": "Fully verified by simulation. Not yet tested on hardware, no flight heritage."
141
+ },
142
+ {
143
+ "name": "Open Logic FT",
144
+ "group": "building-blocks",
145
+ "tagline": [
146
+ "ECC",
147
+ "TMR",
148
+ "Safe FSMs"
149
+ ],
150
+ "summary": "Fault-tolerant fork of Open Logic: RAMs and FIFOs with SECDED ECC, clock crossings with triplicated synchronisers.",
151
+ "public": true,
152
+ "repo": "open-logic-ft",
153
+ "docs": true,
154
+ "trl": 3,
155
+ "trl_status": "Fully verified by simulation. Not yet tested on hardware, no flight heritage."
156
+ }
157
+ ]
158
+ }
openspacehdl/family.py ADDED
@@ -0,0 +1,71 @@
1
+ """The projects of the family, as the website shows them (data/family.json, written by tools/family_data.py)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import re
7
+ from dataclasses import dataclass
8
+ from importlib import resources
9
+
10
+
11
+ @dataclass(frozen=True)
12
+ class Group:
13
+ id: str
14
+ title: str
15
+ summary: str
16
+
17
+
18
+ @dataclass(frozen=True)
19
+ class Project:
20
+ name: str
21
+ group: str
22
+ tagline: tuple[str, ...]
23
+ summary: str
24
+ public: bool
25
+ repo: str | None = None
26
+ docs: bool = False
27
+ trl: int | None = None
28
+ trl_status: str | None = None
29
+
30
+
31
+ @dataclass(frozen=True)
32
+ class Family:
33
+ site: str
34
+ github: str
35
+ source_commit: str
36
+ groups: tuple[Group, ...]
37
+ projects: tuple[Project, ...]
38
+
39
+ def docs_url(self, project: Project) -> str | None:
40
+ """Documentation site of a public project, or None."""
41
+ return f"{self.site}/{project.repo}/" if project.public and project.docs else None
42
+
43
+ def source_url(self, project: Project) -> str | None:
44
+ """Repository of a public project, or None."""
45
+ return f"{self.github}/{project.repo}" if project.public else None
46
+
47
+ def members(self, group: Group) -> list[Project]:
48
+ return [p for p in self.projects if p.group == group.id]
49
+
50
+ def find(self, name: str) -> Project | None:
51
+ """The project with this name or repository name, ignoring case, spaces and hyphens."""
52
+ key = _key(name)
53
+ for p in self.projects:
54
+ if key in (_key(p.name), _key(p.repo or "")):
55
+ return p
56
+ return None
57
+
58
+
59
+ def _key(text: str) -> str:
60
+ return re.sub(r"[^a-z0-9]", "", text.lower())
61
+
62
+
63
+ def load() -> Family:
64
+ data = json.loads(resources.files("openspacehdl").joinpath("data/family.json").read_text(encoding="utf-8"))
65
+ return Family(
66
+ site=data["site"],
67
+ github=data["github"],
68
+ source_commit=data["source"]["commit"],
69
+ groups=tuple(Group(**g) for g in data["groups"]),
70
+ projects=tuple(Project(**{**p, "tagline": tuple(p["tagline"])}) for p in data["projects"]),
71
+ )
@@ -0,0 +1,77 @@
1
+ Metadata-Version: 2.4
2
+ Name: openspacehdl
3
+ Version: 0.0.1
4
+ Summary: Open Space HDL, open-source VHDL IP cores for spacecraft on-board data handling: early release that lists the family
5
+ Author-email: Julian Schneider <julian.schneider@openspacehdl.org>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://openspacehdl.org
8
+ Keywords: vhdl,fpga,ip-core,space,spacewire,spacefibre,ccsds,ecss
9
+ Classifier: Development Status :: 2 - Pre-Alpha
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3 :: Only
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Dynamic: license-file
26
+
27
+ # openspacehdl
28
+
29
+ Python package of [Open Space HDL](https://openspacehdl.org), a family of open-source VHDL IP cores for spacecraft
30
+ on-board data handling.
31
+
32
+ This is an early release. It lists the projects of the family as the website shows them; it does not contain the
33
+ cores or any tools yet.
34
+
35
+ ## Install
36
+
37
+ ```shell
38
+ pip install openspacehdl
39
+ ```
40
+
41
+ The package needs Python 3.10 or later and has no dependencies. On a machine without network access, copy the wheel
42
+ and install it from the file:
43
+
44
+ ```shell
45
+ pip install openspacehdl-<version>-py3-none-any.whl
46
+ ```
47
+
48
+ ## Use
49
+
50
+ ```shell
51
+ openspacehdl --version # version of the package
52
+ openspacehdl info # every project of the family: standard, summary, TRL, documentation and source
53
+ openspacehdl info OpenFibre # one project, by name or repository name
54
+ ```
55
+
56
+ `python -m openspacehdl` works the same way.
57
+
58
+ The list comes from the project cards of [openspacehdl.org](https://openspacehdl.org) at the time of the release.
59
+ A project that is not yet public is listed as "Coming soon", without links.
60
+
61
+ ## Development
62
+
63
+ ```shell
64
+ pip install -r requirements-dev.txt
65
+ pip install -e .
66
+ pytest
67
+ python tools/family_data.py --site <clone of open-space-hdl.github.io> --check
68
+ python -m build
69
+ ```
70
+
71
+ `tools/family_data.py` writes `src/openspacehdl/data/family.json` from `_data/projects.yml` and
72
+ `_data/project_groups.yml` of the website repository; `--check` only compares.
73
+
74
+ ## Licence
75
+
76
+ The package is released under the [MIT License](LICENSE). The IP cores of the family have their own licence (PSI HDL
77
+ Library License), stated in each repository.
@@ -0,0 +1,11 @@
1
+ openspacehdl/__init__.py,sha256=Tsyl-ggC0qKMvJfncedPGB8FeljpvL1HMsYAIF70JMI,110
2
+ openspacehdl/__main__.py,sha256=CXIDS0eQTuE7K0znw8awHDgVFR7OTE-dxw0brVCacqs,110
3
+ openspacehdl/cli.py,sha256=YBig2dywwbGCBkdbxow9r1rdgIcGD_Li0_leZBwuubQ,2618
4
+ openspacehdl/family.py,sha256=0UfEd4Ra0-_M20fOqUCX8AKb_ZvR1wT0BeMZGgvnsPo,2054
5
+ openspacehdl/data/family.json,sha256=FMGTdknJ_wLTmy9AsdCkNIVgH0Wgk1zp0r0hc9cg_3M,5345
6
+ openspacehdl-0.0.1.dist-info/licenses/LICENSE,sha256=Omis6exD_B3M_XQlWdtMC1fJ63si-aELmwojPxI9Uh0,1073
7
+ openspacehdl-0.0.1.dist-info/METADATA,sha256=wDSsBQgv-GnLNsG-6nhaiPwX4-SYwROo1r4MZ5frhEA,2833
8
+ openspacehdl-0.0.1.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
9
+ openspacehdl-0.0.1.dist-info/entry_points.txt,sha256=weweKiUryfr4MkHrERM_IxoiTz4dUzx7xqxv4P7eOGc,55
10
+ openspacehdl-0.0.1.dist-info/top_level.txt,sha256=N0ujaubIerqVdOeBSQOfs8ileSukmfYI_IBk-kiGgRI,13
11
+ openspacehdl-0.0.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.2.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ openspacehdl = openspacehdl.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Julian Schneider
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 @@
1
+ openspacehdl