<p align="center">
<a title="edaa-org.github.io/pySVModel" href="https://edaa-org.github.io/pyEDAA.ProjectModel"><img height="80px" src="doc/_static/logo_on_dark.svg"/></a>
</p>
[![Sourcecode on GitHub](https://img.shields.io/badge/pyEDAA-ProjectModel-ab47bc.svg?longCache=true&style=flat-square&logo=github&longCache=true&logo=GitHub&labelColor=6a1b9a)](https://GitHub.com/edaa-org/pyEDAA.ProjectModel)
[![Sourcecode License](https://img.shields.io/pypi/l/pyEDAA.ProjectModel?longCache=true&style=flat-square&logo=Apache&label=code)](LICENSE.md)
[![Documentation](https://img.shields.io/website?longCache=true&style=flat-square&label=edaa-org.github.io%2FpyEDAA.ProjectModel&logo=GitHub&logoColor=fff&up_color=blueviolet&up_message=Read%20now%20%E2%9E%9A&url=https%3A%2F%2Fedaa-org.github.io%2FpyEDAA.ProjectModel%2Findex.html)](https://edaa-org.github.io/pyEDAA.ProjectModel/)
[![Documentation License](https://img.shields.io/badge/doc-CC--BY%204.0-green?longCache=true&style=flat-square&logo=CreativeCommons&logoColor=fff)](LICENSE.md)
[![Gitter](https://img.shields.io/badge/chat-on%20gitter-4db797.svg?longCache=true&style=flat-square&logo=gitter&logoColor=e8ecef)](https://gitter.im/hdl/community)
[![PyPI](https://img.shields.io/pypi/v/pyEDAA.ProjectModel?longCache=true&style=flat-square&logo=PyPI&logoColor=FBE072)](https://pypi.org/project/pyEDAA.ProjectModel/)
![PyPI - Status](https://img.shields.io/pypi/status/pyEDAA.ProjectModel?longCache=true&style=flat-square&logo=PyPI&logoColor=FBE072)
![PyPI - Python Version](https://img.shields.io/pypi/pyversions/pyEDAA.ProjectModel?longCache=true&style=flat-square&logo=PyPI&logoColor=FBE072)
[![GitHub Workflow - Build and Test Status](https://img.shields.io/github/workflow/status/edaa-org/pyEDAA.ProjectModel/Pipeline/main?longCache=true&style=flat-square&label=Build%20and%20test&logo=GitHub%20Actions&logoColor=FFFFFF)](https://GitHub.com/edaa-org/pyEDAA.ProjectModel/actions/workflows/Pipeline.yml)
[![Libraries.io status for latest release](https://img.shields.io/librariesio/release/pypi/pyEDAA.ProjectModel?longCache=true&style=flat-square&logo=Libraries.io&logoColor=fff)](https://libraries.io/github/edaa-org/pyEDAA.ProjectModel)
[![Codacy - Quality](https://img.shields.io/codacy/grade/c2635df20fa840bc85639ca2fa1d9cb4?longCache=true&style=flat-square&logo=Codacy)](https://www.codacy.com/gh/edaa-org/pyEDAA.ProjectModel)
[![Codacy - Coverage](https://img.shields.io/codacy/coverage/c2635df20fa840bc85639ca2fa1d9cb4?longCache=true&style=flat-square&logo=Codacy)](https://www.codacy.com/gh/edaa-org/pyEDAA.ProjectModel)
[![Codecov - Branch Coverage](https://img.shields.io/codecov/c/github/edaa-org/pyEDAA.ProjectModel?longCache=true&style=flat-square&logo=Codecov)](https://codecov.io/gh/edaa-org/pyEDAA.ProjectModel)
<!--
[![Dependent repos (via libraries.io)](https://img.shields.io/librariesio/dependent-repos/pypi/pyEDAA.ProjectModel?longCache=true&style=flat-square&logo=GitHub)](https://github.com/edaa-org/pyEDAA.ProjectModel/network/dependents)
[![Requires.io](https://img.shields.io/requires/github/edaa-org/pyEDAA.ProjectModel?longCache=true&style=flat-square)](https://requires.io/github/edaa-org/pyEDAA.ProjectModel/requirements/?branch=main)
[![Libraries.io SourceRank](https://img.shields.io/librariesio/sourcerank/pypi/pyEDAA.ProjectModel)](https://libraries.io/github/edaa-org/pyEDAA.ProjectModel/sourcerank)
-->
# Main Goals
This package provides a unified abstract project model for HDL designs and EDA tools.
Third-party frameworks can derive own classes and implement additional logic to create
a concrete project model for their tools.
Frameworks consuming this model can build higher level features and services on top of
such a model, while supporting multiple input sources.
# Data Model
1. The toplevel element is a `Project`, which contains one or multiple designs.
2. A `Design` is a variant of a project and contains filesets.
3. A `FileSet` contains files or further sub-filesets.
4. A `File` represents a single file. E.g. source files, configuration files, constraint files.
5. A `VHDLLibrary` represents a group of `VHDLSourceFile`s being compiled into the same VHDL library.
![img.png](doc/datamodel.png)
# Features
* Construct a project model:
* top-down (project → design → fileset → file) or
* bottom-up (file → fileset → design → project) or
* parsing a project file.
* Designs, filesets and files can use absolute or relative paths.
* `ResolvedPath` returns the resolved absolute path to an object.
* Projects, designs, filesets and files can be validated (e.g. if the path exists).
* Projects, designs, filesets and files can have user-defined attributes.
* User-defined attributes are resolved bottom-up.
# Project File Readers
## OSVVM `*.pro` File Reader
ProjectModel can read `*.pro` files and extract source files. Included `*.pro` files
are represented as sub-filesets.
## Xilinx Vivado `*.xpr` Reader
ProjectModel can read `*.xpr` files and extract source, constraint and simulation
files while preserving the fileset structure.
# Use Cases
* Reading OSVVM's `*.pro` files.
* Reading Xilinx Vivado's `*.xpr` files.
# Examples
```python
from pathlib import Path
from pyEDAA.ProjectModel import Project, Design, FileSet, VHDLSourceFile
print(f"Current working directory: {Path.cwd()}")
projectDirectory = Path.cwd() / "../project"
print(f"Project directory: {projectDirectory!s} - {projectDirectory.exists()}")
project = Project("myProject", rootDirectory=projectDirectory)
designA = Design("designA", project=project, directory=Path("designA"))
designAFileset = FileSet("srcA", design=designA)
for vhdlFilePath in designAFileset.ResolvedPath.glob("*.vhdl"):
designAFileset.AddFile(VHDLSourceFile(vhdlFilePath))
libFileset = FileSet("lib", Path("../lib"), design=designA)
for vhdlFilePath in libFileset.ResolvedPath.glob("*.vhdl"):
libFileset.AddFile(VHDLSourceFile(vhdlFilePath))
print(f"All VHDL files in {designA.Name}:")
for file in designA.Files(fileType=VHDLSourceFile):
print(f" {file.Path}")
```
# Consumers
This layer is used by:
* 🚧 pyEDAA.Workflow
# References
* [Paebbels/pyIPCMI: pyIPCMI/Base/Project.py](https://GitHub.com/Paebbels/pyIPCMI/blob/master/pyIPCMI/Base/Project.py)
* [VUnit/vunit: vunit/project.py](https://GitHub.com/VUnit/vunit/blob/master/vunit/project.py)
* [PyFPGA/pyfpga: fpga/project.py](https://GitHub.com/PyFPGA/pyfpga/blob/main/fpga/project.py)
* [olofk/fusesoc: fusesoc/capi2/core.py](https://GitHub.com/olofk/fusesoc/blob/master/fusesoc/capi2/core.py)
* [XedaHQ/xeda: xeda/flows/flow.py](https://GitHub.com/XedaHQ/xeda/blob/master/xeda/flows/flow.py)
* [tsfpga/tsfpga: tsfpga/build_project_list.py](https://gitlab.com/tsfpga/tsfpga/-/blob/master/tsfpga/build_project_list.py)
* [hdl-make: hdlmake/](https://ohwr.org/project/hdl-make/tree/master/hdlmake)
* [OSVVM/OSVVM-Scripts: OsvvmProjectScripts.tcl](https://GitHub.com/OSVVM/OSVVM-Scripts/blob/master/OsvvmProjectScripts.tcl)
# Contributors
* [Patrick Lehmann](https://GitHub.com/Paebbels) (Maintainer)
* [Unai Martinez-Corral](https://GitHub.com/umarcor)
* [Stefan Unrein](https://GitHub.com/stefanunrein)
* [and more...](https://GitHub.com/edaa-org/pyEDAA.ProjectModel/graphs/contributors)
# License
This Python package (source code) licensed under [Apache License 2.0](LICENSE.md).
The accompanying documentation is licensed under [Creative Commons - Attribution 4.0 (CC-BY 4.0)](doc/Doc-License.rst).
-------------------------
SPDX-License-Identifier: Apache-2.0
Raw data
{
"_id": null,
"home_page": "https://GitHub.com/edaa-org/pyEDAA.ProjectModel",
"name": "pyEDAA.ProjectModel",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "eda project, model, abstract, xilinx, vivado, osvvm, file set, file group, test bench, test harness",
"author": "Patrick Lehmann",
"author_email": "Paebbels@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/08/81/1a66a9e063033fc7dc942a7064bd0ba5d6a694b8a8ecdf55533be485966b/pyedaa_projectmodel-0.5.0.tar.gz",
"platform": null,
"description": "<p align=\"center\">\n <a title=\"edaa-org.github.io/pySVModel\" href=\"https://edaa-org.github.io/pyEDAA.ProjectModel\"><img height=\"80px\" src=\"doc/_static/logo_on_dark.svg\"/></a>\n</p>\n\n[![Sourcecode on GitHub](https://img.shields.io/badge/pyEDAA-ProjectModel-ab47bc.svg?longCache=true&style=flat-square&logo=github&longCache=true&logo=GitHub&labelColor=6a1b9a)](https://GitHub.com/edaa-org/pyEDAA.ProjectModel)\n[![Sourcecode License](https://img.shields.io/pypi/l/pyEDAA.ProjectModel?longCache=true&style=flat-square&logo=Apache&label=code)](LICENSE.md)\n[![Documentation](https://img.shields.io/website?longCache=true&style=flat-square&label=edaa-org.github.io%2FpyEDAA.ProjectModel&logo=GitHub&logoColor=fff&up_color=blueviolet&up_message=Read%20now%20%E2%9E%9A&url=https%3A%2F%2Fedaa-org.github.io%2FpyEDAA.ProjectModel%2Findex.html)](https://edaa-org.github.io/pyEDAA.ProjectModel/)\n[![Documentation License](https://img.shields.io/badge/doc-CC--BY%204.0-green?longCache=true&style=flat-square&logo=CreativeCommons&logoColor=fff)](LICENSE.md)\n[![Gitter](https://img.shields.io/badge/chat-on%20gitter-4db797.svg?longCache=true&style=flat-square&logo=gitter&logoColor=e8ecef)](https://gitter.im/hdl/community) \n[![PyPI](https://img.shields.io/pypi/v/pyEDAA.ProjectModel?longCache=true&style=flat-square&logo=PyPI&logoColor=FBE072)](https://pypi.org/project/pyEDAA.ProjectModel/)\n![PyPI - Status](https://img.shields.io/pypi/status/pyEDAA.ProjectModel?longCache=true&style=flat-square&logo=PyPI&logoColor=FBE072)\n![PyPI - Python Version](https://img.shields.io/pypi/pyversions/pyEDAA.ProjectModel?longCache=true&style=flat-square&logo=PyPI&logoColor=FBE072) \n[![GitHub Workflow - Build and Test Status](https://img.shields.io/github/workflow/status/edaa-org/pyEDAA.ProjectModel/Pipeline/main?longCache=true&style=flat-square&label=Build%20and%20test&logo=GitHub%20Actions&logoColor=FFFFFF)](https://GitHub.com/edaa-org/pyEDAA.ProjectModel/actions/workflows/Pipeline.yml)\n[![Libraries.io status for latest release](https://img.shields.io/librariesio/release/pypi/pyEDAA.ProjectModel?longCache=true&style=flat-square&logo=Libraries.io&logoColor=fff)](https://libraries.io/github/edaa-org/pyEDAA.ProjectModel)\n[![Codacy - Quality](https://img.shields.io/codacy/grade/c2635df20fa840bc85639ca2fa1d9cb4?longCache=true&style=flat-square&logo=Codacy)](https://www.codacy.com/gh/edaa-org/pyEDAA.ProjectModel)\n[![Codacy - Coverage](https://img.shields.io/codacy/coverage/c2635df20fa840bc85639ca2fa1d9cb4?longCache=true&style=flat-square&logo=Codacy)](https://www.codacy.com/gh/edaa-org/pyEDAA.ProjectModel)\n[![Codecov - Branch Coverage](https://img.shields.io/codecov/c/github/edaa-org/pyEDAA.ProjectModel?longCache=true&style=flat-square&logo=Codecov)](https://codecov.io/gh/edaa-org/pyEDAA.ProjectModel)\n\n<!--\n[![Dependent repos (via libraries.io)](https://img.shields.io/librariesio/dependent-repos/pypi/pyEDAA.ProjectModel?longCache=true&style=flat-square&logo=GitHub)](https://github.com/edaa-org/pyEDAA.ProjectModel/network/dependents)\n[![Requires.io](https://img.shields.io/requires/github/edaa-org/pyEDAA.ProjectModel?longCache=true&style=flat-square)](https://requires.io/github/edaa-org/pyEDAA.ProjectModel/requirements/?branch=main)\n[![Libraries.io SourceRank](https://img.shields.io/librariesio/sourcerank/pypi/pyEDAA.ProjectModel)](https://libraries.io/github/edaa-org/pyEDAA.ProjectModel/sourcerank) \n-->\n\n# Main Goals\n\nThis package provides a unified abstract project model for HDL designs and EDA tools.\nThird-party frameworks can derive own classes and implement additional logic to create\na concrete project model for their tools.\n\nFrameworks consuming this model can build higher level features and services on top of\nsuch a model, while supporting multiple input sources.\n\n# Data Model\n\n1. The toplevel element is a `Project`, which contains one or multiple designs.\n2. A `Design` is a variant of a project and contains filesets.\n3. A `FileSet` contains files or further sub-filesets.\n4. A `File` represents a single file. E.g. source files, configuration files, constraint files.\n5. A `VHDLLibrary` represents a group of `VHDLSourceFile`s being compiled into the same VHDL library.\n\n![img.png](doc/datamodel.png)\n\n# Features\n\n* Construct a project model: \n * top-down (project → design → fileset → file) or\n * bottom-up (file → fileset → design → project) or\n * parsing a project file.\n\n* Designs, filesets and files can use absolute or relative paths.\n * `ResolvedPath` returns the resolved absolute path to an object.\n\n* Projects, designs, filesets and files can be validated (e.g. if the path exists).\n\n* Projects, designs, filesets and files can have user-defined attributes.\n * User-defined attributes are resolved bottom-up.\n\n# Project File Readers\n\n## OSVVM `*.pro` File Reader\n\nProjectModel can read `*.pro` files and extract source files. Included `*.pro` files\nare represented as sub-filesets.\n\n## Xilinx Vivado `*.xpr` Reader\n\nProjectModel can read `*.xpr` files and extract source, constraint and simulation\nfiles while preserving the fileset structure.\n\n# Use Cases\n\n* Reading OSVVM's `*.pro` files.\n* Reading Xilinx Vivado's `*.xpr` files.\n\n# Examples\n\n```python\nfrom pathlib import Path\nfrom pyEDAA.ProjectModel import Project, Design, FileSet, VHDLSourceFile\n\nprint(f\"Current working directory: {Path.cwd()}\")\nprojectDirectory = Path.cwd() / \"../project\"\nprint(f\"Project directory: {projectDirectory!s} - {projectDirectory.exists()}\")\n\nproject = Project(\"myProject\", rootDirectory=projectDirectory)\ndesignA = Design(\"designA\", project=project, directory=Path(\"designA\"))\ndesignAFileset = FileSet(\"srcA\", design=designA)\nfor vhdlFilePath in designAFileset.ResolvedPath.glob(\"*.vhdl\"):\n\tdesignAFileset.AddFile(VHDLSourceFile(vhdlFilePath))\n\nlibFileset = FileSet(\"lib\", Path(\"../lib\"), design=designA)\nfor vhdlFilePath in libFileset.ResolvedPath.glob(\"*.vhdl\"):\n\tlibFileset.AddFile(VHDLSourceFile(vhdlFilePath))\n\nprint(f\"All VHDL files in {designA.Name}:\")\nfor file in designA.Files(fileType=VHDLSourceFile):\n\tprint(f\" {file.Path}\")\n```\n\n# Consumers\n\nThis layer is used by:\n\n* \ud83d\udea7 pyEDAA.Workflow\n\n\n# References\n\n* [Paebbels/pyIPCMI: pyIPCMI/Base/Project.py](https://GitHub.com/Paebbels/pyIPCMI/blob/master/pyIPCMI/Base/Project.py)\n* [VUnit/vunit: vunit/project.py](https://GitHub.com/VUnit/vunit/blob/master/vunit/project.py)\n* [PyFPGA/pyfpga: fpga/project.py](https://GitHub.com/PyFPGA/pyfpga/blob/main/fpga/project.py)\n* [olofk/fusesoc: fusesoc/capi2/core.py](https://GitHub.com/olofk/fusesoc/blob/master/fusesoc/capi2/core.py)\n* [XedaHQ/xeda: xeda/flows/flow.py](https://GitHub.com/XedaHQ/xeda/blob/master/xeda/flows/flow.py)\n* [tsfpga/tsfpga: tsfpga/build_project_list.py](https://gitlab.com/tsfpga/tsfpga/-/blob/master/tsfpga/build_project_list.py)\n* [hdl-make: hdlmake/](https://ohwr.org/project/hdl-make/tree/master/hdlmake)\n* [OSVVM/OSVVM-Scripts: OsvvmProjectScripts.tcl](https://GitHub.com/OSVVM/OSVVM-Scripts/blob/master/OsvvmProjectScripts.tcl)\n\n# Contributors\n\n* [Patrick Lehmann](https://GitHub.com/Paebbels) (Maintainer)\n* [Unai Martinez-Corral](https://GitHub.com/umarcor)\n* [Stefan Unrein](https://GitHub.com/stefanunrein)\n* [and more...](https://GitHub.com/edaa-org/pyEDAA.ProjectModel/graphs/contributors)\n\n# License\n\nThis Python package (source code) licensed under [Apache License 2.0](LICENSE.md). \nThe accompanying documentation is licensed under [Creative Commons - Attribution 4.0 (CC-BY 4.0)](doc/Doc-License.rst).\n\n-------------------------\nSPDX-License-Identifier: Apache-2.0\n",
"bugtrack_url": null,
"license": "Apache-2.0",
"summary": "An abstract model of EDA tool projects.",
"version": "0.5.0",
"project_urls": {
"Documentation": "https://edaa-org.GitHub.io/pyEDAA.ProjectModel",
"Homepage": "https://GitHub.com/edaa-org/pyEDAA.ProjectModel",
"Issue Tracker": "https://GitHub.com/edaa-org/pyEDAA.ProjectModel/issues",
"Source Code": "https://GitHub.com/edaa-org/pyEDAA.ProjectModel"
},
"split_keywords": [
"eda project",
" model",
" abstract",
" xilinx",
" vivado",
" osvvm",
" file set",
" file group",
" test bench",
" test harness"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "cce25bb03144c63abd4f07409362c5b293c23cf467307749513c783f5458b017",
"md5": "c9faedae8b5f6ccd69596e838de10633",
"sha256": "29a17ec4ff8266b27d9532f2ea7f6d162140ddd0df07dcbe03e74713d543e4cc"
},
"downloads": -1,
"filename": "pyEDAA.ProjectModel-0.5.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "c9faedae8b5f6ccd69596e838de10633",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 34818,
"upload_time": "2024-11-03T22:21:04",
"upload_time_iso_8601": "2024-11-03T22:21:04.481404Z",
"url": "https://files.pythonhosted.org/packages/cc/e2/5bb03144c63abd4f07409362c5b293c23cf467307749513c783f5458b017/pyEDAA.ProjectModel-0.5.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "08811a66a9e063033fc7dc942a7064bd0ba5d6a694b8a8ecdf55533be485966b",
"md5": "14cb15aab43bfa9905bdab03f9e08131",
"sha256": "de339273da39013c5062d6f9d208528cd1b3553dbf80cd28640da868eb7cedc7"
},
"downloads": -1,
"filename": "pyedaa_projectmodel-0.5.0.tar.gz",
"has_sig": false,
"md5_digest": "14cb15aab43bfa9905bdab03f9e08131",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 26253,
"upload_time": "2024-11-03T22:21:02",
"upload_time_iso_8601": "2024-11-03T22:21:02.824487Z",
"url": "https://files.pythonhosted.org/packages/08/81/1a66a9e063033fc7dc942a7064bd0ba5d6a694b8a8ecdf55533be485966b/pyedaa_projectmodel-0.5.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-03 22:21:02",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "pyedaa.projectmodel"
}