diff --git a/.buildinfo b/.buildinfo new file mode 100644 index 00000000..ccea200f --- /dev/null +++ b/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 7133a5af6d992ad8f5e8918c0e42bbf0 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/ChangeLog/index.html b/ChangeLog/index.html new file mode 100644 index 00000000..012f963c --- /dev/null +++ b/ChangeLog/index.html @@ -0,0 +1,147 @@ + + + + + + + ChangeLog — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

ChangeLog

+
+

Upcoming Release

+
    +
  • tbd

  • +
+
+
+

01.09.2021

+

pyEDAA.ProjectModel was split from pyIPCMI (v1.1.6) as an independent Python package.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/Dependency.html b/Dependency.html new file mode 100644 index 00000000..101cc0cc --- /dev/null +++ b/Dependency.html @@ -0,0 +1,372 @@ + + + + + + + Dependency — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

Dependency

+ + + + + + + + + + + +

Libraries.io

Requires.io

Libraries.io status for latest release

Requires.io

+
+

pyEDAA.ProjectModel Package

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Package

Version

License

Dependencies

pyTooling

≥5.0.0

Apache License, 2.0

None

pyVHDLModel

≥0.27.1

Apache License, 2.0

+

pySVModel

≥0.3.1

Apache License, 2.0

+

pySystemRDLModel

≥0.1.0

Apache License, 2.0

+
+
+
+

Unit Testing / Coverage / Type Checking (Optional)

+

Additional Python packages needed for testing, code coverage collection and static type checking. These packages are +only needed for developers or on a CI server, thus sub-dependencies are not evaluated further.

+

Manually Installing Test Requirements

+

Use the tests/requirements.txt file to install all dependencies via pip3. The file will recursively install +the mandatory dependencies too.

+
pip3 install -U -r tests/requirements.txt
+
+
+

Dependency List

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Package

Version

License

Dependencies

pytest

≥7.4.0

MIT

Not yet evaluated.

pytest-cov

≥4.1.0

MIT

Not yet evaluated.

Coverage

≥7.3

Apache License, 2.0

Not yet evaluated.

mypy

≥1.5

MIT

Not yet evaluated.

typing-extensions

≥4.7.1

PSF-2.0

Not yet evaluated.

lxml

≥4.9

BSD 3-Clause

Not yet evaluated.

+
+
+

Sphinx Documentation (Optional)

+

Additional Python packages needed for documentation generation. These packages are only needed for developers or on a +CI server, thus sub-dependencies are not evaluated further.

+

Manually Installing Documentation Requirements

+

Use the doc/requirements.txt file to install all dependencies via pip3. The file will recursively install +the mandatory dependencies too.

+
pip3 install -U -r doc/requirements.txt
+
+
+

Dependency List

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Package

Version

License

Dependencies

pyTooling

≥5.0.0

Apache License, 2.0

None

Sphinx

≥5.3.0

BSD 3-Clause

Not yet evaluated.

sphinx_btd_theme

≥0.5.2

MIT

Not yet evaluated.

!! sphinx_fontawesome

≥0.0.6

GPL 2.0

Not yet evaluated.

sphinx_autodoc_typehints

≥1.19.5

MIT

Not yet evaluated.

+
+
+

Packaging (Optional)

+

Additional Python packages needed for installation package generation. These packages are only needed for developers or +on a CI server, thus sub-dependencies are not evaluated further.

+

Manually Installing Packaging Requirements

+

Use the build/requirements.txt file to install all dependencies via pip3. The file will recursively +install the mandatory dependencies too.

+
pip3 install -U -r build/requirements.txt
+
+
+

Dependency List

+ + + + + + + + + + + + + + + + + + + + +

Package

Version

License

Dependencies

pyTooling

≥5.0.0

Apache License, 2.0

None

wheel

≥0.40.0

MIT

Not yet evaluated.

+
+
+

Publishing (CI-Server only)

+

Additional Python packages needed for publishing the generated installation package to e.g, PyPI or any equivalent +services. These packages are only needed for maintainers or on a CI server, thus sub-dependencies are not evaluated +further.

+

Manually Installing Publishing Requirements

+

Use the dist/requirements.txt file to install all dependencies via pip3. The file will recursively +install the mandatory dependencies too.

+
pip3 install -U -r dist/requirements.txt
+
+
+

Dependency List

+ + + + + + + + + + + + + + + + + + + + +

Package

Version

License

Dependencies

wheel

≥0.40.0

MIT

Not yet evaluated.

Twine

≥4.0.2

Apache License, 2.0

Not yet evaluated.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/Doc-License.html b/Doc-License.html new file mode 100644 index 00000000..8542d67d --- /dev/null +++ b/Doc-License.html @@ -0,0 +1,486 @@ + + + + + + + Creative Commons Attribution 4.0 International — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+
    +
  • »
  • +
  • Creative Commons Attribution 4.0 International
  • +
  • + Edit on GitHub +
  • +
+
+
+ +
+
+ + +
+

Attention

+

This CC BY 4.0 license applies only to the documentation of this project.

+
+
+

Creative Commons Attribution 4.0 International

+

Creative Commons Corporation (“Creative Commons”) is not a law firm and does not +provide legal services or legal advice. Distribution of Creative Commons public +licenses does not create a lawyer-client or other relationship. Creative Commons +makes its licenses and related information available on an “as-is” basis. +Creative Commons gives no warranties regarding its licenses, any material +licensed under their terms and conditions, or any related information. Creative +Commons disclaims all liability for damages resulting from their use to the +fullest extent possible.

+ +

Creative Commons Attribution 4.0 International Public License

+

By exercising the Licensed Rights (defined below), You accept and agree to be +bound by the terms and conditions of this Creative Commons Attribution 4.0 +International Public License (“Public License”). To the extent this Public +License may be interpreted as a contract, You are granted the Licensed Rights +in consideration of Your acceptance of these terms and conditions, and the +Licensor grants You such rights in consideration of benefits the Licensor +receives from making the Licensed Material available under these terms and +conditions.

+
+

Section 1 – Definitions.

+
    +
  1. Adapted Material means material subject to Copyright and Similar +Rights that is derived from or based upon the Licensed Material and in +which the Licensed Material is translated, altered, arranged, transformed, or +otherwise modified in a manner requiring permission under the Copyright and +Similar Rights held by the Licensor. For purposes of this Public License, +where the Licensed Material is a musical work, performance, or sound +recording, Adapted Material is always produced where the Licensed Material +is synched in timed relation with a moving image.

  2. +
  3. Adapter’s License means the license You apply to Your Copyright and +Similar Rights in Your contributions to Adapted Material in accordance with +the terms and conditions of this Public License.

  4. +
  5. Copyright and Similar Rights means copyright and/or similar rights +closely related to copyright including, without limitation, performance, +broadcast, sound recording, and Sui Generis Database Rights, without regard +to how the rights are labeled or categorized. For purposes of this Public +License, the rights specified in Section 2(b)(1)-(2) are not Copyright and +Similar Rights.

  6. +
  7. Effective Technological Measures means those measures that, in the +absence of proper authority, may not be circumvented under laws fulfilling +obligations under Article 11 of the WIPO Copyright Treaty adopted on +December 20, 1996, and/or similar international agreements.

  8. +
  9. Exceptions and Limitations means fair use, fair dealing, and/or any +other exception or limitation to Copyright and Similar Rights that applies to +Your use of the Licensed Material.

  10. +
  11. Licensed Material means the artistic or literary work, database, or +other material to which the Licensor applied this Public License.

  12. +
  13. Licensed Rights means the rights granted to You subject to the terms +and conditions of this Public License, which are limited to all Copyright and +Similar Rights that apply to Your use of the Licensed Material and that the +Licensor has authority to license.

  14. +
  15. Licensor means the individual(s) or entity(ies) granting rights under +this Public License.

  16. +
  17. Share means to provide material to the public by any means or process +that requires permission under the Licensed Rights, such as reproduction, +public display, public performance, distribution, dissemination, +communication, or importation, and to make material available to the public +including in ways that members of the public may access the material from a +place and at a time individually chosen by them.

  18. +
  19. Sui Generis Database Rights means rights other than copyright +resulting from Directive 96/9/EC of the European Parliament and of the +Council of 11 March 1996 on the legal protection of databases, as amended +and/or succeeded, as well as other essentially equivalent rights anywhere +in the world.

  20. +
  21. You means the individual or entity exercising the Licensed Rights +under this Public License. Your has a corresponding meaning.

  22. +
+
+
+

Section 2 – Scope.

+
    +
  1. License grant.

    +
      +
    1. Subject to the terms and conditions of this Public License, the Licensor +hereby grants You a worldwide, royalty-free, non-sublicensable, +non-exclusive, irrevocable license to exercise the Licensed Rights in the +Licensed Material to:

      +
      +
        +
      1. reproduce and Share the Licensed Material, in whole or in part; and

      2. +
      3. produce, reproduce, and Share Adapted Material.

      4. +
      +
      +
    2. +
    3. Exceptions and Limitations. For the avoidance of doubt, where +Exceptions and Limitations apply to Your use, this Public License does not +apply, and You do not need to comply with its terms and conditions.

    4. +
    5. Term. The term of this Public License is specified in Section 6(a).

    6. +
    7. Media and formats; technical modifications allowed. The Licensor +authorizes You to exercise the Licensed Rights in all media and formats +whether now known or hereafter created, and to make technical +modifications necessary to do so. The Licensor waives and/or agrees not to +assert any right or authority to forbid You from making technical +modifications necessary to exercise the Licensed Rights, including +technical modifications necessary to circumvent Effective Technological +Measures. For purposes of this Public License, simply making modifications +authorized by this Section 2(a)(4) never produces Adapted Material.

    8. +
    9. Downstream recipients.

      +
      +
        +
      1. Offer from the Licensor – Licensed Material. Every recipient of +the Licensed Material automatically receives an offer from the +Licensor to exercise the Licensed Rights under the terms and +conditions of this Public License.

      2. +
      3. No downstream restrictions. You may not offer or impose any +additional or different terms or conditions on, or apply any Effective +Technological Measures to, the Licensed Material if doing so restricts +exercise of the Licensed Rights by any recipient of the Licensed +Material.

      4. +
      +
      +
    10. +
    11. No endorsement. Nothing in this Public License constitutes or may +be construed as permission to assert or imply that You are, or that Your +use of the Licensed Material is, connected with, or sponsored, endorsed, +or granted official status by, the Licensor or others designated to +receive attribution as provided in Section 3(a)(1)(A)(i).

    12. +
    +
  2. +
  3. Other rights.

    +
      +
    1. Moral rights, such as the right of integrity, are not licensed under this +Public License, nor are publicity, privacy, and/or other similar +personality rights; however, to the extent possible, the Licensor waives +and/or agrees not to assert any such rights held by the Licensor to the +limited extent necessary to allow You to exercise the Licensed Rights, but +not otherwise.

    2. +
    3. Patent and trademark rights are not licensed under this Public License.

    4. +
    5. To the extent possible, the Licensor waives any right to collect royalties +from You for the exercise of the Licensed Rights, whether directly or +through a collecting society under any voluntary or waivable statutory or +compulsory licensing scheme. In all other cases the Licensor expressly +reserves any right to collect such royalties.

    6. +
    +
  4. +
+
+
+

Section 3 – License Conditions.

+

Your exercise of the Licensed Rights is expressly made subject to the following conditions.

+
    +
  1. Attribution.

    +
      +
    1. If You Share the Licensed Material (including in modified form), You must:

      +
      +
        +
      1. retain the following if it is supplied by the Licensor with the +Licensed Material:

      2. +
      +
      +
        +
      1. identification of the creator(s) of the Licensed Material and any +others designated to receive attribution, in any reasonable manner +requested by the Licensor (including by pseudonym if designated);

      2. +
      3. a copyright notice;

      4. +
      5. a notice that refers to this Public License;

      6. +
      7. a notice that refers to the disclaimer of warranties;

      8. +
      9. a URI or hyperlink to the Licensed Material to the extent reasonably +practicable;

      10. +
      +
      +
        +
      1. indicate if You modified the Licensed Material and retain an +indication of any previous modifications; and

      2. +
      3. indicate the Licensed Material is licensed under this Public License, +and include the text of, or the URI or hyperlink to, this Public +License.

      4. +
      +
      +
    2. +
    3. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner +based on the medium, means, and context in which You Share the Licensed +Material. For example, it may be reasonable to satisfy the conditions by +providing a URI or hyperlink to a resource that includes the required +information.

    4. +
    5. If requested by the Licensor, You must remove any of the information +required by Section 3(a)(1)(A) to the extent reasonably practicable.

    6. +
    7. If You Share Adapted Material You produce, the Adapter’s License You apply +must not prevent recipients of the Adapted Material from complying with +this Public License.

    8. +
    +
  2. +
+
+
+

Section 4 – Sui Generis Database Rights.

+

Where the Licensed Rights include Sui Generis Database Rights that apply to Your +use of the Licensed Material:

+
    +
  1. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, +reuse, reproduce, and Share all or a substantial portion of the contents of +the database;

  2. +
  3. if You include all or a substantial portion of the database contents in a +database in which You have Sui Generis Database Rights, then the database +in which You have Sui Generis Database Rights (but not its individual +contents) is Adapted Material; and

  4. +
  5. You must comply with the conditions in Section 3(a) if You Share all or a +substantial portion of the contents of the database.

  6. +
+

For the avoidance of doubt, this Section 4 supplements and does not replace +Your obligations under this Public License where the Licensed Rights include +other Copyright and Similar Rights.

+
+
+

Section 5 – Disclaimer of Warranties and Limitation of Liability.

+
    +
  1. Unless otherwise separately undertaken by the Licensor, to the extent +possible, the Licensor offers the Licensed Material as-is and as-available, +and makes no representations or warranties of any kind concerning the +Licensed Material, whether express, implied, statutory, or other. This +includes, without limitation, warranties of title, merchantability, +fitness for a particular purpose, non-infringement, absence of latent or +other defects, accuracy, or the presence or absence of errors, whether or +not known or discoverable. Where disclaimers of warranties are not allowed +in full or in part, this disclaimer may not apply to You.

  2. +
  3. To the extent possible, in no event will the Licensor be liable to You +on any legal theory (including, without limitation, negligence) or +otherwise for any direct, special, indirect, incidental, consequential, +punitive, exemplary, or other losses, costs, expenses, or damages arising +out of this Public License or use of the Licensed Material, even if the +Licensor has been advised of the possibility of such losses, costs, expenses, +or damages. Where a limitation of liability is not allowed in full or in +part, this limitation may not apply to You.

  4. +
  5. The disclaimer of warranties and limitation of liability provided above +shall be interpreted in a manner that, to the extent possible, most +closely approximates an absolute disclaimer and waiver of all liability.

  6. +
+
+
+

Section 6 – Term and Termination.

+
    +
  1. This Public License applies for the term of the Copyright and Similar Rights +licensed here. However, if You fail to comply with this Public License, then +Your rights under this Public License terminate automatically.

  2. +
  3. Where Your right to use the Licensed Material has terminated under +Section 6(a), it reinstates:

    +
      +
    1. automatically as of the date the violation is cured, provided it is cured +within 30 days of Your discovery of the violation; or

    2. +
    3. upon express reinstatement by the Licensor.

    4. +
    +

    For the avoidance of doubt, this Section 6(b) does not affect any right the +Licensor may have to seek remedies for Your violations of this Public License.

    +
  4. +
  5. For the avoidance of doubt, the Licensor may also offer the Licensed Material +under separate terms or conditions or stop distributing the Licensed Material +at any time; however, doing so will not terminate this Public License.

  6. +
  7. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.

  8. +
+
+
+

Section 7 – Other Terms and Conditions.

+
    +
  1. The Licensor shall not be bound by any additional or different terms or +conditions communicated by You unless expressly agreed.

  2. +
  3. Any arrangements, understandings, or agreements regarding the Licensed +Material not stated herein are separate from and independent of the terms +and conditions of this Public License.

  4. +
+
+
+

Section 8 – Interpretation.

+
    +
  1. For the avoidance of doubt, this Public License does not, and shall not be +interpreted to, reduce, limit, restrict, or impose conditions on any use of +the Licensed Material that could lawfully be made without permission under +this Public License.

  2. +
  3. To the extent possible, if any provision of this Public License is deemed +unenforceable, it shall be automatically reformed to the minimum extent +necessary to make it enforceable. If the provision cannot be reformed, it +shall be severed from this Public License without affecting the +enforceability of the remaining terms and conditions.

  4. +
  5. No term or condition of this Public License will be waived and no failure to +comply consented to unless expressly agreed to by the Licensor.

  6. +
  7. Nothing in this Public License constitutes or may be interpreted as a +limitation upon, or waiver of, any privileges and immunities that apply to +the Licensor or You, including from the legal processes of any jurisdiction +or authority.

  8. +
+
+

Creative Commons is not a party to its public licenses. Notwithstanding, +Creative Commons may elect to apply one of its public licenses to material it +publishes and in those instances will be considered the “Licensor.” Except for +the limited purpose of indicating that material is shared under a Creative +Commons public license or as otherwise permitted by the Creative Commons +policies published at creativecommons.org/policies, +Creative Commons does not authorize the use of the trademark “Creative Commons” +or any other trademark or logo of Creative Commons without its prior written +consent including, without limitation, in connection with any unauthorized +modifications to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For the +avoidance of doubt, this paragraph does not form part of the public licenses.

+

Creative Commons may be contacted at creativecommons.org

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/FileTypes/index.html b/FileTypes/index.html new file mode 100644 index 00000000..81e5b6c7 --- /dev/null +++ b/FileTypes/index.html @@ -0,0 +1,183 @@ + + + + + + + File Types — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

File Types

+

Design Goal

+

TBD

+
+

Content Types

+
+ graph TD; + HRC[HumanReadableContent] --> XMLC[XMLContent]; + HRC --> YAMLC[YAMLContent]; + HRC --> JSONC[JSONContent]; + HRC --> INIC[INIContent]; + HRC --> TOMLC[TOMLContent]; + HRC --> TCLC[TCLContent] --> SDCC[SDCContent]; +
+
+

Overall Hierarchy

+
+ graph TD; + File-->TextFile; + File-->LogFile; + File-->XMLFile; + File--->SourceFile; + File-->ConstraintFile; + File-->ProjectFile; + File-->SettingFile; + SourceFile-->HDLSourceFile; + SourceFile-->NetlistFile; + NetlistFile-->EDIFNetlistFile; + HDLSourceFile-->VHDLSourceFile; + HDLSourceFile-->VerilogSourceFile; + HDLSourceFile-->SystemVerilogSourceFile; + SourceFile-->PythonSourceFile; + PythonSourceFile-->CocotbSourceFile + SourceFile-->CSourceFile; + SourceFile-->CppSourceFile; +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/Glossary.html b/Glossary.html new file mode 100644 index 00000000..6fe582dc --- /dev/null +++ b/Glossary.html @@ -0,0 +1,178 @@ + + + + + + + Glossary — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

Glossary

+
+
LRM

Language Reference Manual is the name given to IEEE Standard documents defining Hardware Description Languages:

+ +
+
base-class

An ancestor class for other derived classes.

+
+
File

A representation of a physical file.

+
+
FileSet

A group of files.

+
+
Default fileset

If no fileset is specified, the pre-existing fileset named default is used to group files.

+
+
VHDLLibrary

A namespace in VHDL to group and organize VHDL design units (entity, package, configuration, context).

+
+
Design

A …

+
+
Project

A …

+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/Installation.html b/Installation.html new file mode 100644 index 00000000..bfda14d5 --- /dev/null +++ b/Installation.html @@ -0,0 +1,197 @@ + + + + + + + Installation/Updates — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

Installation/Updates

+
+

Note

+

Python ≥3.7 is required for this package due to problems with meta classes and +__getattr__ in Python 3.6.

+
+
+

Using PIP

+
+

Installation from PyPI using PIP

+
pip3 install pyEDAA.ProjectModel
+
+
+
+
+

Updating from PyPI using PIP

+
pip3 install -U pyEDAA.ProjectModel
+
+
+
+
+

Uninstallation using PIP

+
pip3 uninstall pyEDAA.ProjectModel
+
+
+
+
+

Installation from local directory using PIP

+
pip3 install .
+
+
+
+
+
+

Using setup.py (legacy)

+

See sections above on how to use PIP.

+
+

Installation using setup.py

+
setup.py install
+
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/License.html b/License.html new file mode 100644 index 00000000..59d76c6a --- /dev/null +++ b/License.html @@ -0,0 +1,277 @@ + + + + + + + Apache License 2.0 — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

Note

+

This is a local copy of the Apache License Version 2.0.

+
+
+

Attention

+

This Apache License, 2.0 applies to all source and configuration files of project, except documentation.

+
+
+

Apache License 2.0

+

Version 2.0, January 2004

+

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

+
+

1. Definitions.

+

“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

+

“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

+

“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that +entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether +by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

+

“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

+

“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and +configuration files.

+

“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object +code, generated documentation, and conversions to other media types.

+

“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is +included in or attached to the work (an example is provided in the Appendix below).

+

“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

+

“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative +Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to +submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication +sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue +tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is +conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

+

“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work.

+
+ +
+

3. Grant of Patent License.

+

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such +license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of +their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim +or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then +any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

+
+
+

4. Redistribution.

+

You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions:

+
    +
  • You must give any other recipients of the Work or Derivative Works a copy of this License; and

  • +
  • You must cause any modified files to carry prominent notices stating that You changed the files; and

  • +
  • You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source +form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

  • +
  • If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the +Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE +file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, +alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

  • +
+

You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise +complies with the conditions stated in this License.

+
+
+

5. Submission of Contributions.

+

Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any +separate license agreement you may have executed with Licensor regarding such Contributions.

+
+
+

6. Trademarks.

+

This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable +and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

+
+
+

7. Disclaimer of Warranty.

+

Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, +MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and +assume any risks associated with Your exercise of permissions under this License.

+
+
+

8. Limitation of Liability.

+

In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or +consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages +for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been +advised of the possibility of such damages.

+
+
+

9. Accepting Warranty or Additional Liability.

+

While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other +liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole +responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

+
+

Appendix: How to apply the Apache License to your work

+

To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets “[]” replaced with your own identifying +information. (Don’t include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or +class name and description of purpose be included on the same “printed page” as the copyright notice for easier identification within third-party archives.

+
Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/ProjectModel/Design.html b/ProjectModel/Design.html new file mode 100644 index 00000000..3f73032b --- /dev/null +++ b/ProjectModel/Design.html @@ -0,0 +1,252 @@ + + + + + + + Design — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

Design

+

Generic description of an EDA design.

+
+

Todo

+

Write documentation.

+
+

Class Relationship

+
+ graph TD; + Project --> Design; + Design --> VHDLLibrary; + Design --> FileSet; + VHDLLibrary --> File; + FileSet --> File + + style Design fill:#ee9b00 +
+

Condensed definition of class Design

+
@export
+class Design:
+  _name:                  str
+  _project:               Nullable['Project']
+  _directory:             Nullable[Path]
+  _fileSets:              Dict[str, FileSet]
+  _defaultFileSet:        Nullable[FileSet]
+  _vhdlLibraries:         Dict[str, VHDLLibrary]
+  _vhdlVersion:           VHDLVersion
+  _verilogVersion:        VerilogVersion
+  _svVersion:             SystemVerilogVersion
+  _externalVHDLLibraries: List
+
+  def __init__(
+    self,
+    name: str,
+    directory: Path = Path("."),
+    project: 'Project' = None,
+    vhdlVersion: VHDLVersion = None,
+    verilogVersion: VerilogVersion = None,
+    svVersion: SystemVerilogVersion = None
+  ):
+
+  @property
+  def Name(self) -> str:
+
+  @property
+  def Project(self) -> Nullable['Project']:
+  @Project.setter
+  def Project(self, value: 'Project') -> None:
+
+  @property
+  def Directory(self) -> Path:
+  @Directory.setter
+  def Directory(self, value: Path) -> None:
+
+  @property
+  def ResolvedPath(self) -> Path:
+
+  @property
+  def DefaultFileSet(self) -> FileSet:
+  @DefaultFileSet.setter
+  def DefaultFileSet(self, value: Union[str, FileSet]) -> None:
+
+  @property
+  def FileSets(self) -> Dict[str, FileSet]:
+
+  def Files(self, fileType: FileType = FileTypes.Any, fileSet: Union[str, FileSet] = None) -> Generator[File, None, None]:
+
+  @property
+  def VHDLLibraries(self) -> List[VHDLLibrary]:
+
+  @property
+  def VHDLVersion(self) -> VHDLVersion:
+  @VHDLVersion.setter
+  def VHDLVersion(self, value: VHDLVersion) -> None:
+
+  @property
+  def VerilogVersion(self) -> VerilogVersion:
+  @VerilogVersion.setter
+  def VerilogVersion(self, value: VerilogVersion) -> None:
+
+  @property
+  def SVVersion(self) -> SystemVerilogVersion:
+  @SVVersion.setter
+  def SVVersion(self, value: SystemVerilogVersion) -> None:
+
+  @property
+  def ExternalVHDLLibraries(self) -> List:
+
+  def AddFileSet(self, fileSet: FileSet) -> None:
+
+  def AddFileSets(self, fileSets: Iterable[FileSet]) -> None:
+
+  def AddFile(self, file: File) -> None:
+
+  def AddFiles(self, files: Iterable[File]) -> None:
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/ProjectModel/File.html b/ProjectModel/File.html new file mode 100644 index 00000000..8cf3812b --- /dev/null +++ b/ProjectModel/File.html @@ -0,0 +1,213 @@ + + + + + + + File — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

File

+

Generic description of a file in EDA design.

+
+

Todo

+

Write documentation.

+
+

Class Relationship

+
+ graph TD; + Project --> Design; + Design --> VHDLLibrary; + Design --> FileSet; + VHDLLibrary --> File; + FileSet --> File + + style File fill:#ee9b00 +
+

Condensed definition of class File

+
@export
+class File(metaclass=FileType):
+  _path:     Path
+  _project:  Nullable['Project']
+  _design:   Nullable['Design']
+  _fileSet:  Nullable['FileSet']
+
+  def __init__(
+    self,
+    path: Path,
+    project: 'Project' = None,
+    design: 'Design' = None,
+    fileSet: 'FileSet' = None
+  ):
+
+  @property
+  def FileType(self) -> 'FileType':
+
+  @property
+  def Path(self) -> Path:
+
+  @property
+  def ResolvedPath(self) -> Path:
+
+  @property
+  def Project(self) -> Nullable['Project']:
+  @Project.setter
+  def Project(self, value: 'Project') -> None:
+
+  @property
+  def Design(self) -> Nullable['Design']:
+  @Design.setter
+  def Design(self, value: 'Design') -> None:
+
+  @property
+  def FileSet(self) -> Nullable['FileSet']:
+  @FileSet.setter
+  def FileSet(self, value: 'FileSet') -> None:
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/ProjectModel/FileSet.html b/ProjectModel/FileSet.html new file mode 100644 index 00000000..22f34969 --- /dev/null +++ b/ProjectModel/FileSet.html @@ -0,0 +1,257 @@ + + + + + + + FileSet — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

FileSet

+

Generic description of an EDA file set (group of files).

+
+

Todo

+

Write documentation.

+
+

Class Relationship

+
+ graph TD; + Project --> Design; + Design --> VHDLLibrary; + Design --> FileSet; + VHDLLibrary --> File; + FileSet --> File + + style FileSet fill:#ee9b00 +
+

Condensed definition of class FileSet

+
@export
+class FileSet:
+  _name:        str
+  _project:     Nullable['Project']
+  _design:      Nullable['Design']
+  _directory:   Nullable[Path]
+  _parent:      Nullable['FileSet']
+  _fileSets:    Dict[str, 'FileSet']
+  _files:       List[File]
+
+  _vhdlLibrary:     'VHDLLibrary'
+  _vhdlVersion:     VHDLVersion
+  _verilogVersion:  VerilogVersion
+  _svVersion:       SystemVerilogVersion
+
+  def __init__(
+    self,
+    name: str,
+    directory: Path = Path("."),
+    project: 'Project' = None,
+    design: 'Design' = None,
+    parent: Nullable['FileSet'] = None,
+    vhdlLibrary: Union[str, 'VHDLLibrary'] = None,
+    vhdlVersion: VHDLVersion = None,
+    verilogVersion: VerilogVersion = None,
+    svVersion: SystemVerilogVersion = None
+  ):
+
+  @property
+  def Name(self) -> str:
+
+  @property
+  def Project(self) -> Nullable['Project']:
+  @Project.setter
+  def Project(self, value: 'Project') -> None:
+
+  @property
+  def Design(self) -> Nullable['Design']:
+  @Design.setter
+  def Design(self, value: 'Design') -> None:
+
+  @property
+  def Directory(self) -> Path:
+  @Directory.setter
+  def Directory(self, value: Path) -> None:
+
+  @property
+  def ResolvedPath(self) -> Path:
+
+  @property
+  def Parent(self) -> Nullable['FileSet']:
+  @Parent.setter
+  def Parent(self, value: 'FileSet') -> None:
+
+  @property
+  def FileSets(self) -> Dict[str, 'FileSet']:
+
+  def Files(self, fileType: FileType = FileTypes.Any, fileSet: Union[str, 'FileSet'] = None) -> Generator[File, None, None]:
+
+  def AddFile(self, file: File) -> None:
+
+  def AddFiles(self, files: Iterable[File]) -> None:
+
+  @property
+  def VHDLLibrary(self) -> 'VHDLLibrary':
+  @VHDLLibrary.setter
+  def VHDLLibrary(self, value: 'VHDLLibrary') -> None:
+
+  @property
+  def VHDLVersion(self) -> VHDLVersion:
+  @VHDLVersion.setter
+  def VHDLVersion(self, value: VHDLVersion) -> None:
+
+  @property
+  def VerilogVersion(self) -> VerilogVersion:
+  @VerilogVersion.setter
+  def VerilogVersion(self, value: VerilogVersion) -> None:
+
+  @property
+  def SVVersion(self) -> SystemVerilogVersion:
+  @SVVersion.setter
+  def SVVersion(self, value: SystemVerilogVersion) -> None:
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/ProjectModel/Project.html b/ProjectModel/Project.html new file mode 100644 index 00000000..20ffadfb --- /dev/null +++ b/ProjectModel/Project.html @@ -0,0 +1,221 @@ + + + + + + + Project — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

Project

+

Generic description of an EDA project.

+
+

Todo

+

Write documentation.

+
+

Class Relationship

+
+ graph TD; + Project --> Design; + Design --> VHDLLibrary; + Design --> FileSet; + VHDLLibrary --> File; + FileSet --> File + + style Project fill:#ee9b00 +
+

Condensed definition of class Project

+
@export
+class Project:
+  _name:                  str
+  _rootDirectory:         Nullable[Path]
+  _designs:               Dict[str, Design]
+  _vhdlVersion:           VHDLVersion
+  _verilogVersion:        VerilogVersion
+  _svVersion:             SystemVerilogVersion
+
+  def __init__(
+    self,
+    name: str,
+    rootDirectory: Path = Path("."),
+    vhdlVersion: VHDLVersion = None,
+    verilogVersion: VerilogVersion = None,
+    svVersion: SystemVerilogVersion = None
+  ):
+
+  @property
+  def Name(self) -> str:
+
+  @property
+  def RootDirectory(self) -> Path:
+  @RootDirectory.setter
+  def RootDirectory(self, value: Path) -> None:
+
+  @property
+  def ResolvedPath(self) -> Path:
+
+  @property
+  def Designs(self) -> Dict[str, Design]:
+
+  @property
+  def VHDLVersion(self) -> VHDLVersion:
+  @VHDLVersion.setter
+  def VHDLVersion(self, value: VHDLVersion) -> None:
+
+  @property
+  def VerilogVersion(self) -> VerilogVersion:
+  @VerilogVersion.setter
+  def VerilogVersion(self, value: VerilogVersion) -> None:
+
+  @property
+  def SVVersion(self) -> SystemVerilogVersion:
+  @SVVersion.setter
+  def SVVersion(self, value: SystemVerilogVersion) -> None:
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/ProjectModel/VHDLLibrary.html b/ProjectModel/VHDLLibrary.html new file mode 100644 index 00000000..f67a30be --- /dev/null +++ b/ProjectModel/VHDLLibrary.html @@ -0,0 +1,211 @@ + + + + + + + VHDL Library — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

VHDL Library

+

Generic description of a VHDL library (group of VHDL files containing VHDL primary units).

+
+

Todo

+

Write documentation.

+
+

Class Relationship

+
+ graph TD; + Project --> Design; + Design --> VHDLLibrary; + Design --> FileSet; + VHDLLibrary --> File; + FileSet --> File + + style VHDLLibrary fill:#ee9b00 +
+

Condensed definition of class VHDLLibrary

+
@export
+class VHDLLibrary:
+  _name:        str
+  _project:     Nullable['Project']
+  _design:      Nullable['Design']
+  _files:       List[File]
+  _vhdlVersion: VHDLVersion
+
+  def __init__(
+    self,
+    name: str,
+    project: 'Project' = None,
+    design: 'Design' = None,
+    vhdlVersion: VHDLVersion = None
+  ):
+
+  @property
+  def Name(self) -> str:
+
+  @property
+  def Project(self) -> Nullable['Project']:
+  @Project.setter
+  def Project(self, value: 'Project'):
+
+  @property
+  def Design(self) -> Nullable['Design']:
+  @Design.setter
+  def Design(self, value: 'Design'):
+
+  @property
+  def Files(self) -> Generator[File, None, None]:
+
+  @property
+  def VHDLVersion(self) -> VHDLVersion:
+  @VHDLVersion.setter
+  def VHDLVersion(self, value: VHDLVersion) -> None:
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/ProjectModel/index.html b/ProjectModel/index.html new file mode 100644 index 00000000..8439acf0 --- /dev/null +++ b/ProjectModel/index.html @@ -0,0 +1,183 @@ + + + + + + + Project Model — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

Project Model

+

Design Goal

+
    +
  • Clearly named classes that model the semantics of an EDA project.

  • +
  • Child objects shall have a reference to their parent.

  • +
+

Overall Hierarchy

+

An EDA project contains one or multiple variants of a EDA design. +A design then has at least one but usually multiple file sets to group source files and apply settings or attributes to that group.

+
+ graph TD; + Project-->Design_A; + Project-->Design_B; + Design_A-->VHDLLibrary_LA; + Design_A-->FileSet_DefaultA; + Design_A-->FileSet_A1; + Design_A-->FileSet_A2; + FileSet_A2-->FileSet_3 + Design_B-->VHDLLibrary_LB; + Design_B-->FileSet_DefaultB; + Design_B-->FileSet_B1; + Design_B-->FileSet_B2; + FileSet_B2-->FileSet_3 +

Elements of the Project Model

+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/_images/inheritance-063728fd2cfa34a9b138a69dd16f0b4aaea34177.svg b/_images/inheritance-063728fd2cfa34a9b138a69dd16f0b4aaea34177.svg new file mode 100644 index 00000000..736028d9 --- /dev/null +++ b/_images/inheritance-063728fd2cfa34a9b138a69dd16f0b4aaea34177.svg @@ -0,0 +1,14 @@ + + +inheritancee231accfb7 + + +HumanReadableContent + + +HumanReadableContent + + + + + \ No newline at end of file diff --git a/_images/inheritance-2b5d7dabba4a67f31e52f4fed2225d2c7b10765f.svg b/_images/inheritance-2b5d7dabba4a67f31e52f4fed2225d2c7b10765f.svg new file mode 100644 index 00000000..4ed4bcd4 --- /dev/null +++ b/_images/inheritance-2b5d7dabba4a67f31e52f4fed2225d2c7b10765f.svg @@ -0,0 +1,29 @@ + + +inheritanceadcfb8a705 + + +HumanReadableContent + + +HumanReadableContent + + + + + +YAMLContent + + +YAMLContent + + + + + +HumanReadableContent->YAMLContent + + + + + \ No newline at end of file diff --git a/_images/inheritance-5e17d5028d7232bdd5af9819eadc850b34d6ea50.svg b/_images/inheritance-5e17d5028d7232bdd5af9819eadc850b34d6ea50.svg new file mode 100644 index 00000000..f75bfb3c --- /dev/null +++ b/_images/inheritance-5e17d5028d7232bdd5af9819eadc850b34d6ea50.svg @@ -0,0 +1,44 @@ + + +inheritancef5edb30dd4 + + +HumanReadableContent + + +HumanReadableContent + + + + + +TCLContent + + +TCLContent + + + + + +HumanReadableContent->TCLContent + + + + + +SDCContent + + +SDCContent + + + + + +TCLContent->SDCContent + + + + + \ No newline at end of file diff --git a/_images/inheritance-62e8393f7483867bd82a4a8aee4c9456c248b48c.svg b/_images/inheritance-62e8393f7483867bd82a4a8aee4c9456c248b48c.svg new file mode 100644 index 00000000..61b0703b --- /dev/null +++ b/_images/inheritance-62e8393f7483867bd82a4a8aee4c9456c248b48c.svg @@ -0,0 +1,29 @@ + + +inheritancec2c0e419d2 + + +HumanReadableContent + + +HumanReadableContent + + + + + +XMLContent + + +XMLContent + + + + + +HumanReadableContent->XMLContent + + + + + \ No newline at end of file diff --git a/_images/inheritance-669ae4a4c8413fa1c5ec41beb8ba4abadefe0e89.svg b/_images/inheritance-669ae4a4c8413fa1c5ec41beb8ba4abadefe0e89.svg new file mode 100644 index 00000000..8bf4f0a3 --- /dev/null +++ b/_images/inheritance-669ae4a4c8413fa1c5ec41beb8ba4abadefe0e89.svg @@ -0,0 +1,29 @@ + + +inheritancef90e69562f + + +Attribute + + +Attribute + + + + + +KeyValueAttribute + + +KeyValueAttribute + + + + + +Attribute->KeyValueAttribute + + + + + \ No newline at end of file diff --git a/_images/inheritance-66c4490be2acf871df767ef8626ee61f66927fe4.svg b/_images/inheritance-66c4490be2acf871df767ef8626ee61f66927fe4.svg new file mode 100644 index 00000000..5b318e86 --- /dev/null +++ b/_images/inheritance-66c4490be2acf871df767ef8626ee61f66927fe4.svg @@ -0,0 +1,29 @@ + + +inheritanceed0cac69b5 + + +HumanReadableContent + + +HumanReadableContent + + + + + +TCLContent + + +TCLContent + + + + + +HumanReadableContent->TCLContent + + + + + \ No newline at end of file diff --git a/_images/inheritance-6733c60e688669df4d723d030b94b08771b544f0.svg b/_images/inheritance-6733c60e688669df4d723d030b94b08771b544f0.svg new file mode 100644 index 00000000..54bbbab1 --- /dev/null +++ b/_images/inheritance-6733c60e688669df4d723d030b94b08771b544f0.svg @@ -0,0 +1,29 @@ + + +inheritance6b912cd543 + + +ExtendedType + + +ExtendedType + + + + + +FileType + + +FileType + + + + + +ExtendedType->FileType + + + + + \ No newline at end of file diff --git a/_images/inheritance-696f3f531383281156de220e3f4a329f3b18df01.svg b/_images/inheritance-696f3f531383281156de220e3f4a329f3b18df01.svg new file mode 100644 index 00000000..2a379120 --- /dev/null +++ b/_images/inheritance-696f3f531383281156de220e3f4a329f3b18df01.svg @@ -0,0 +1,14 @@ + + +inheritance12f794fece + + +VHDLLibrary + + +VHDLLibrary + + + + + \ No newline at end of file diff --git a/_images/inheritance-79e991b280af2f60f72a974dfab6a6ad6180cf3f.svg b/_images/inheritance-79e991b280af2f60f72a974dfab6a6ad6180cf3f.svg new file mode 100644 index 00000000..8fbb3289 --- /dev/null +++ b/_images/inheritance-79e991b280af2f60f72a974dfab6a6ad6180cf3f.svg @@ -0,0 +1,29 @@ + + +inheritancec6bf2d3a2b + + +HumanReadableContent + + +HumanReadableContent + + + + + +TOMLContent + + +TOMLContent + + + + + +HumanReadableContent->TOMLContent + + + + + \ No newline at end of file diff --git a/_images/inheritance-85176d5ea3073d3dcf002a61a71a122dd17c682c.svg b/_images/inheritance-85176d5ea3073d3dcf002a61a71a122dd17c682c.svg new file mode 100644 index 00000000..22516378 --- /dev/null +++ b/_images/inheritance-85176d5ea3073d3dcf002a61a71a122dd17c682c.svg @@ -0,0 +1,14 @@ + + +inheritance3952958544 + + +Design + + +Design + + + + + \ No newline at end of file diff --git a/_images/inheritance-9fb593524758443f81df0dc757fb7f3be9c4a8b5.svg b/_images/inheritance-9fb593524758443f81df0dc757fb7f3be9c4a8b5.svg new file mode 100644 index 00000000..16664c0e --- /dev/null +++ b/_images/inheritance-9fb593524758443f81df0dc757fb7f3be9c4a8b5.svg @@ -0,0 +1,14 @@ + + +inheritance76eed77688 + + +Project + + +Project + + + + + \ No newline at end of file diff --git a/_images/inheritance-b7906b5ccd5adab45094b626ae926a7ec93ab2fd.svg b/_images/inheritance-b7906b5ccd5adab45094b626ae926a7ec93ab2fd.svg new file mode 100644 index 00000000..684571fa --- /dev/null +++ b/_images/inheritance-b7906b5ccd5adab45094b626ae926a7ec93ab2fd.svg @@ -0,0 +1,29 @@ + + +inheritance874f3aac8d + + +HumanReadableContent + + +HumanReadableContent + + + + + +PythonContent + + +PythonContent + + + + + +HumanReadableContent->PythonContent + + + + + \ No newline at end of file diff --git a/_images/inheritance-c4954f78e088ea69d4e97f665cbf8389a3e1c8a3.svg b/_images/inheritance-c4954f78e088ea69d4e97f665cbf8389a3e1c8a3.svg new file mode 100644 index 00000000..6cd3fe9d --- /dev/null +++ b/_images/inheritance-c4954f78e088ea69d4e97f665cbf8389a3e1c8a3.svg @@ -0,0 +1,29 @@ + + +inheritancecfec5b17ae + + +HumanReadableContent + + +HumanReadableContent + + + + + +JSONContent + + +JSONContent + + + + + +HumanReadableContent->JSONContent + + + + + \ No newline at end of file diff --git a/_images/inheritance-c64c581cc7329aff1cff1a11167eac6255c63094.svg b/_images/inheritance-c64c581cc7329aff1cff1a11167eac6255c63094.svg new file mode 100644 index 00000000..fc53cdb7 --- /dev/null +++ b/_images/inheritance-c64c581cc7329aff1cff1a11167eac6255c63094.svg @@ -0,0 +1,14 @@ + + +inheritance2bb1a068e1 + + +FileSet + + +FileSet + + + + + \ No newline at end of file diff --git a/_images/inheritance-c8269a4789c1b013e14920d9b73a913ecb7ebb41.svg b/_images/inheritance-c8269a4789c1b013e14920d9b73a913ecb7ebb41.svg new file mode 100644 index 00000000..cab7ee23 --- /dev/null +++ b/_images/inheritance-c8269a4789c1b013e14920d9b73a913ecb7ebb41.svg @@ -0,0 +1,29 @@ + + +inheritancee7e42b3f56 + + +HumanReadableContent + + +HumanReadableContent + + + + + +INIContent + + +INIContent + + + + + +HumanReadableContent->INIContent + + + + + \ No newline at end of file diff --git a/_images/inheritance-ca27c3d2d11b97c480dd00c3d05b875293b39e4a.svg b/_images/inheritance-ca27c3d2d11b97c480dd00c3d05b875293b39e4a.svg new file mode 100644 index 00000000..e980641f --- /dev/null +++ b/_images/inheritance-ca27c3d2d11b97c480dd00c3d05b875293b39e4a.svg @@ -0,0 +1,14 @@ + + +inheritance2935b438b8 + + +Attribute + + +Attribute + + + + + \ No newline at end of file diff --git a/_images/inheritance-d7d978395e7c4d6a16eac8705a996b77e789a75e.svg b/_images/inheritance-d7d978395e7c4d6a16eac8705a996b77e789a75e.svg new file mode 100644 index 00000000..c03e734b --- /dev/null +++ b/_images/inheritance-d7d978395e7c4d6a16eac8705a996b77e789a75e.svg @@ -0,0 +1,29 @@ + + +inheritance4df4ad03ac + + +Attribute + + +Attribute + + + + + +UsedInAttribute + + +UsedInAttribute + + + + + +Attribute->UsedInAttribute + + + + + \ No newline at end of file diff --git a/_images/logo_on_light.svg b/_images/logo_on_light.svg new file mode 100644 index 00000000..eac24d90 --- /dev/null +++ b/_images/logo_on_light.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/_modules/index.html b/_modules/index.html new file mode 100644 index 00000000..b7dcc5cf --- /dev/null +++ b/_modules/index.html @@ -0,0 +1,129 @@ + + + + + + Overview: module code — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+
    +
  • »
  • +
  • Overview: module code
  • +
  • +
  • +
+
+
+ +
+
+ +

All modules for which code is available

+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/_modules/pyEDAA/ProjectModel.html b/_modules/pyEDAA/ProjectModel.html new file mode 100644 index 00000000..0ac7efb4 --- /dev/null +++ b/_modules/pyEDAA/ProjectModel.html @@ -0,0 +1,2130 @@ + + + + + + pyEDAA.ProjectModel — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +

Source code for pyEDAA.ProjectModel

+# ==================================================================================================================== #
+#               _____ ____    _        _      ____            _           _   __  __           _      _                #
+#   _ __  _   _| ____|  _ \  / \      / \    |  _ \ _ __ ___ (_) ___  ___| |_|  \/  | ___   __| | ___| |               #
+#  | '_ \| | | |  _| | | | |/ _ \    / _ \   | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ |               #
+#  | |_) | |_| | |___| |_| / ___ \  / ___ \ _|  __/| | | (_) | |  __/ (__| |_| |  | | (_) | (_| |  __/ |               #
+#  | .__/ \__, |_____|____/_/   \_\/_/   \_(_)_|   |_|  \___// |\___|\___|\__|_|  |_|\___/ \__,_|\___|_|               #
+#  |_|    |___/                                            |__/                                                        #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany                                                            #
+# Copyright 2014-2016 Technische Universität Dresden - Germany, Chair of VLSI-Design, Diagnostics and Architecture     #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""An abstract model of EDA tool projects."""
+__author__ =    "Patrick Lehmann"
+__email__ =     "Paebbels@gmail.com"
+__copyright__ = "2014-2023, Patrick Lehmann, Unai Martinez-Corral"
+__license__ =   "Apache License, Version 2.0"
+__version__ =   "0.5.0"
+__keywords__ =  ["eda project", "model", "abstract", "xilinx", "vivado", "osvvm", "file set", "file group", "test bench", "test harness"]
+
+from os.path import relpath as path_relpath
+from pathlib import Path as pathlib_Path
+from typing  import Dict, Union, Optional as Nullable, List, Iterable, Generator, Tuple, Any as typing_Any, Type, Set, Any
+
+from pyTooling.Decorators  import export
+from pyTooling.MetaClasses import ExtendedType
+from pyTooling.Graph       import Graph, Vertex
+from pySVModel             import SystemVerilogVersion
+from pyVHDLModel           import VHDLVersion
+from pySystemRDLModel      import SystemRDLVersion
+
+
+
+[docs] +@export +class Attribute(metaclass=ExtendedType): + KEY: str + VALUE_TYPE: typing_Any + + @staticmethod + def resolve(obj: typing_Any, key: Type['Attribute']): + if isinstance(obj, File): + return obj._fileSet[key] + elif isinstance(obj, FileSet): + return obj._design[key] + elif isinstance(obj, Design): + return obj._project[key] + else: + raise Exception("Resolution error")
+ + + +
+[docs] +@export +class FileType(ExtendedType): + """ + A :term:`meta-class` to construct *FileType* classes. + + Modifications done by this meta-class: + * Register all classes of type :class:`FileType` or derived variants in a class field :attr:`FileType.FileTypes` in this meta-class. + """ + + FileTypes: Dict[str, 'FileType'] = {} #: Dictionary of all classes of type :class:`FileType` or derived variants + Any: 'FileType' + +
+[docs] + def __init__(cls, name: str, bases: Tuple[type, ...], dictionary: Dict[str, typing_Any], **kwargs): + super().__init__(name, bases, dictionary, **kwargs) + cls.Any = cls
+ + +
+[docs] + def __new__(cls, className, baseClasses, classMembers: Dict, *args, **kwargs): + fileType = super().__new__(cls, className, baseClasses, classMembers, *args, **kwargs) + cls.FileTypes[className] = fileType + return fileType
+ + + def __getattr__(cls, item) -> 'FileType': + if item[:2] != "__" and item[-2:] != "__": + return cls.FileTypes[item] + else: + return super().__getattribute__(item) + + def __contains__(cls, item) -> bool: + return issubclass(item, cls)
+ + + +@export +class File(metaclass=FileType, slots=True): + """ + A :term:`File` represents a file in a design. This :term:`base-class` is used + for all derived file classes. + + A file can be created standalone and later associated to a fileset, design and + project. Or a fileset, design and/or project can be associated immediately + while creating a file. + + :arg path: Relative or absolute path to the file. + :arg project: Project the file is associated with. + :arg design: Design the file is associated with. + :arg fileSet: Fileset the file is associated with. + """ + + _path: pathlib_Path + _fileType: 'FileType' + _project: Nullable['Project'] + _design: Nullable['Design'] + _fileSet: Nullable['FileSet'] + _attributes: Dict[Type[Attribute], typing_Any] + + def __init__( + self, + path: pathlib_Path, + project: 'Project' = None, + design: 'Design' = None, + fileSet: 'FileSet' = None + ): + self._fileType = getattr(FileTypes, self.__class__.__name__) + self._path = path + if project is not None: + self._project = project + self._design = design + if fileSet is not None: + self.FileSet = fileSet + elif design is not None: + self._project = design._project + self._design = design + self.FileSet = design.DefaultFileSet if fileSet is None else fileSet + elif fileSet is not None: + design = fileSet._design + if design is not None: + self._project = design._project + else: + self._project = None + self._design = design + self.FileSet = fileSet + else: + self._project = None + self._design = None + self._fileSet = None + + self._attributes = {} + self._registerAttributes() + + def _registerAttributes(self): + pass + + @property + def FileType(self) -> 'FileType': + """Read-only property to return the file type of this file.""" + return self._fileType + + @property + def Path(self) -> pathlib_Path: + """Read-only property returning the path of this file.""" + return self._path + + # TODO: setter? + + @property + def ResolvedPath(self) -> pathlib_Path: + """Read-only property returning the resolved path of this file.""" + if self._path.is_absolute(): + return self._path.resolve() + elif self._fileSet is not None: + path = (self._fileSet.ResolvedPath / self._path).resolve() + + if path.is_absolute(): + return path + else: + # WORKAROUND: https://stackoverflow.com/questions/67452690/pathlib-path-relative-to-vs-os-path-relpath + return pathlib_Path(path_relpath(path, pathlib_Path.cwd())) + else: + # TODO: message and exception type + raise Exception("") + + @property + def Project(self) -> Nullable['Project']: + """Property setting or returning the project this file is used in.""" + return self._project + + @Project.setter + def Project(self, value: 'Project') -> None: + self._project = value + + if self._fileSet is None: + self._project.DefaultDesign.DefaultFileSet.AddFile(self) + + @property + def Design(self) -> Nullable['Design']: + """Property setting or returning the design this file is used in.""" + return self._design + + @Design.setter + def Design(self, value: 'Design') -> None: + self._design = value + + if self._fileSet is None: + self._design.DefaultFileSet.AddFile(self) + + if self._project is None: + self._project = value._project + elif self._project is not value._project: + raise Exception("The design's project is not identical to the already assigned project.") + + @property + def FileSet(self) -> Nullable['FileSet']: + """Property setting or returning the fileset this file is used in.""" + return self._fileSet + + @FileSet.setter + def FileSet(self, value: 'FileSet') -> None: + self._fileSet = value + value._files.append(self) + + def Validate(self): + """Validate this file.""" + if self._path is None: + raise Exception("Validation: File has no path.") + try: + path = self.ResolvedPath + except Exception as ex: + raise Exception(f"Validation: File '{self._path}' could not compute resolved path.") from ex + if not path.exists(): + raise Exception(f"Validation: File '{self._path}' (={path}) does not exist.") + if not path.is_file(): + raise Exception(f"Validation: File '{self._path}' (={path}) is not a file.") + + if self._fileSet is None: + raise Exception(f"Validation: File '{self._path}' has no fileset.") + if self._design is None: + raise Exception(f"Validation: File '{self._path}' has no design.") + if self._project is None: + raise Exception(f"Validation: File '{self._path}' has no project.") + + def __len__(self) -> int: + """ + Returns number of attributes set on this file. + + :returns: The number if attributes set on this file. + """ + return len(self._attributes) + + def __getitem__(self, key: Type[Attribute]) -> Any: + """Index access for returning attributes on this file. + + :param key: The attribute type. + :returns: The attribute's value. + :raises TypeError: When parameter 'key' is not a subclass of Attribute. + """ + if not issubclass(key, Attribute): + raise TypeError("Parameter 'key' is not an 'Attribute'.") + + try: + return self._attributes[key] + except KeyError: + return key.resolve(self, key) + + def __setitem__(self, key: Type[Attribute], value: typing_Any) -> None: + """ + Index access for adding or setting attributes on this file. + + :param key: The attribute type. + :param value: The attributes value. + :raises TypeError: When parameter 'key' is not a subclass of Attribute. + """ + if not issubclass(key, Attribute): + raise TypeError("Parameter 'key' is not an 'Attribute'.") + + self._attributes[key] = value + + def __delitem__(self, key: Type[Attribute]) -> None: + """ + Index access for deleting attributes on this file. + + :param key: The attribute type. + """ + if not issubclass(key, Attribute): + raise TypeError("Parameter 'key' is not an 'Attribute'.") + + del self._attributes[key] + + def __str__(self) -> str: + return f"{self._path}" + + +FileTypes = File + + +
+[docs] +@export +class HumanReadableContent(metaclass=ExtendedType, mixin=True): + """A file type representing human-readable contents."""
+ + + +
+[docs] +@export +class XMLContent(HumanReadableContent, mixin=True): + """A file type representing XML contents."""
+ + + +
+[docs] +@export +class YAMLContent(HumanReadableContent, mixin=True): + """A file type representing YAML contents."""
+ + + +
+[docs] +@export +class JSONContent(HumanReadableContent, mixin=True): + """A file type representing JSON contents."""
+ + + +
+[docs] +@export +class INIContent(HumanReadableContent, mixin=True): + """A file type representing INI contents."""
+ + + +
+[docs] +@export +class TOMLContent(HumanReadableContent, mixin=True): + """A file type representing TOML contents."""
+ + + +
+[docs] +@export +class TCLContent(HumanReadableContent, mixin=True): + """A file type representing content in TCL code."""
+ + + +
+[docs] +@export +class SDCContent(TCLContent, mixin=True): + """A file type representing contents as Synopsys Design Constraints (SDC)."""
+ + + +
+[docs] +@export +class PythonContent(HumanReadableContent, mixin=True): + """A file type representing contents as Python source code."""
+ + + +@export +class TextFile(File, HumanReadableContent): + """A text file (``*.txt``).""" + + +@export +class LogFile(File, HumanReadableContent): + """A log file (``*.log``).""" + + +@export +class XMLFile(File, XMLContent): + """An XML file (``*.xml``).""" + + +@export +class SourceFile(File): + """Base-class of all source files.""" + + +@export +class HDLSourceFile(SourceFile): + """Base-class of all HDL source files.""" + + +@export +class RDLSourceFile(SourceFile): + """Base-class of all RDL source files.""" + + +@export +class NetlistFile(SourceFile): + """Base-class of all netlist source files.""" + + +@export +class EDIFNetlistFile(NetlistFile): + """Netlist file in EDIF (Electronic Design Interchange Format).""" + + +@export +class TCLSourceFile(SourceFile, TCLContent): + """A TCL source file.""" + + +@export +class VHDLSourceFile(HDLSourceFile, HumanReadableContent): + """ + A VHDL source file (of any language version). + + :arg path: Relative or absolute path to the file. + :arg vhdlLibrary: VHDLLibrary this VHDL source file is associated wih. + :arg vhdlVersion: VHDLVersion this VHDL source file is associated wih. + :arg project: Project the file is associated with. + :arg design: Design the file is associated with. + :arg fileSet: Fileset the file is associated with. + """ + + _vhdlLibrary: Nullable['VHDLLibrary'] + _vhdlVersion: VHDLVersion + + def __init__(self, path: pathlib_Path, vhdlLibrary: Union[str, 'VHDLLibrary'] = None, vhdlVersion: VHDLVersion = None, project: 'Project' = None, design: 'Design' = None, fileSet: 'FileSet' = None): + super().__init__(path, project, design, fileSet) + + if isinstance(vhdlLibrary, str): + if design is not None: + try: + vhdlLibrary = design.VHDLLibraries[vhdlLibrary] + except KeyError as ex: + raise Exception(f"VHDL library '{vhdlLibrary}' not found in design '{design.Name}'.") from ex + elif project is not None: + try: + vhdlLibrary = project.DefaultDesign.VHDLLibraries[vhdlLibrary] + except KeyError as ex: + raise Exception(f"VHDL library '{vhdlLibrary}' not found in default design '{project.DefaultDesign.Name}'.") from ex + else: + raise Exception(f"Can't lookup VHDL library because neither 'project' nor 'design' is given as a parameter.") + elif isinstance(vhdlLibrary, VHDLLibrary): + self._vhdlLibrary = vhdlLibrary + vhdlLibrary.AddFile(self) + elif vhdlLibrary is None: + self._vhdlLibrary = None + else: + raise TypeError(f"Parameter 'vhdlLibrary' is neither a 'str' nor 'VHDLibrary'.") + + self._vhdlVersion = vhdlVersion + + def Validate(self) -> None: + """Validate this VHDL source file.""" + super().Validate() + + try: + _ = self.VHDLLibrary + except Exception as ex: + raise Exception(f"Validation: VHDLSourceFile '{self._path}' (={self.ResolvedPath}) has no VHDLLibrary assigned.") from ex + try: + _ = self.VHDLVersion + except Exception as ex: + raise Exception(f"Validation: VHDLSourceFile '{self._path}' (={self.ResolvedPath}) has no VHDLVersion assigned.") from ex + + @property + def VHDLLibrary(self) -> 'VHDLLibrary': + """Property setting or returning the VHDL library this VHDL source file is used in.""" + if self._vhdlLibrary is not None: + return self._vhdlLibrary + elif self._fileSet is not None: + return self._fileSet.VHDLLibrary + else: + raise Exception("VHDLLibrary was neither set locally nor globally.") + + @VHDLLibrary.setter + def VHDLLibrary(self, value: 'VHDLLibrary') -> None: + self._vhdlLibrary = value + value._files.append(self) + + @property + def VHDLVersion(self) -> VHDLVersion: + """Property setting or returning the VHDL version this VHDL source file is used in.""" + if self._vhdlVersion is not None: + return self._vhdlVersion + elif self._fileSet is not None: + return self._fileSet.VHDLVersion + else: + raise Exception("VHDLVersion was neither set locally nor globally.") + + @VHDLVersion.setter + def VHDLVersion(self, value: VHDLVersion) -> None: + self._vhdlVersion = value + + def __repr__(self) -> str: + return f"<VHDL file: '{self.ResolvedPath}'; lib: '{self.VHDLLibrary}'; version: {self.VHDLVersion}>" + + +class VerilogMixIn(metaclass=ExtendedType, mixin=True): + @property + def VerilogVersion(self) -> SystemVerilogVersion: + """Property setting or returning the Verilog version this Verilog source file is used in.""" + if self._version is not None: + return self._version + elif self._fileSet is not None: + return self._fileSet.VerilogVersion + else: + raise Exception("VerilogVersion was neither set locally nor globally.") + + @VerilogVersion.setter + def VerilogVersion(self, value: SystemVerilogVersion) -> None: + self._version = value + + +class SystemVerilogMixIn(metaclass=ExtendedType, mixin=True): + @property + def SVVersion(self) -> SystemVerilogVersion: + """Property setting or returning the SystemVerilog version this SystemVerilog source file is used in.""" + if self._version is not None: + return self._version + elif self._fileSet is not None: + return self._fileSet.SVVersion + else: + raise Exception("SVVersion was neither set locally nor globally.") + + @SVVersion.setter + def SVVersion(self, value: SystemVerilogVersion) -> None: + self._version = value + + +@export +class VerilogBaseFile(HDLSourceFile, HumanReadableContent): + _version: SystemVerilogVersion + + def __init__(self, path: pathlib_Path, version: SystemVerilogVersion = None, project: 'Project' = None, design: 'Design' = None, fileSet: 'FileSet' = None): + super().__init__(path, project, design, fileSet) + + self._version = version + + +@export +class VerilogSourceFile(VerilogBaseFile, VerilogMixIn): + """A Verilog source file (of any language version).""" + + +@export +class VerilogHeaderFile(VerilogBaseFile, VerilogMixIn): + """A Verilog header file (of any language version).""" + + +@export +class SystemVerilogBaseFile(VerilogBaseFile): + ... + + +@export +class SystemVerilogSourceFile(SystemVerilogBaseFile, SystemVerilogMixIn): + """A SystemVerilog source file (of any language version).""" + + +@export +class SystemVerilogHeaderFile(SystemVerilogBaseFile, SystemVerilogMixIn): + """A SystemVerilog header file (of any language version).""" + + +@export +class SystemRDLSourceFile(RDLSourceFile, HumanReadableContent): + """A SystemRDL source file (of any language version).""" + + _srdlVersion: SystemRDLVersion + + def __init__(self, path: pathlib_Path, srdlVersion: SystemRDLVersion = None, project: 'Project' = None, design: 'Design' = None, fileSet: 'FileSet' = None): + super().__init__(path, project, design, fileSet) + + self._srdlVersion = srdlVersion + + @property + def SystemRDLVersion(self) -> SystemRDLVersion: + """Property setting or returning the SystemRDL version this SystemRDL source file is used in.""" + if self._srdlVersion is not None: + return self._srdlVersion + elif self._fileSet is not None: + return self._fileSet.SRDLVersion + else: + raise Exception("SRDLVersion was neither set locally nor globally.") + + @SystemRDLVersion.setter + def SystemRDLVersion(self, value: SystemRDLVersion) -> None: + self._srdlVersion = value + + +@export +class PythonSourceFile(SourceFile, PythonContent): + """A Python source file.""" + + +# TODO: move to a Cocotb module +@export +class CocotbPythonFile(PythonSourceFile): + """A Python source file used by Cocotb.""" + + +@export +class ConstraintFile(File, HumanReadableContent): + """Base-class of all constraint files.""" + + +@export +class ProjectFile(File): + """Base-class of all tool-specific project files.""" + + +@export +class CSourceFile(SourceFile): + """Base-class of all ANSI-C source files.""" + + +@export +class CppSourceFile(SourceFile): + """Base-class of all ANSI-C++ source files.""" + + +@export +class SettingFile(File): + """Base-class of all tool-specific setting files.""" + + +@export +class SimulationAnalysisFile(File): + """Base-class of all tool-specific analysis files.""" + + +@export +class SimulationElaborationFile(File): + """Base-class of all tool-specific elaboration files.""" + + +@export +class SimulationStartFile(File): + """Base-class of all tool-specific simulation start-up files.""" + + +@export +class SimulationRunFile(File): + """Base-class of all tool-specific simulation run (execution) files.""" + + +@export +class WaveformConfigFile(File): + """Base-class of all tool-specific waveform configuration files.""" + + +@export +class WaveformDatabaseFile(File): + """Base-class of all tool-specific waveform database files.""" + + +@export +class WaveformExchangeFile(File): + """Base-class of all tool-independent waveform exchange files.""" + + +
+[docs] +@export +class FileSet(metaclass=ExtendedType, slots=True): + """ + A :term:`FileSet` represents a group of files. Filesets can have sub-filesets. + + The order of insertion is preserved. A fileset can be created standalone and + later associated to another fileset, design and/or project. Or a fileset, + design and/or project can be associated immediately while creating the + fileset. + + :arg name: Name of this fileset. + :arg topLevel: Name of the fileset's toplevel. + :arg directory: Path of this fileset (absolute or relative to a parent fileset or design). + :arg project: Project the file is associated with. + :arg design: Design the file is associated with. + :arg parent: Parent fileset if this fileset is nested. + :arg vhdlLibrary: Default VHDL library for files in this fileset, if not specified for the file itself. + :arg vhdlVersion: Default VHDL version for files in this fileset, if not specified for the file itself. + :arg verilogVersion: Default Verilog version for files in this fileset, if not specified for the file itself. + :arg svVersion: Default SystemVerilog version for files in this fileset, if not specified for the file itself. + :arg srdlVersion: Default SystemRDL version for files in this fileset, if not specified for the file itself. + """ + + _name: str + _topLevel: Nullable[str] + _project: Nullable['Project'] + _design: Nullable['Design'] + _directory: pathlib_Path + _parent: Nullable['FileSet'] + _fileSets: Dict[str, 'FileSet'] + _files: List[File] + _set: Set + _attributes: Dict[Type[Attribute], typing_Any] + _vhdlLibraries: Dict[str, 'VHDLLibrary'] + _vhdlLibrary: 'VHDLLibrary' + _vhdlVersion: VHDLVersion + _verilogVersion: SystemVerilogVersion + _svVersion: SystemVerilogVersion + _srdlVersion: SystemRDLVersion + +
+[docs] + def __init__( + self, + name: str, + topLevel: str = None, + directory: pathlib_Path = pathlib_Path("."), + project: 'Project' = None, + design: 'Design' = None, + parent: Nullable['FileSet'] = None, + vhdlLibrary: Union[str, 'VHDLLibrary'] = None, + vhdlVersion: VHDLVersion = None, + verilogVersion: SystemVerilogVersion = None, + svVersion: SystemVerilogVersion = None, + srdlVersion: SystemRDLVersion = None + ): + self._name = name + self._topLevel = topLevel + if project is not None: + self._project = project + self._design = design if design is not None else project.DefaultDesign + + elif design is not None: + self._project = design._project + self._design = design + else: + self._project = None + self._design = None + self._directory = directory + self._parent = parent + self._fileSets = {} + self._files = [] + self._set = set() + + if design is not None: + design._fileSets[name] = self + + self._attributes = {} + self._vhdlLibraries = {} + + # TODO: handle if vhdlLibrary is a string + self._vhdlLibrary = vhdlLibrary + self._vhdlVersion = vhdlVersion + self._verilogVersion = verilogVersion + self._svVersion = svVersion + self._srdlVersion = srdlVersion
+ + + @property + def Name(self) -> str: + """Property setting or returning the fileset's name.""" + return self._name + + @Name.setter + def Name(self, value: str) -> None: + self._name = value + + @property + def TopLevel(self) -> str: + """Property setting or returning the fileset's toplevel.""" + return self._topLevel + + @TopLevel.setter + def TopLevel(self, value: str) -> None: + self._topLevel = value + + @property + def Project(self) -> Nullable['Project']: + """Property setting or returning the project this fileset is used in.""" + return self._project + + @Project.setter + def Project(self, value: 'Project') -> None: + self._project = value + + @property + def Design(self) -> Nullable['Design']: + """Property setting or returning the design this fileset is used in.""" + if self._design is not None: + return self._design + elif self._parent is not None: + return self._parent.Design + else: + return None + # TODO: raise exception instead + # QUESTION: how to handle if design and parent is set? + + @Design.setter + def Design(self, value: 'Design') -> None: + self._design = value + if self._project is None: + self._project = value._project + elif self._project is not value._project: + raise Exception("The design's project is not identical to the already assigned project.") + + @property + def Directory(self) -> pathlib_Path: + """Property setting or returning the directory this fileset is located in.""" + return self._directory + + @Directory.setter + def Directory(self, value: pathlib_Path) -> None: + self._directory = value + + @property + def ResolvedPath(self) -> pathlib_Path: + """Read-only property returning the resolved path of this fileset.""" + if self._directory.is_absolute(): + return self._directory.resolve() + else: + if self._parent is not None: + directory = self._parent.ResolvedPath + elif self._design is not None: + directory = self._design.ResolvedPath + elif self._project is not None: + directory = self._project.ResolvedPath + else: + # TODO: message and exception type + raise Exception("") + + directory = (directory / self._directory).resolve() + if directory.is_absolute(): + return directory + else: + # WORKAROUND: https://stackoverflow.com/questions/67452690/pathlib-path-relative-to-vs-os-path-relpath + return pathlib_Path(path_relpath(directory, pathlib_Path.cwd())) + + @property + def Parent(self) -> Nullable['FileSet']: + """Property setting or returning the parent fileset this fileset is used in.""" + return self._parent + + @Parent.setter + def Parent(self, value: 'FileSet') -> None: + self._parent = value + value._fileSets[self._name] = self + # TODO: check it it already exists + # QUESTION: make an Add fileset method? + + @property + def FileSets(self) -> Dict[str, 'FileSet']: + """Read-only property returning the dictionary of sub-filesets.""" + return self._fileSets + +
+[docs] + def Files(self, fileType: FileType = FileTypes.Any, fileSet: Union[bool, str, 'FileSet'] = None) -> Generator[File, None, None]: + """ + Method returning the files of this fileset. + + :arg fileType: A filter for file types. Default: ``Any``. + :arg fileSet: Specifies how to handle sub-filesets. + """ + if fileSet is False: + for file in self._files: + if file.FileType in fileType: + yield file + elif fileSet is None: + for fileSet in self._fileSets.values(): + for file in fileSet.Files(fileType): + yield file + for file in self._files: + if file.FileType in fileType: + yield file + else: + if isinstance(fileSet, str): + fileSetName = fileSet + try: + fileSet = self._fileSets[fileSetName] + except KeyError as ex: + raise Exception(f"Fileset {fileSetName} not bound to fileset {self.Name}.") from ex + elif not isinstance(fileSet, FileSet): + raise TypeError("Parameter 'fileSet' is not of type 'str' or 'FileSet' nor value 'None'.") + + for file in fileSet.Files(fileType): + yield file
+ + +
+[docs] + def AddFileSet(self, fileSet: "FileSet") -> None: + """ + Method to add a single sub-fileset to this fileset. + + :arg fileSet: A fileset to add to this fileset as sub-fileset. + """ + if not isinstance(fileSet, FileSet): + raise ValueError("Parameter 'fileSet' is not of type ProjectModel.FileSet.") + elif fileSet in self._fileSets: + raise Exception("Sub-fileset already contains this fileset.") + elif fileSet.Name in self._fileSets.keys(): + raise Exception(f"Fileset already contains a sub-fileset named '{fileSet.Name}'.") + + self._fileSets[fileSet.Name] = fileSet + fileSet._parent = self
+ + +
+[docs] + def AddFileSets(self, fileSets: Iterable["FileSet"]) -> None: + """ + Method to add a multiple sub-filesets to this fileset. + + :arg fileSets: An iterable of filesets to add each to the fileset. + """ + for fileSet in fileSets: + self.AddFileSet(fileSet)
+ + + @property + def FileSetCount(self) -> int: + """Returns number of file sets excl. sub-filesets.""" + return len(self._fileSets) + + @property + def TotalFileSetCount(self) -> int: + """Returns number of file sets incl. sub-filesets.""" + fileSetCount = len(self._fileSets) + for fileSet in self._fileSets.values(): + fileSetCount += fileSet.TotalFileSetCount + + return fileSetCount + +
+[docs] + def AddFile(self, file: File) -> None: + """ + Method to add a single file to this fileset. + + :arg file: A file to add to this fileset. + """ + if not isinstance(file, File): + raise TypeError("Parameter 'file' is not of type ProjectModel.File.") + elif file._fileSet is not None: + ex = ValueError(f"File '{file.Path!s}' is already part of fileset '{file.FileSet.Name}'.") + ex.add_note(f"A file can't be assigned to another fileset.") + raise ex + elif file in self._set: + ex = ValueError(f"File '{file.Path!s}' is already part of this fileset.") + ex.add_note(f"A file can't be added twice to a fileset.") + raise ex + + self._files.append(file) + self._set.add(file) + file._fileSet = self
+ + +
+[docs] + def AddFiles(self, files: Iterable[File]) -> None: + """ + Method to add a multiple files to this fileset. + + :arg files: An iterable of files to add each to the fileset. + """ + for file in files: + self.AddFile(file)
+ + + @property + def FileCount(self) -> int: + """Returns number of files excl. sub-filesets.""" + return len(self._files) + + @property + def TotalFileCount(self) -> int: + """Returns number of files incl. the files in sub-filesets.""" + fileCount = len(self._files) + for fileSet in self._fileSets.values(): + fileCount += fileSet.FileCount + + return fileCount + +
+[docs] + def Validate(self) -> None: + """Validate this fileset.""" + if self._name is None or self._name == "": + raise Exception("Validation: FileSet has no name.") + + if self._directory is None: + raise Exception(f"Validation: FileSet '{self._name}' has no directory.") + try: + path = self.ResolvedPath + except Exception as ex: + raise Exception(f"Validation: FileSet '{self._name}' could not compute resolved path.") from ex + if not path.exists(): + raise Exception(f"Validation: FileSet '{self._name}'s directory '{path}' does not exist.") + if not path.is_dir(): + raise Exception(f"Validation: FileSet '{self._name}'s directory '{path}' is not a directory.") + + if self._design is None: + raise Exception(f"Validation: FileSet '{self._directory}' has no design.") + if self._project is None: + raise Exception(f"Validation: FileSet '{self._directory}' has no project.") + + for fileSet in self._fileSets.values(): + fileSet.Validate() + for file in self._files: + file.Validate()
+ + + def GetOrCreateVHDLLibrary(self, name) -> 'VHDLLibrary': + if name in self._vhdlLibraries: + return self._vhdlLibraries[name] + elif name in self._design._vhdlLibraries: + library = self._design._vhdlLibraries[name] + self._vhdlLibraries[name] = library + return library + else: + library = VHDLLibrary(name, design=self._design, vhdlVersion=self._vhdlVersion) + self._vhdlLibraries[name] = library + return library + + @property + def VHDLLibrary(self) -> 'VHDLLibrary': + """Property setting or returning the VHDL library of this fileset.""" + if self._vhdlLibrary is not None: + return self._vhdlLibrary + elif self._parent is not None: + return self._parent.VHDLLibrary + elif self._design is not None: + return self._design.VHDLLibrary + else: + raise Exception("VHDLLibrary was neither set locally nor globally.") + + @VHDLLibrary.setter + def VHDLLibrary(self, value: 'VHDLLibrary') -> None: + self._vhdlLibrary = value + + @property + def VHDLVersion(self) -> VHDLVersion: + """Property setting or returning the VHDL version of this fileset.""" + if self._vhdlVersion is not None: + return self._vhdlVersion + elif self._parent is not None: + return self._parent.VHDLVersion + elif self._design is not None: + return self._design.VHDLVersion + else: + raise Exception("VHDLVersion was neither set locally nor globally.") + + @VHDLVersion.setter + def VHDLVersion(self, value: VHDLVersion) -> None: + self._vhdlVersion = value + + @property + def VerilogVersion(self) -> SystemVerilogVersion: + """Property setting or returning the Verilog version of this fileset.""" + if self._verilogVersion is not None: + return self._verilogVersion + elif self._parent is not None: + return self._parent.VerilogVersion + elif self._design is not None: + return self._design.VerilogVersion + else: + raise Exception("VerilogVersion was neither set locally nor globally.") + + @VerilogVersion.setter + def VerilogVersion(self, value: SystemVerilogVersion) -> None: + self._verilogVersion = value + + @property + def SVVersion(self) -> SystemVerilogVersion: + """Property setting or returning the SystemVerilog version of this fileset.""" + if self._svVersion is not None: + return self._svVersion + elif self._parent is not None: + return self._parent.SVVersion + elif self._design is not None: + return self._design.SVVersion + else: + raise Exception("SVVersion was neither set locally nor globally.") + + @SVVersion.setter + def SVVersion(self, value: SystemVerilogVersion) -> None: + self._svVersion = value + + @property + def SRDLVersion(self) -> SystemRDLVersion: + if self._srdlVersion is not None: + return self._srdlVersion + elif self._parent is not None: + return self._parent.SRDLVersion + elif self._design is not None: + return self._design.SRDLVersion + else: + raise Exception("SRDLVersion was neither set locally nor globally.") + + @SRDLVersion.setter + def SRDLVersion(self, value: SystemRDLVersion) -> None: + self._srdlVersion = value + +
+[docs] + def __len__(self) -> int: + """ + Returns number of attributes set on this fileset. + + :returns: The number if attributes set on this fileset. + """ + return len(self._attributes)
+ + +
+[docs] + def __getitem__(self, key: Type[Attribute]) -> Any: + """Index access for returning attributes on this fileset. + + :param key: The attribute type. + :returns: The attribute's value. + :raises TypeError: When parameter 'key' is not a subclass of Attribute. + """ + if not issubclass(key, Attribute): + raise TypeError("Parameter 'key' is not an 'Attribute'.") + + try: + return self._attributes[key] + except KeyError: + return key.resolve(self, key)
+ + +
+[docs] + def __setitem__(self, key: Type[Attribute], value: typing_Any) -> None: + """ + Index access for adding or setting attributes on this fileset. + + :param key: The attribute type. + :param value: The attributes value. + :raises TypeError: When parameter 'key' is not a subclass of Attribute. + """ + if not issubclass(key, Attribute): + raise TypeError("Parameter 'key' is not an 'Attribute'.") + + self._attributes[key] = value
+ + +
+[docs] + def __delitem__(self, key: Type[Attribute]) -> None: + """ + Index access for deleting attributes on this fileset. + + :param key: The attribute type. + """ + if not issubclass(key, Attribute): + raise TypeError("Parameter 'key' is not an 'Attribute'.") + + del self._attributes[key]
+ + +
+[docs] + def __str__(self) -> str: + """Returns the fileset's name.""" + return self._name
+
+ + + +
+[docs] +@export +class VHDLLibrary(metaclass=ExtendedType, slots=True): + """ + A :term:`VHDLLibrary` represents a group of VHDL source files compiled into the same VHDL library. + + :arg name: The VHDL libraries' name. + :arg project: Project the VHDL library is associated with. + :arg design: Design the VHDL library is associated with. + :arg vhdlVersion: Default VHDL version for files in this VHDL library, if not specified for the file itself. + """ + + _name: str + _project: Nullable['Project'] + _design: Nullable['Design'] + _files: List[File] + _vhdlVersion: VHDLVersion + + _dependencyNode: Vertex + +
+[docs] + def __init__( + self, + name: str, + project: 'Project' = None, + design: 'Design' = None, + vhdlVersion: VHDLVersion = None + ): + self._name = name + if project is not None: + self._project = project + self._design = project._defaultDesign if design is None else design + self._dependencyNode = Vertex(value=self, graph=self._design._vhdlLibraryDependencyGraph) + + if name in self._design._vhdlLibraries: + raise Exception(f"Library '{name}' already in design '{self._design.Name}'.") + else: + self._design._vhdlLibraries[name] = self + + elif design is not None: + self._project = design._project + self._design = design + self._dependencyNode = Vertex(value=self, graph=design._vhdlLibraryDependencyGraph) + + if name in design._vhdlLibraries: + raise Exception(f"Library '{name}' already in design '{design.Name}'.") + else: + design._vhdlLibraries[name] = self + + else: + self._project = None + self._design = None + self._dependencyNode = None + + self._files = [] + self._vhdlVersion = vhdlVersion
+ + + @property + def Name(self) -> str: + return self._name + + @property + def Project(self) -> Nullable['Project']: + """Property setting or returning the project this VHDL library is used in.""" + return self._project + + @Project.setter + def Project(self, value: 'Project') -> None: + if not isinstance(value, Project): + raise TypeError("Parameter 'value' is not of type 'Project'.") + + if value is None: + # TODO: unlink VHDLLibrary from project + self._project = None + else: + self._project = value + if self._design is None: + self._design = value._defaultDesign + + @property + def Design(self) -> Nullable['Design']: + """Property setting or returning the design this VHDL library is used in.""" + return self._design + + @Design.setter + def Design(self, value: 'Design') -> None: + if not isinstance(value, Design): + raise TypeError("Parameter 'value' is not of type 'Design'.") + + if value is None: + # TODO: unlink VHDLLibrary from design + self._design = None + else: + if self._design is None: + self._design = value + self._dependencyNode = Vertex(value=self, graph=self._design._vhdlLibraryDependencyGraph) + elif self._design is not value: + # TODO: move VHDLLibrary to other design + # TODO: create new vertex in dependency graph and remove vertex from old graph + self._design = value + else: + pass + + if self._project is None: + self._project = value._project + elif self._project is not value._project: + raise Exception("The design's project is not identical to the already assigned project.") + + @property + def Files(self) -> Generator[File, None, None]: + """Read-only property to return all files in this VHDL library.""" + for file in self._files: + yield file + + @property + def VHDLVersion(self) -> VHDLVersion: + """Property setting or returning the VHDL version of this VHDL library.""" + if self._vhdlVersion is not None: + return self._vhdlVersion + elif self._design is not None: + return self._design.VHDLVersion + else: + raise Exception("VHDLVersion is not set on VHDLLibrary nor parent object.") + + @VHDLVersion.setter + def VHDLVersion(self, value: VHDLVersion) -> None: + self._vhdlVersion = value + + def AddDependency(self, library: 'VHDLLibrary') -> None: + library.parent = self + + def AddFile(self, vhdlFile: VHDLSourceFile) -> None: + if not isinstance(vhdlFile, VHDLSourceFile): + raise TypeError(f"Parameter 'vhdlFile' is not a 'VHDLSourceFile'.") + + self._files.append(vhdlFile) + + def AddFiles(self, vhdlFiles: Iterable[VHDLSourceFile]) -> None: + for vhdlFile in vhdlFiles: + if not isinstance(vhdlFile, VHDLSourceFile): + raise TypeError(f"Item '{vhdlFile}' in parameter 'vhdlFiles' is not a 'VHDLSourceFile'.") + + self._files.append(vhdlFile) + + @property + def FileCount(self) -> int: + """Returns number of files.""" + return len(self._files) + +
+[docs] + def __len__(self) -> int: + """ + Returns number of attributes set on this VHDL library. + + :returns: The number if attributes set on this VHDL library. + """ + return len(self._attributes)
+ + +
+[docs] + def __getitem__(self, key: Type[Attribute]) -> Any: + """Index access for returning attributes on this VHDL library. + + :param key: The attribute type. + :returns: The attribute's value. + :raises TypeError: When parameter 'key' is not a subclass of Attribute. + """ + if not issubclass(key, Attribute): + raise TypeError("Parameter 'key' is not an 'Attribute'.") + + try: + return self._attributes[key] + except KeyError: + return key.resolve(self, key)
+ + +
+[docs] + def __setitem__(self, key: Type[Attribute], value: typing_Any) -> None: + """ + Index access for adding or setting attributes on this VHDL library. + + :param key: The attribute type. + :param value: The attributes value. + :raises TypeError: When parameter 'key' is not a subclass of Attribute. + """ + if not issubclass(key, Attribute): + raise TypeError("Parameter 'key' is not an 'Attribute'.") + + self._attributes[key] = value
+ + +
+[docs] + def __delitem__(self, key: Type[Attribute]) -> None: + """ + Index access for deleting attributes on this VHDL library. + + :param key: The attribute type. + """ + if not issubclass(key, Attribute): + raise TypeError("Parameter 'key' is not an 'Attribute'.") + + del self._attributes[key]
+ + +
+[docs] + def __str__(self) -> str: + """Returns the VHDL library's name.""" + return self._name
+
+ + + +
+[docs] +@export +class Design(metaclass=ExtendedType, slots=True): + """ + A :term:`Design` represents a group of filesets and the source files therein. + + Each design contains at least one fileset - the :term:`default fileset`. For + designs with VHDL source files, a independent `VHDLLibraries` overlay structure + exists. + + :arg name: The design's name. + :arg topLevel: Name of the design's toplevel. + :arg directory: Path of this design (absolute or relative to the project). + :arg project: Project the design is associated with. + :arg vhdlVersion: Default VHDL version for files in this design, if not specified for the file itself. + :arg verilogVersion: Default Verilog version for files in this design, if not specified for the file itself. + :arg svVersion: Default SystemVerilog version for files in this design, if not specified for the file itself. + :arg srdlVersion: Default SystemRDL version for files in this fileset, if not specified for the file itself. + """ + + _name: str + _topLevel: Nullable[str] + _project: Nullable['Project'] + _directory: pathlib_Path + _fileSets: Dict[str, FileSet] + _defaultFileSet: Nullable[FileSet] + _attributes: Dict[Type[Attribute], typing_Any] + + _vhdlLibraries: Dict[str, VHDLLibrary] + _vhdlVersion: VHDLVersion + _verilogVersion: SystemVerilogVersion + _svVersion: SystemVerilogVersion + _srdlVersion: SystemRDLVersion + _externalVHDLLibraries: List + + _vhdlLibraryDependencyGraph: Graph + _fileDependencyGraph: Graph + +
+[docs] + def __init__( + self, + name: str, + topLevel: str = None, + directory: pathlib_Path = pathlib_Path("."), + project: 'Project' = None, + vhdlVersion: VHDLVersion = None, + verilogVersion: SystemVerilogVersion = None, + svVersion: SystemVerilogVersion = None, + srdlVersion: SystemRDLVersion = None + ): + self._name = name + self._topLevel = topLevel + self._project = project + if project is not None: + project._designs[name] = self + self._directory = directory + self._fileSets = {} + self._defaultFileSet = FileSet("default", project=project, design=self) + self._attributes = {} + self._vhdlLibraries = {} + self._vhdlVersion = vhdlVersion + self._verilogVersion = verilogVersion + self._svVersion = svVersion + self._srdlVersion = srdlVersion + self._externalVHDLLibraries = [] + + self._vhdlLibraryDependencyGraph = Graph() + self._fileDependencyGraph = Graph()
+ + + @property + def Name(self) -> str: + """Property setting or returning the design's name.""" + return self._name + + @Name.setter + def Name(self, value: str) -> None: + self._name = value + + @property + def TopLevel(self) -> str: + """Property setting or returning the fileset's toplevel.""" + return self._topLevel + + @TopLevel.setter + def TopLevel(self, value: str) -> None: + self._topLevel = value + + @property + def Project(self) -> Nullable['Project']: + """Property setting or returning the project this design is used in.""" + return self._project + + @Project.setter + def Project(self, value: 'Project') -> None: + self._project = value + + @property + def Directory(self) -> pathlib_Path: + """Property setting or returning the directory this design is located in.""" + return self._directory + + @Directory.setter + def Directory(self, value: pathlib_Path) -> None: + self._directory = value + + @property + def ResolvedPath(self) -> pathlib_Path: + """Read-only property returning the resolved path of this fileset.""" + if self._directory.is_absolute(): + return self._directory.resolve() + elif self._project is not None: + path = (self._project.ResolvedPath / self._directory).resolve() + + if path.is_absolute(): + return path + else: + # WORKAROUND: https://stackoverflow.com/questions/67452690/pathlib-path-relative-to-vs-os-path-relpath + return pathlib_Path(path_relpath(path, pathlib_Path.cwd())) + else: + # TODO: message and exception type + raise Exception("") + + @property + def DefaultFileSet(self) -> FileSet: + """Property setting or returning the default fileset of this design.""" + return self._defaultFileSet + + @DefaultFileSet.setter + def DefaultFileSet(self, value: Union[str, FileSet]) -> None: + if isinstance(value, str): + if value not in self._fileSets.keys(): + raise Exception(f"Fileset '{value}' is not in this design.") + + self._defaultFileSet = self._fileSets[value] + elif isinstance(value, FileSet): + if value not in self.FileSets: + raise Exception(f"Fileset '{value}' is not associated to this design.") + + self._defaultFileSet = value + else: + raise ValueError("Unsupported parameter type for 'value'.") + + # TODO: return generator with another method + @property + def FileSets(self) -> Dict[str, FileSet]: + """Read-only property returning the dictionary of filesets.""" + return self._fileSets + +
+[docs] + def Files(self, fileType: FileType = FileTypes.Any, fileSet: Union[str, FileSet] = None) -> Generator[File, None, None]: + """ + Method returning the files of this design. + + :arg fileType: A filter for file types. Default: ``Any``. + :arg fileSet: Specifies if all files from all filesets (``fileSet=None``) are files from a single fileset are returned. + """ + if fileSet is None: + for fileSet in self._fileSets.values(): + for file in fileSet.Files(fileType): + yield file + else: + if isinstance(fileSet, str): + try: + fileSet = self._fileSets[fileSet] + except KeyError as ex: + raise Exception(f"Fileset {fileSet.Name} not bound to design {self.Name}.") from ex + elif not isinstance(fileSet, FileSet): + raise TypeError("Parameter 'fileSet' is not of type 'str' or 'FileSet' nor value 'None'.") + + for file in fileSet.Files(fileType): + yield file
+ + +
+[docs] + def Validate(self) -> None: + """Validate this design.""" + if self._name is None or self._name == "": + raise Exception("Validation: Design has no name.") + + if self._directory is None: + raise Exception(f"Validation: Design '{self._name}' has no directory.") + try: + path = self.ResolvedPath + except Exception as ex: + raise Exception(f"Validation: Design '{self._name}' could not compute resolved path.") from ex + if not path.exists(): + raise Exception(f"Validation: Design '{self._name}'s directory '{path}' does not exist.") + if not path.is_dir(): + raise Exception(f"Validation: Design '{self._name}'s directory '{path}' is not a directory.") + + if len(self._fileSets) == 0: + raise Exception(f"Validation: Design '{self._name}' has no fileset.") + try: + if self._defaultFileSet is not self._fileSets[self._defaultFileSet.Name]: + raise Exception(f"Validation: Design '{self._name}'s default fileset is the same as listed in filesets.") + except KeyError as ex: + raise Exception(f"Validation: Design '{self._name}'s default fileset is not in list of filesets.") from ex + if self._project is None: + raise Exception(f"Validation: Design '{self._path}' has no project.") + + for fileSet in self._fileSets.values(): + fileSet.Validate()
+ + + @property + def VHDLLibraries(self) -> Dict[str, VHDLLibrary]: + return self._vhdlLibraries + + @property + def VHDLVersion(self) -> VHDLVersion: + if self._vhdlVersion is not None: + return self._vhdlVersion + elif self._project is not None: + return self._project.VHDLVersion + else: + raise Exception("VHDLVersion was neither set locally nor globally.") + + @VHDLVersion.setter + def VHDLVersion(self, value: VHDLVersion) -> None: + self._vhdlVersion = value + + @property + def VerilogVersion(self) -> SystemVerilogVersion: + if self._verilogVersion is not None: + return self._verilogVersion + elif self._project is not None: + return self._project.VerilogVersion + else: + raise Exception("VerilogVersion was neither set locally nor globally.") + + @VerilogVersion.setter + def VerilogVersion(self, value: SystemVerilogVersion) -> None: + self._verilogVersion = value + + @property + def SVVersion(self) -> SystemVerilogVersion: + if self._svVersion is not None: + return self._svVersion + elif self._project is not None: + return self._project.SVVersion + else: + raise Exception("SVVersion was neither set locally nor globally.") + + @SVVersion.setter + def SVVersion(self, value: SystemVerilogVersion) -> None: + self._svVersion = value + + @property + def SRDLVersion(self) -> SystemRDLVersion: + if self._srdlVersion is not None: + return self._srdlVersion + elif self._project is not None: + return self._project.SRDLVersion + else: + raise Exception("SRDLVersion was neither set locally nor globally.") + + @SRDLVersion.setter + def SRDLVersion(self, value: SystemRDLVersion) -> None: + self._srdlVersion = value + + @property + def ExternalVHDLLibraries(self) -> List: + return self._externalVHDLLibraries + + def AddFileSet(self, fileSet: FileSet) -> None: + if not isinstance(fileSet, FileSet): + raise ValueError("Parameter 'fileSet' is not of type ProjectModel.FileSet.") + elif fileSet in self._fileSets: + raise Exception("Design already contains this fileset.") + elif fileSet.Name in self._fileSets.keys(): + raise Exception(f"Design already contains a fileset named '{fileSet.Name}'.") + + self._fileSets[fileSet.Name] = fileSet + fileSet.Design = self + fileSet._parent = self + + def AddFileSets(self, fileSets: Iterable[FileSet]) -> None: + for fileSet in fileSets: + self.AddFileSet(fileSet) + + @property + def FileSetCount(self) -> int: + """Returns number of file sets excl. sub-filesets.""" + return len(self._fileSets) + + @property + def TotalFileSetCount(self) -> int: + """Returns number of file sets incl. sub-filesets.""" + fileSetCount = len(self._fileSets) + for fileSet in self._fileSets.values(): + fileSetCount += fileSet.TotalFileSetCount + + return fileSetCount + + def AddFile(self, file: File) -> None: + if file.FileSet is None: + self._defaultFileSet.AddFile(file) + else: + raise ValueError(f"File '{file.Path!s}' is already part of fileset '{file.FileSet.Name}' and can't be assigned via Design to a default fileset.") + + def AddFiles(self, files: Iterable[File]) -> None: + for file in files: + self.AddFile(file) + + def AddVHDLLibrary(self, vhdlLibrary: VHDLLibrary) -> None: + if vhdlLibrary.Name in self._vhdlLibraries: + if self._vhdlLibraries[vhdlLibrary.Name] is vhdlLibrary: + raise Exception(f"The VHDLLibrary '{vhdlLibrary.Name}' was already added to the design.") + else: + raise Exception(f"A VHDLLibrary with same name ('{vhdlLibrary.Name}') already exists for this design.") + + +
+[docs] + def __len__(self) -> int: + """ + Returns number of attributes set on this design. + + :returns: The number if attributes set on this design. + """ + return len(self._attributes)
+ + +
+[docs] + def __getitem__(self, key: Type[Attribute]) -> Any: + """Index access for returning attributes on this design. + + :param key: The attribute type. + :returns: The attribute's value. + :raises TypeError: When parameter 'key' is not a subclass of Attribute. + """ + if not issubclass(key, Attribute): + raise TypeError("Parameter 'key' is not an 'Attribute'.") + + try: + return self._attributes[key] + except KeyError: + return key.resolve(self, key)
+ + +
+[docs] + def __setitem__(self, key: Type[Attribute], value: typing_Any) -> None: + """ + Index access for adding or setting attributes on this design. + + :param key: The attribute type. + :param value: The attributes value. + :raises TypeError: When parameter 'key' is not a subclass of Attribute. + """ + if not issubclass(key, Attribute): + raise TypeError("Parameter 'key' is not an 'Attribute'.") + + self._attributes[key] = value
+ + +
+[docs] + def __delitem__(self, key: Type[Attribute]) -> None: + """ + Index access for deleting attributes on this design. + + :param key: The attribute type. + """ + if not issubclass(key, Attribute): + raise TypeError("Parameter 'key' is not an 'Attribute'.") + + del self._attributes[key]
+ + +
+[docs] + def __str__(self) -> str: + return self._name
+
+ + + +
+[docs] +@export +class Project(metaclass=ExtendedType, slots=True): + """ + A :term:`Project` represents a group of designs and the source files therein. + + :arg name: The project's name. + :arg rootDirectory: Base-path to the project. + :arg vhdlVersion: Default VHDL version for files in this project, if not specified for the file itself. + :arg verilogVersion: Default Verilog version for files in this project, if not specified for the file itself. + :arg svVersion: Default SystemVerilog version for files in this project, if not specified for the file itself. + """ + + _name: str + _rootDirectory: pathlib_Path + _designs: Dict[str, Design] + _defaultDesign: Design + _attributes: Dict[Type[Attribute], typing_Any] + + _vhdlVersion: VHDLVersion + _verilogVersion: SystemVerilogVersion + _svVersion: SystemVerilogVersion + _srdlVersion: SystemRDLVersion + +
+[docs] + def __init__( + self, + name: str, + rootDirectory: pathlib_Path = pathlib_Path("."), + vhdlVersion: VHDLVersion = None, + verilogVersion: SystemVerilogVersion = None, + svVersion: SystemVerilogVersion = None + ): + self._name = name + self._rootDirectory = rootDirectory + self._designs = {} + self._defaultDesign = Design("default", project=self) + self._attributes = {} + self._vhdlVersion = vhdlVersion + self._verilogVersion = verilogVersion + self._svVersion = svVersion
+ + + @property + def Name(self) -> str: + """Property setting or returning the project's name.""" + return self._name + + @property + def RootDirectory(self) -> pathlib_Path: + """Property setting or returning the root directory this project is located in.""" + return self._rootDirectory + + @RootDirectory.setter + def RootDirectory(self, value: pathlib_Path) -> None: + self._rootDirectory = value + + @property + def ResolvedPath(self) -> pathlib_Path: + """Read-only property returning the resolved path of this fileset.""" + path = self._rootDirectory.resolve() + if self._rootDirectory.is_absolute(): + return path + else: + # WORKAROUND: https://stackoverflow.com/questions/67452690/pathlib-path-relative-to-vs-os-path-relpath + return pathlib_Path(path_relpath(path, pathlib_Path.cwd())) + + # TODO: return generator with another method + @property + def Designs(self) -> Dict[str, Design]: + return self._designs + + @property + def DefaultDesign(self) -> Design: + return self._defaultDesign + +
+[docs] + def Validate(self) -> None: + """Validate this project.""" + if self._name is None or self._name == "": + raise Exception("Validation: Project has no name.") + + if self._rootDirectory is None: + raise Exception(f"Validation: Project '{self._name}' has no root directory.") + try: + path = self.ResolvedPath + except Exception as ex: + raise Exception(f"Validation: Project '{self._name}' could not compute resolved path.") from ex + if not path.exists(): + raise Exception(f"Validation: Project '{self._name}'s directory '{path}' does not exist.") + if not path.is_dir(): + raise Exception(f"Validation: Project '{self._name}'s directory '{path}' is not a directory.") + + if len(self._designs) == 0: + raise Exception(f"Validation: Project '{self._name}' has no design.") + try: + if self._defaultDesign is not self._designs[self._defaultDesign.Name]: + raise Exception(f"Validation: Project '{self._name}'s default design is the same as listed in designs.") + except KeyError as ex: + raise Exception(f"Validation: Project '{self._name}'s default design is not in list of designs.") from ex + + for design in self._designs.values(): + design.Validate()
+ + + @property + def DesignCount(self) -> int: + """Returns number of designs.""" + return len(self._designs) + + @property + def VHDLVersion(self) -> VHDLVersion: + # TODO: check for None and return exception + return self._vhdlVersion + + @VHDLVersion.setter + def VHDLVersion(self, value: VHDLVersion) -> None: + self._vhdlVersion = value + + @property + def VerilogVersion(self) -> SystemVerilogVersion: + # TODO: check for None and return exception + return self._verilogVersion + + @VerilogVersion.setter + def VerilogVersion(self, value: SystemVerilogVersion) -> None: + self._verilogVersion = value + + @property + def SVVersion(self) -> SystemVerilogVersion: + # TODO: check for None and return exception + return self._svVersion + + @SVVersion.setter + def SVVersion(self, value: SystemVerilogVersion) -> None: + self._svVersion = value + + @property + def SRDLVersion(self) -> SystemRDLVersion: + # TODO: check for None and return exception + return self._srdlVersion + + @SRDLVersion.setter + def SRDLVersion(self, value: SystemRDLVersion) -> None: + self._srdlVersion = value + +
+[docs] + def __len__(self) -> int: + """ + Returns number of attributes set on this project. + + :returns: The number if attributes set on this project. + """ + return len(self._attributes)
+ + +
+[docs] + def __getitem__(self, key: Type[Attribute]) -> Any: + """Index access for returning attributes on this project. + + :param key: The attribute type. + :returns: The attribute's value. + :raises TypeError: When parameter 'key' is not a subclass of Attribute. + """ + if not issubclass(key, Attribute): + raise TypeError("Parameter 'key' is not an 'Attribute'.") + + try: + return self._attributes[key] + except KeyError: + return key.resolve(self, key)
+ + +
+[docs] + def __setitem__(self, key: Type[Attribute], value: typing_Any) -> None: + """ + Index access for adding or setting attributes on this project. + + :param key: The attribute type. + :param value: The attributes value. + :raises TypeError: When parameter 'key' is not a subclass of Attribute. + """ + if not issubclass(key, Attribute): + raise TypeError("Parameter 'key' is not an 'Attribute'.") + + self._attributes[key] = value
+ + +
+[docs] + def __delitem__(self, key: Type[Attribute]) -> None: + """ + Index access for deleting attributes on this project. + + :param key: The attribute type. + """ + if not issubclass(key, Attribute): + raise TypeError("Parameter 'key' is not an 'Attribute'.") + + del self._attributes[key]
+ + +
+[docs] + def __str__(self) -> str: + return self._name
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/_modules/pyEDAA/ProjectModel/Attributes.html b/_modules/pyEDAA/ProjectModel/Attributes.html new file mode 100644 index 00000000..29c4d85b --- /dev/null +++ b/_modules/pyEDAA/ProjectModel/Attributes.html @@ -0,0 +1,187 @@ + + + + + + pyEDAA.ProjectModel.Attributes — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +

Source code for pyEDAA.ProjectModel.Attributes

+# ==================================================================================================================== #
+#               _____ ____    _        _      ____            _           _   __  __           _      _                #
+#   _ __  _   _| ____|  _ \  / \      / \    |  _ \ _ __ ___ (_) ___  ___| |_|  \/  | ___   __| | ___| |               #
+#  | '_ \| | | |  _| | | | |/ _ \    / _ \   | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ |               #
+#  | |_) | |_| | |___| |_| / ___ \  / ___ \ _|  __/| | | (_) | |  __/ (__| |_| |  | | (_) | (_| |  __/ |               #
+#  | .__/ \__, |_____|____/_/   \_\/_/   \_(_)_|   |_|  \___// |\___|\___|\__|_|  |_|\___/ \__,_|\___|_|               #
+#  |_|    |___/                                            |__/                                                        #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany                                                            #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""A set of common attributes to store meta information on ProjectModel entities (project, design, fileset, file, ...)."""
+from typing               import Dict
+from pyTooling.Decorators import export
+
+from pyEDAA.ProjectModel  import Attribute
+
+
+
+[docs] +@export +class KeyValueAttribute(Attribute): + KEY = "ID" + + _keyValuePairs: Dict[str, str] + +
+[docs] + def __init__(self): + super().__init__() + + self._keyValuePairs = {}
+ + + def __getitem__(self, item: str) -> str: + return self._keyValuePairs[item] + + def __setitem__(self, key: str, value: str) -> None: + self._keyValuePairs[key] = value
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/_modules/pyEDAA/ProjectModel/Xilinx/Vivado.html b/_modules/pyEDAA/ProjectModel/Xilinx/Vivado.html new file mode 100644 index 00000000..5704d1f4 --- /dev/null +++ b/_modules/pyEDAA/ProjectModel/Xilinx/Vivado.html @@ -0,0 +1,336 @@ + + + + + + pyEDAA.ProjectModel.Xilinx.Vivado — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +

Source code for pyEDAA.ProjectModel.Xilinx.Vivado

+# ==================================================================================================================== #
+#               _____ ____    _        _      ____            _           _   __  __           _      _                #
+#   _ __  _   _| ____|  _ \  / \      / \    |  _ \ _ __ ___ (_) ___  ___| |_|  \/  | ___   __| | ___| |               #
+#  | '_ \| | | |  _| | | | |/ _ \    / _ \   | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ |               #
+#  | |_) | |_| | |___| |_| / ___ \  / ___ \ _|  __/| | | (_) | |  __/ (__| |_| |  | | (_) | (_| |  __/ |               #
+#  | .__/ \__, |_____|____/_/   \_\/_/   \_(_)_|   |_|  \___// |\___|\___|\__|_|  |_|\___/ \__,_|\___|_|               #
+#  |_|    |___/                                            |__/                                                        #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany                                                            #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""Specific file types and attributes for Xilinx Vivado."""
+from pathlib import Path
+from typing import Iterable
+
+from xml.dom import minidom, Node
+
+from pyTooling.MetaClasses import ExtendedType
+from pyVHDLModel import VHDLVersion
+from pyTooling.Decorators import export
+
+from pyEDAA.ProjectModel import ProjectFile, XMLFile, XMLContent, SDCContent, Project, FileSet, Attribute, Design
+from pyEDAA.ProjectModel import File as Model_File
+from pyEDAA.ProjectModel import ConstraintFile as Model_ConstraintFile
+from pyEDAA.ProjectModel import VerilogSourceFile as Model_VerilogSourceFile
+from pyEDAA.ProjectModel import VHDLSourceFile as Model_VHDLSourceFile
+
+
+
+[docs] +@export +class UsedInAttribute(Attribute): + KEY = "UsedIn" + VALUE_TYPE = Iterable[str]
+ + + +@export +class File(Model_File): + pass + + +class VivadoFileMixIn(metaclass=ExtendedType, mixin=True): + def _registerAttributes(self): + self._attributes[UsedInAttribute] = [] + + +@export +class ConstraintFile(Model_ConstraintFile, VivadoFileMixIn): + def _registerAttributes(self): + super()._registerAttributes() + VivadoFileMixIn._registerAttributes(self) + + +@export +class VerilogSourceFile(Model_VerilogSourceFile): + def _registerAttributes(self): + super()._registerAttributes() + VivadoFileMixIn._registerAttributes(self) + + +@export +class VHDLSourceFile(Model_VHDLSourceFile): + def _registerAttributes(self): + super()._registerAttributes() + VivadoFileMixIn._registerAttributes(self) + + +@export +class VivadoProjectFile(ProjectFile, XMLContent): + """A Vivado project file (``*.xpr``).""" + + _xprProject: Project + + def __init__( + self, + path: Path, + project: Project = None, + design: Design = None, + fileSet: FileSet = None + ): + super().__init__(path, project, design, fileSet) + + self._xprProject = None + + @property + def ProjectModel(self) -> Project: + return self._xprProject + + def Parse(self): + if not self._path.exists(): + raise Exception(f"Vivado project file '{self._path!s}' not found.") from FileNotFoundError(f"File '{self._path!s}' not found.") + + try: + root = minidom.parse(str(self._path)).documentElement + except Exception as ex: + raise Exception(f"Couldn't open '{self._path!s}'.") from ex + + self._xprProject = Project(self._path.stem, rootDirectory=self._path.parent) + self._ParseRootElement(root) + + def _ParseRootElement(self, root): + for rootNode in root.childNodes: + if rootNode.nodeName == "FileSets": + self._ParseFileSets(rootNode) + break + + def _ParseFileSets(self, filesetsNode): + for fileSetsNode in filesetsNode.childNodes: + if fileSetsNode.nodeType == Node.ELEMENT_NODE and fileSetsNode.tagName == "FileSet": + self._ParseFileSet(fileSetsNode) + + def _ParseFileSet(self, filesetNode): + filesetName = filesetNode.getAttribute("Name") + fileset = FileSet(filesetName, design=self._xprProject.DefaultDesign) + + for fileNode in filesetNode.childNodes: + if fileNode.nodeType == Node.ELEMENT_NODE: + if fileNode.tagName == "File": + self._ParseFile(fileNode, fileset) + elif fileNode.nodeType == Node.ELEMENT_NODE and fileNode.tagName == "Config": + self._ParseFileSetConfig(fileNode, fileset) + + def _ParseFile(self, fileNode, fileset): + croppedPath = fileNode.getAttribute("Path").replace("$PPRDIR/", "") + filePath = Path(croppedPath) + if filePath.suffix in (".vhd", ".vhdl"): + self._ParseVHDLFile(fileNode, filePath, fileset) + elif filePath.suffix == ".xdc": + self._ParseXDCFile(fileNode, filePath, fileset) + elif filePath.suffix == ".v": + self._ParseVerilogFile(fileNode, filePath, fileset) + elif filePath.suffix == ".xci": + self._ParseXCIFile(fileNode, filePath, fileset) + else: + self._ParseDefaultFile(fileNode, filePath, fileset) + + def _ParseVHDLFile(self, fileNode, path, fileset): + vhdlFile = VHDLSourceFile(path) + fileset.AddFile(vhdlFile) + usedInAttr = vhdlFile[UsedInAttribute] + + for childNode in fileNode.childNodes: + if childNode.nodeType == Node.ELEMENT_NODE and childNode.tagName == "FileInfo": + if childNode.getAttribute("SFType") == "VHDL2008": + vhdlFile.VHDLVersion = VHDLVersion.VHDL2008 + else: + vhdlFile.VHDLVersion = VHDLVersion.VHDL93 + + for fileAttribute in childNode.childNodes: + if fileAttribute.nodeType == Node.ELEMENT_NODE and fileAttribute.tagName == "Attr": + if fileAttribute.getAttribute("Name") == "Library": + libraryName = fileAttribute.getAttribute("Val") + vhdlFile.VHDLLibrary = fileset.GetOrCreateVHDLLibrary(libraryName) + elif fileAttribute.getAttribute("Val") == "UsedIn": + usedInAttr.append(fileAttribute.getAttribute("Val")) + + def _ParseDefaultFile(self, _, path, fileset): + File(path, fileSet=fileset) + + def _ParseXDCFile(self, _, path, fileset): + XDCConstraintFile(path, fileSet=fileset) + + def _ParseVerilogFile(self, _, path, fileset): + VerilogSourceFile(path, fileSet=fileset) + + def _ParseXCIFile(self, _, path, fileset): + IPCoreInstantiationFile(path, fileSet=fileset) + + def _ParseFileSetConfig(self, fileNode, fileset): + for option in fileNode.childNodes: + if option.nodeType == Node.ELEMENT_NODE and option.tagName == "Option": + if option.getAttribute("Name") == "TopModule": + fileset.TopLevel = option.getAttribute("Val") + + +@export +class XDCConstraintFile(ConstraintFile, SDCContent): + """A Vivado constraint file (Xilinx Design Constraints; ``*.xdc``).""" + + +@export +class IPCoreDescriptionFile(XMLFile): + pass + + +@export +class IPCoreInstantiationFile(XMLFile): + """A Vivado IP core instantiation file (Xilinx IPCore Instance; ``*.xci``).""" +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/_sources/ChangeLog/index.rst.txt b/_sources/ChangeLog/index.rst.txt new file mode 100644 index 00000000..168996de --- /dev/null +++ b/_sources/ChangeLog/index.rst.txt @@ -0,0 +1,12 @@ +ChangeLog +######### + +Upcoming Release +================ + +* tbd + +01.09.2021 +========== + +`pyEDAA.ProjectModel` was split from `pyIPCMI` (v1.1.6) as an independent Python package. diff --git a/_sources/Dependency.rst.txt b/_sources/Dependency.rst.txt new file mode 100644 index 00000000..b50b55f9 --- /dev/null +++ b/_sources/Dependency.rst.txt @@ -0,0 +1,172 @@ +.. _dependency: + +Dependency +########## + +.. |img-ProjectModel-lib-status| image:: https://img.shields.io/librariesio/release/pypi/pyEDAA.ProjectModel + :alt: Libraries.io status for latest release + :height: 22 + :target: https://libraries.io/github/edaa-org/pyEDAA.ProjectModel +.. |img-ProjectModel-req-status| image:: https://img.shields.io/requires/github/edaa-org/pyEDAA.ProjectModel + :alt: Requires.io + :height: 22 + :target: https://requires.io/github/edaa-org/pyEDAA.ProjectModel/requirements/?branch=main + ++------------------------------------------+------------------------------------------+ +| `Libraries.io `_ | `Requires.io `_ | ++==========================================+==========================================+ +| |img-ProjectModel-lib-status| | |img-ProjectModel-req-status| | ++------------------------------------------+------------------------------------------+ + + +.. _dependency-package: + +pyEDAA.ProjectModel Package +*************************** + ++------------------------------------------------------------------------+-------------+-------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Package** | **Version** | **License** | **Dependencies** | ++========================================================================+=============+===========================================================================================+========================================================================================================================================================+ +| `pyTooling `__ | ≥5.0.0 | `Apache License, 2.0 `__ | *None* | ++------------------------------------------------------------------------+-------------+-------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+ +| `pyVHDLModel `__ | ≥0.27.1 | `Apache License, 2.0 `__ | * `pyTooling `__ (`Apache License, 2.0 `__) | ++------------------------------------------------------------------------+-------------+-------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+ +| `pySVModel `__ | ≥0.3.1 | `Apache License, 2.0 `__ | * `pyTooling `__ (`Apache License, 2.0 `__) | ++------------------------------------------------------------------------+-------------+-------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+ +| `pySystemRDLModel `__ | ≥0.1.0 | `Apache License, 2.0 `__ | * `pyTooling `__ (`Apache License, 2.0 `__) | ++------------------------------------------------------------------------+-------------+-------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+ + + +.. _dependency-testing: + +Unit Testing / Coverage / Type Checking (Optional) +************************************************** + +Additional Python packages needed for testing, code coverage collection and static type checking. These packages are +only needed for developers or on a CI server, thus sub-dependencies are not evaluated further. + + +.. rubric:: Manually Installing Test Requirements + +Use the :file:`tests/requirements.txt` file to install all dependencies via ``pip3``. The file will recursively install +the mandatory dependencies too. + +.. code-block:: shell + + pip3 install -U -r tests/requirements.txt + + +.. rubric:: Dependency List + ++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ +| **Package** | **Version** | **License** | **Dependencies** | ++=====================================================================+=============+========================================================================================+======================+ +| `pytest `__ | ≥7.4.0 | `MIT `__ | *Not yet evaluated.* | ++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ +| `pytest-cov `__ | ≥4.1.0 | `MIT `__ | *Not yet evaluated.* | ++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ +| `Coverage `__ | ≥7.3 | `Apache License, 2.0 `__ | *Not yet evaluated.* | ++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ +| `mypy `__ | ≥1.5 | `MIT `__ | *Not yet evaluated.* | ++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ +| `typing-extensions `__ | ≥4.7.1 | `PSF-2.0 `__ | *Not yet evaluated.* | ++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ +| `lxml `__ | ≥4.9 | `BSD 3-Clause `__ | *Not yet evaluated.* | ++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ + + +.. _dependency-documentation: + +Sphinx Documentation (Optional) +******************************* + +Additional Python packages needed for documentation generation. These packages are only needed for developers or on a +CI server, thus sub-dependencies are not evaluated further. + + +.. rubric:: Manually Installing Documentation Requirements + +Use the :file:`doc/requirements.txt` file to install all dependencies via ``pip3``. The file will recursively install +the mandatory dependencies too. + +.. code-block:: shell + + pip3 install -U -r doc/requirements.txt + + +.. rubric:: Dependency List + ++-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Package** | **Version** | **License** | **Dependencies** | ++=================================================================================================+==============+==========================================================================================================+======================================================================================================================================================+ +| `pyTooling `__ | ≥5.0.0 | `Apache License, 2.0 `__ | *None* | ++-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ +| `Sphinx `__ | ≥5.3.0 | `BSD 3-Clause `__ | *Not yet evaluated.* | ++-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ +| `sphinx_btd_theme `__ | ≥0.5.2 | `MIT `__ | *Not yet evaluated.* | ++-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ +| !! `sphinx_fontawesome `__ | ≥0.0.6 | `GPL 2.0 `__ | *Not yet evaluated.* | ++-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ +| `sphinx_autodoc_typehints `__ | ≥1.19.5 | `MIT `__ | *Not yet evaluated.* | ++-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ + + +.. _dependency-packaging: + +Packaging (Optional) +******************** + +Additional Python packages needed for installation package generation. These packages are only needed for developers or +on a CI server, thus sub-dependencies are not evaluated further. + + +.. rubric:: Manually Installing Packaging Requirements + +Use the :file:`build/requirements.txt` file to install all dependencies via ``pip3``. The file will recursively +install the mandatory dependencies too. + +.. code-block:: shell + + pip3 install -U -r build/requirements.txt + + +.. rubric:: Dependency List + ++----------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Package** | **Version** | **License** | **Dependencies** | ++============================================================================+==============+==========================================================================================================+======================================================================================================================================================+ +| `pyTooling `__ | ≥5.0.0 | `Apache License, 2.0 `__ | *None* | ++----------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ +| `wheel `__ | ≥0.40.0 | `MIT `__ | *Not yet evaluated.* | ++----------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ + + +.. _dependency-publishing: + +Publishing (CI-Server only) +*************************** + +Additional Python packages needed for publishing the generated installation package to e.g, PyPI or any equivalent +services. These packages are only needed for maintainers or on a CI server, thus sub-dependencies are not evaluated +further. + + +.. rubric:: Manually Installing Publishing Requirements + +Use the :file:`dist/requirements.txt` file to install all dependencies via ``pip3``. The file will recursively +install the mandatory dependencies too. + +.. code-block:: shell + + pip3 install -U -r dist/requirements.txt + + +.. rubric:: Dependency List + ++----------------------------------------------------------+--------------+-------------------------------------------------------------------------------------------+----------------------+ +| **Package** | **Version** | **License** | **Dependencies** | ++==========================================================+==============+===========================================================================================+======================+ +| `wheel `__ | ≥0.40.0 | `MIT `__ | *Not yet evaluated.* | ++----------------------------------------------------------+--------------+-------------------------------------------------------------------------------------------+----------------------+ +| `Twine `__ | ≥4.0.2 | `Apache License, 2.0 `__ | *Not yet evaluated.* | ++----------------------------------------------------------+--------------+-------------------------------------------------------------------------------------------+----------------------+ diff --git a/_sources/Doc-License.rst.txt b/_sources/Doc-License.rst.txt new file mode 100644 index 00000000..1258fbc2 --- /dev/null +++ b/_sources/Doc-License.rst.txt @@ -0,0 +1,353 @@ +.. _DOCLICENSE: + +.. Note:: This is a local copy of the `Creative Commons - Attribution 4.0 International (CC BY 4.0) `__. + +.. Attention:: This **CC BY 4.0** license applies only to the **documentation** of this project. + + +Creative Commons Attribution 4.0 International +############################################## + +Creative Commons Corporation (“Creative Commons”) is not a law firm and does not +provide legal services or legal advice. Distribution of Creative Commons public +licenses does not create a lawyer-client or other relationship. Creative Commons +makes its licenses and related information available on an “as-is” basis. +Creative Commons gives no warranties regarding its licenses, any material +licensed under their terms and conditions, or any related information. Creative +Commons disclaims all liability for damages resulting from their use to the +fullest extent possible. + +.. topic:: Using Creative Commons Public Licenses + + Creative Commons public licenses provide a standard set of terms and conditions + that creators and other rights holders may use to share original works of + authorship and other material subject to copyright and certain other rights + specified in the public license below. The following considerations are for + informational purposes only, are not exhaustive, and do not form part of our + licenses. + + * **Considerations for licensors:** Our public licenses are intended for use + by those authorized to give the public permission to use material in ways + otherwise restricted by copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms and conditions + of the license they choose before applying it. Licensors should also secure + all rights necessary before applying our licenses so that the public can reuse + the material as expected. Licensors should clearly mark any material not + subject to the license. This includes other CC-licensed material, or material + used under an exception or limitation to copyright. + `More considerations for licensors `__. + + * **Considerations for the public:** By using one of our public licenses, a + licensor grants the public permission to use the licensed material under + specified terms and conditions. If the licensor’s permission is not necessary + for any reason–for example, because of any applicable exception or limitation + to copyright–then that use is not regulated by the license. Our licenses grant + only permissions under copyright and certain other rights that a licensor has + authority to grant. Use of the licensed material may still be restricted for + other reasons, including because others have copyright or other rights in the + material. A licensor may make special requests, such as asking that all + changes be marked or described. Although not required by our licenses, you are + encouraged to respect those requests where reasonable. + `More considerations for the public `__. + +:xlarge:`Creative Commons Attribution 4.0 International Public License` + +By exercising the Licensed Rights (defined below), You accept and agree to be +bound by the terms and conditions of this Creative Commons Attribution 4.0 +International Public License ("Public License"). To the extent this Public +License may be interpreted as a contract, You are granted the Licensed Rights +in consideration of Your acceptance of these terms and conditions, and the +Licensor grants You such rights in consideration of benefits the Licensor +receives from making the Licensed Material available under these terms and +conditions. + +Section 1 – Definitions. +======================== + +a. **Adapted Material** means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material and in + which the Licensed Material is translated, altered, arranged, transformed, or + otherwise modified in a manner requiring permission under the Copyright and + Similar Rights held by the Licensor. For purposes of this Public License, + where the Licensed Material is a musical work, performance, or sound + recording, Adapted Material is always produced where the Licensed Material + is synched in timed relation with a moving image. + +b. **Adapter's License** means the license You apply to Your Copyright and + Similar Rights in Your contributions to Adapted Material in accordance with + the terms and conditions of this Public License. + +c. **Copyright and Similar Rights** means copyright and/or similar rights + closely related to copyright including, without limitation, performance, + broadcast, sound recording, and Sui Generis Database Rights, without regard + to how the rights are labeled or categorized. For purposes of this Public + License, the rights specified in Section 2(b)(1)-(2) are not Copyright and + Similar Rights. + +d. **Effective Technological Measures** means those measures that, in the + absence of proper authority, may not be circumvented under laws fulfilling + obligations under Article 11 of the WIPO Copyright Treaty adopted on + December 20, 1996, and/or similar international agreements. + +e. **Exceptions and Limitations** means fair use, fair dealing, and/or any + other exception or limitation to Copyright and Similar Rights that applies to + Your use of the Licensed Material. + +f. **Licensed Material** means the artistic or literary work, database, or + other material to which the Licensor applied this Public License. + +g. **Licensed Rights** means the rights granted to You subject to the terms + and conditions of this Public License, which are limited to all Copyright and + Similar Rights that apply to Your use of the Licensed Material and that the + Licensor has authority to license. + +h. **Licensor** means the individual(s) or entity(ies) granting rights under + this Public License. + +i. **Share** means to provide material to the public by any means or process + that requires permission under the Licensed Rights, such as reproduction, + public display, public performance, distribution, dissemination, + communication, or importation, and to make material available to the public + including in ways that members of the public may access the material from a + place and at a time individually chosen by them. + +j. **Sui Generis Database Rights** means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of the + Council of 11 March 1996 on the legal protection of databases, as amended + and/or succeeded, as well as other essentially equivalent rights anywhere + in the world. + +k. **You** means the individual or entity exercising the Licensed Rights + under this Public License. **Your** has a corresponding meaning. + +Section 2 – Scope. +================== + +a. **License grant.** + + 1. Subject to the terms and conditions of this Public License, the Licensor + hereby grants You a worldwide, royalty-free, non-sublicensable, + non-exclusive, irrevocable license to exercise the Licensed Rights in the + Licensed Material to: + + A. reproduce and Share the Licensed Material, in whole or in part; and + + B. produce, reproduce, and Share Adapted Material. + + 2. :underline:`Exceptions and Limitations.` For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public License does not + apply, and You do not need to comply with its terms and conditions. + + 3. :underline:`Term.` The term of this Public License is specified in Section 6(a). + + 4. :underline:`Media and formats`; :underline:`technical modifications allowed.` The Licensor + authorizes You to exercise the Licensed Rights in all media and formats + whether now known or hereafter created, and to make technical + modifications necessary to do so. The Licensor waives and/or agrees not to + assert any right or authority to forbid You from making technical + modifications necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective Technological + Measures. For purposes of this Public License, simply making modifications + authorized by this Section 2(a)(4) never produces Adapted Material. + + 5. :underline:`Downstream recipients.` + + A. :underline:`Offer from the Licensor – Licensed Material.` Every recipient of + the Licensed Material automatically receives an offer from the + Licensor to exercise the Licensed Rights under the terms and + conditions of this Public License. + + B. :underline:`No downstream restrictions.` You may not offer or impose any + additional or different terms or conditions on, or apply any Effective + Technological Measures to, the Licensed Material if doing so restricts + exercise of the Licensed Rights by any recipient of the Licensed + Material. + + 6. :underline:`No endorsement.` Nothing in this Public License constitutes or may + be construed as permission to assert or imply that You are, or that Your + use of the Licensed Material is, connected with, or sponsored, endorsed, + or granted official status by, the Licensor or others designated to + receive attribution as provided in Section 3(a)(1)(A)(i). + +b. **Other rights.** + + 1. Moral rights, such as the right of integrity, are not licensed under this + Public License, nor are publicity, privacy, and/or other similar + personality rights; however, to the extent possible, the Licensor waives + and/or agrees not to assert any such rights held by the Licensor to the + limited extent necessary to allow You to exercise the Licensed Rights, but + not otherwise. + + 2. Patent and trademark rights are not licensed under this Public License. + + 3. To the extent possible, the Licensor waives any right to collect royalties + from You for the exercise of the Licensed Rights, whether directly or + through a collecting society under any voluntary or waivable statutory or + compulsory licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + +Section 3 – License Conditions. +=============================== + +Your exercise of the Licensed Rights is expressly made subject to the following conditions. + +a. **Attribution.** + + 1. If You Share the Licensed Material (including in modified form), You must: + + A. retain the following if it is supplied by the Licensor with the + Licensed Material: + + i. identification of the creator(s) of the Licensed Material and any + others designated to receive attribution, in any reasonable manner + requested by the Licensor (including by pseudonym if designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of warranties; + + v. a URI or hyperlink to the Licensed Material to the extent reasonably + practicable; + + B. indicate if You modified the Licensed Material and retain an + indication of any previous modifications; and + + C. indicate the Licensed Material is licensed under this Public License, + and include the text of, or the URI or hyperlink to, this Public + License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner + based on the medium, means, and context in which You Share the Licensed + Material. For example, it may be reasonable to satisfy the conditions by + providing a URI or hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the information + required by Section 3(a)(1)(A) to the extent reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's License You apply + must not prevent recipients of the Adapted Material from complying with + this Public License. + +Section 4 – Sui Generis Database Rights. +======================================== + +Where the Licensed Rights include Sui Generis Database Rights that apply to Your +use of the Licensed Material: + +a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, + reuse, reproduce, and Share all or a substantial portion of the contents of + the database; + +b. if You include all or a substantial portion of the database contents in a + database in which You have Sui Generis Database Rights, then the database + in which You have Sui Generis Database Rights (but not its individual + contents) is Adapted Material; and + +c. You must comply with the conditions in Section 3(a) if You Share all or a + substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not replace +Your obligations under this Public License where the Licensed Rights include +other Copyright and Similar Rights. + +Section 5 – Disclaimer of Warranties and Limitation of Liability. +================================================================= + +a. **Unless otherwise separately undertaken by the Licensor, to the extent + possible, the Licensor offers the Licensed Material as-is and as-available, + and makes no representations or warranties of any kind concerning the + Licensed Material, whether express, implied, statutory, or other. This + includes, without limitation, warranties of title, merchantability, + fitness for a particular purpose, non-infringement, absence of latent or + other defects, accuracy, or the presence or absence of errors, whether or + not known or discoverable. Where disclaimers of warranties are not allowed + in full or in part, this disclaimer may not apply to You.** + +b. **To the extent possible, in no event will the Licensor be liable to You + on any legal theory (including, without limitation, negligence) or + otherwise for any direct, special, indirect, incidental, consequential, + punitive, exemplary, or other losses, costs, expenses, or damages arising + out of this Public License or use of the Licensed Material, even if the + Licensor has been advised of the possibility of such losses, costs, expenses, + or damages. Where a limitation of liability is not allowed in full or in + part, this limitation may not apply to You.** + +c. The disclaimer of warranties and limitation of liability provided above + shall be interpreted in a manner that, to the extent possible, most + closely approximates an absolute disclaimer and waiver of all liability. + +Section 6 – Term and Termination. +================================= + +a. This Public License applies for the term of the Copyright and Similar Rights + licensed here. However, if You fail to comply with this Public License, then + Your rights under this Public License terminate automatically. + +b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided it is cured + within 30 days of Your discovery of the violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any right the + Licensor may have to seek remedies for Your violations of this Public License. + +c. For the avoidance of doubt, the Licensor may also offer the Licensed Material + under separate terms or conditions or stop distributing the Licensed Material + at any time; however, doing so will not terminate this Public License. + +d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. + +Section 7 – Other Terms and Conditions. +======================================= + +a. The Licensor shall not be bound by any additional or different terms or + conditions communicated by You unless expressly agreed. + +b. Any arrangements, understandings, or agreements regarding the Licensed + Material not stated herein are separate from and independent of the terms + and conditions of this Public License. + +Section 8 – Interpretation. +=========================== + +a. For the avoidance of doubt, this Public License does not, and shall not be + interpreted to, reduce, limit, restrict, or impose conditions on any use of + the Licensed Material that could lawfully be made without permission under + this Public License. + +b. To the extent possible, if any provision of this Public License is deemed + unenforceable, it shall be automatically reformed to the minimum extent + necessary to make it enforceable. If the provision cannot be reformed, it + shall be severed from this Public License without affecting the + enforceability of the remaining terms and conditions. + +c. No term or condition of this Public License will be waived and no failure to + comply consented to unless expressly agreed to by the Licensor. + +d. Nothing in this Public License constitutes or may be interpreted as a + limitation upon, or waiver of, any privileges and immunities that apply to + the Licensor or You, including from the legal processes of any jurisdiction + or authority. + +------------------ + +Creative Commons is not a party to its public licenses. Notwithstanding, +Creative Commons may elect to apply one of its public licenses to material it +publishes and in those instances will be considered the “Licensor.” Except for +the limited purpose of indicating that material is shared under a Creative +Commons public license or as otherwise permitted by the Creative Commons +policies published at `creativecommons.org/policies `__, +Creative Commons does not authorize the use of the trademark “Creative Commons” +or any other trademark or logo of Creative Commons without its prior written +consent including, without limitation, in connection with any unauthorized +modifications to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For the +avoidance of doubt, this paragraph does not form part of the public licenses. + +Creative Commons may be contacted at `creativecommons.org `__ diff --git a/_sources/FileTypes/index.rst.txt b/_sources/FileTypes/index.rst.txt new file mode 100644 index 00000000..099191e0 --- /dev/null +++ b/_sources/FileTypes/index.rst.txt @@ -0,0 +1,50 @@ +.. _filetypes: + +File Types +########## + +.. rubric:: Design Goal + +TBD + +Content Types +============= + +.. mermaid:: + + graph TD; + HRC[HumanReadableContent] --> XMLC[XMLContent]; + HRC --> YAMLC[YAMLContent]; + HRC --> JSONC[JSONContent]; + HRC --> INIC[INIContent]; + HRC --> TOMLC[TOMLContent]; + HRC --> TCLC[TCLContent] --> SDCC[SDCContent]; + + +Overall Hierarchy +================= + +.. mermaid:: + + graph TD; + File-->TextFile; + File-->LogFile; + File-->XMLFile; + File--->SourceFile; + File-->ConstraintFile; + File-->ProjectFile; + File-->SettingFile; + SourceFile-->HDLSourceFile; + SourceFile-->NetlistFile; + NetlistFile-->EDIFNetlistFile; + HDLSourceFile-->VHDLSourceFile; + HDLSourceFile-->VerilogSourceFile; + HDLSourceFile-->SystemVerilogSourceFile; + SourceFile-->PythonSourceFile; + PythonSourceFile-->CocotbSourceFile + SourceFile-->CSourceFile; + SourceFile-->CppSourceFile; + +.. # + autoclasstree:: pyEDAA.ProjectModel.Design + :full: diff --git a/_sources/Glossary.rst.txt b/_sources/Glossary.rst.txt new file mode 100644 index 00000000..955197ce --- /dev/null +++ b/_sources/Glossary.rst.txt @@ -0,0 +1,45 @@ +Glossary +######## + +.. glossary:: + + LRM + *Language Reference Manual* is the name given to IEEE Standard documents defining Hardware Description Languages: + + * VHDL LRM revisions: + + * `1076-2019 `__. + * `1076-2008 `__ aka IEC 61691-1-1:2011. + * `1076-2002 `__ aka IEC 61691-1-1 Ed.1 (2004-10). + * `1076-2000 `__. + * `1076-1993 `__. + * `1076-1987 `__. + + * Verilog LRM revisions: + + *TBC* + + * System Verilog LRM revisions: + + *TBC* + + base-class + An ancestor class for other derived classes. + + File + A representation of a physical file. + + FileSet + A group of files. + + Default fileset + If no fileset is specified, the pre-existing fileset named ``default`` is used to group files. + + VHDLLibrary + A namespace in VHDL to group and organize VHDL design units (entity, package, configuration, context). + + Design + A ... + + Project + A ... diff --git a/_sources/Installation.rst.txt b/_sources/Installation.rst.txt new file mode 100644 index 00000000..77c65b60 --- /dev/null +++ b/_sources/Installation.rst.txt @@ -0,0 +1,60 @@ +.. _installation: + +Installation/Updates +#################### + +.. note:: + + Python ≥3.7 is required for this package due to problems with meta classes and + ``__getattr__`` in Python 3.6. + +.. _installation-pip: + +Using PIP +********* + +Installation from PyPI using PIP +================================ + +.. code-block:: bash + + pip3 install pyEDAA.ProjectModel + + +Updating from PyPI using PIP +============================ + +.. code-block:: bash + + pip3 install -U pyEDAA.ProjectModel + + +Uninstallation using PIP +======================== + +.. code-block:: bash + + pip3 uninstall pyEDAA.ProjectModel + + +Installation from local directory using PIP +=========================================== + +.. code-block:: bash + + pip3 install . + + +.. _installation-setup: + +Using ``setup.py`` (legacy) +*************************** + +See sections above on how to use PIP. + +Installation using ``setup.py`` +=============================== + +.. code-block:: bash + + setup.py install diff --git a/_sources/License.rst.txt b/_sources/License.rst.txt new file mode 100644 index 00000000..fba66a20 --- /dev/null +++ b/_sources/License.rst.txt @@ -0,0 +1,140 @@ +.. _SRCLICENSE: + +.. Note:: This is a local copy of the `Apache License Version 2.0 `__. + +.. Attention:: This **Apache License, 2.0** applies to all **source and configuration files of project**, **except documentation**. + +Apache License 2.0 +################## + +Version 2.0, January 2004 + +:xlarge:`TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION` + + +1. Definitions. +=============== +**"License"** shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +**"Licensor"** shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +**"Legal Entity"** shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that +entity. For the purposes of this definition, **"control"** means (i) the power, direct or indirect, to cause the direction or management of such entity, whether +by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +**"You"** (or **"Your"**) shall mean an individual or Legal Entity exercising permissions granted by this License. + +**"Source"** form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and +configuration files. + +**"Object"** form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object +code, generated documentation, and conversions to other media types. + +**"Work"** shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is +included in or attached to the work (an example is provided in the Appendix below). + +**"Derivative Works"** shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +**"Contribution"** shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative +Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to +submit on behalf of the copyright owner. For the purposes of this definition, **"submitted"** means any form of electronic, verbal, or written communication +sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue +tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is +conspicuously marked or otherwise designated in writing by the copyright owner as **"Not a Contribution."** + +**"Contributor"** shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. +============================== +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. +=========================== +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such +license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of +their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim +or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then +any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. +================== +You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +* You must give any other recipients of the Work or Derivative Works a copy of this License; and +* You must cause any modified files to carry prominent notices stating that You changed the files; and +* You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source + form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +* If the Work includes a **"NOTICE"** text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the + attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the + following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the + Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE + file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, + alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise +complies with the conditions stated in this License. + +5. Submission of Contributions. +=============================== +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any +separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. +============== +This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable +and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. +========================== +Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, +MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and +assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. +=========================== +In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or +consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages +for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been +advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. +============================================== +While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other +liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole +responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +---------------------------------------------------------------------------------------------------------------------------------------------------------------- + +:xlarge:`Appendix: How to apply the Apache License to your work` + +To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying +information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or +class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. + +.. code-block:: none + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/_sources/ProjectModel/Design.rst.txt b/_sources/ProjectModel/Design.rst.txt new file mode 100644 index 00000000..bc6c2b80 --- /dev/null +++ b/_sources/ProjectModel/Design.rst.txt @@ -0,0 +1,108 @@ +.. _projectmodel-design: + +Design +###### + +Generic description of an EDA design. + +.. todo:: + + Write documentation. + + +.. rubric:: Class Relationship + +.. mermaid:: + + graph TD; + Project --> Design; + Design --> VHDLLibrary; + Design --> FileSet; + VHDLLibrary --> File; + FileSet --> File + + style Design fill:#ee9b00 + + +Condensed definition of class :class:`~pyEDAA.ProjectModel.Design` +================================================================== + +.. code-block:: Python + + @export + class Design: + _name: str + _project: Nullable['Project'] + _directory: Nullable[Path] + _fileSets: Dict[str, FileSet] + _defaultFileSet: Nullable[FileSet] + _vhdlLibraries: Dict[str, VHDLLibrary] + _vhdlVersion: VHDLVersion + _verilogVersion: VerilogVersion + _svVersion: SystemVerilogVersion + _externalVHDLLibraries: List + + def __init__( + self, + name: str, + directory: Path = Path("."), + project: 'Project' = None, + vhdlVersion: VHDLVersion = None, + verilogVersion: VerilogVersion = None, + svVersion: SystemVerilogVersion = None + ): + + @property + def Name(self) -> str: + + @property + def Project(self) -> Nullable['Project']: + @Project.setter + def Project(self, value: 'Project') -> None: + + @property + def Directory(self) -> Path: + @Directory.setter + def Directory(self, value: Path) -> None: + + @property + def ResolvedPath(self) -> Path: + + @property + def DefaultFileSet(self) -> FileSet: + @DefaultFileSet.setter + def DefaultFileSet(self, value: Union[str, FileSet]) -> None: + + @property + def FileSets(self) -> Dict[str, FileSet]: + + def Files(self, fileType: FileType = FileTypes.Any, fileSet: Union[str, FileSet] = None) -> Generator[File, None, None]: + + @property + def VHDLLibraries(self) -> List[VHDLLibrary]: + + @property + def VHDLVersion(self) -> VHDLVersion: + @VHDLVersion.setter + def VHDLVersion(self, value: VHDLVersion) -> None: + + @property + def VerilogVersion(self) -> VerilogVersion: + @VerilogVersion.setter + def VerilogVersion(self, value: VerilogVersion) -> None: + + @property + def SVVersion(self) -> SystemVerilogVersion: + @SVVersion.setter + def SVVersion(self, value: SystemVerilogVersion) -> None: + + @property + def ExternalVHDLLibraries(self) -> List: + + def AddFileSet(self, fileSet: FileSet) -> None: + + def AddFileSets(self, fileSets: Iterable[FileSet]) -> None: + + def AddFile(self, file: File) -> None: + + def AddFiles(self, files: Iterable[File]) -> None: diff --git a/_sources/ProjectModel/File.rst.txt b/_sources/ProjectModel/File.rst.txt new file mode 100644 index 00000000..063cf66d --- /dev/null +++ b/_sources/ProjectModel/File.rst.txt @@ -0,0 +1,69 @@ +.. _projectmodel-file: + +File +#### + +Generic description of a file in EDA design. + +.. todo:: + + Write documentation. + + +.. rubric:: Class Relationship + +.. mermaid:: + + graph TD; + Project --> Design; + Design --> VHDLLibrary; + Design --> FileSet; + VHDLLibrary --> File; + FileSet --> File + + style File fill:#ee9b00 + + +Condensed definition of class :class:`~pyEDAA.ProjectModel.File` +================================================================ + +.. code-block:: Python + + @export + class File(metaclass=FileType): + _path: Path + _project: Nullable['Project'] + _design: Nullable['Design'] + _fileSet: Nullable['FileSet'] + + def __init__( + self, + path: Path, + project: 'Project' = None, + design: 'Design' = None, + fileSet: 'FileSet' = None + ): + + @property + def FileType(self) -> 'FileType': + + @property + def Path(self) -> Path: + + @property + def ResolvedPath(self) -> Path: + + @property + def Project(self) -> Nullable['Project']: + @Project.setter + def Project(self, value: 'Project') -> None: + + @property + def Design(self) -> Nullable['Design']: + @Design.setter + def Design(self, value: 'Design') -> None: + + @property + def FileSet(self) -> Nullable['FileSet']: + @FileSet.setter + def FileSet(self, value: 'FileSet') -> None: diff --git a/_sources/ProjectModel/FileSet.rst.txt b/_sources/ProjectModel/FileSet.rst.txt new file mode 100644 index 00000000..b63e06d1 --- /dev/null +++ b/_sources/ProjectModel/FileSet.rst.txt @@ -0,0 +1,113 @@ +.. _projectmodel-fileset: + +FileSet +####### + +Generic description of an EDA file set (group of files). + +.. todo:: + + Write documentation. + + +.. rubric:: Class Relationship + +.. mermaid:: + + graph TD; + Project --> Design; + Design --> VHDLLibrary; + Design --> FileSet; + VHDLLibrary --> File; + FileSet --> File + + style FileSet fill:#ee9b00 + + +Condensed definition of class :class:`~pyEDAA.ProjectModel.FileSet` +=================================================================== + +.. code-block:: Python + + @export + class FileSet: + _name: str + _project: Nullable['Project'] + _design: Nullable['Design'] + _directory: Nullable[Path] + _parent: Nullable['FileSet'] + _fileSets: Dict[str, 'FileSet'] + _files: List[File] + + _vhdlLibrary: 'VHDLLibrary' + _vhdlVersion: VHDLVersion + _verilogVersion: VerilogVersion + _svVersion: SystemVerilogVersion + + def __init__( + self, + name: str, + directory: Path = Path("."), + project: 'Project' = None, + design: 'Design' = None, + parent: Nullable['FileSet'] = None, + vhdlLibrary: Union[str, 'VHDLLibrary'] = None, + vhdlVersion: VHDLVersion = None, + verilogVersion: VerilogVersion = None, + svVersion: SystemVerilogVersion = None + ): + + @property + def Name(self) -> str: + + @property + def Project(self) -> Nullable['Project']: + @Project.setter + def Project(self, value: 'Project') -> None: + + @property + def Design(self) -> Nullable['Design']: + @Design.setter + def Design(self, value: 'Design') -> None: + + @property + def Directory(self) -> Path: + @Directory.setter + def Directory(self, value: Path) -> None: + + @property + def ResolvedPath(self) -> Path: + + @property + def Parent(self) -> Nullable['FileSet']: + @Parent.setter + def Parent(self, value: 'FileSet') -> None: + + @property + def FileSets(self) -> Dict[str, 'FileSet']: + + def Files(self, fileType: FileType = FileTypes.Any, fileSet: Union[str, 'FileSet'] = None) -> Generator[File, None, None]: + + def AddFile(self, file: File) -> None: + + def AddFiles(self, files: Iterable[File]) -> None: + + @property + def VHDLLibrary(self) -> 'VHDLLibrary': + @VHDLLibrary.setter + def VHDLLibrary(self, value: 'VHDLLibrary') -> None: + + @property + def VHDLVersion(self) -> VHDLVersion: + @VHDLVersion.setter + def VHDLVersion(self, value: VHDLVersion) -> None: + + @property + def VerilogVersion(self) -> VerilogVersion: + @VerilogVersion.setter + def VerilogVersion(self, value: VerilogVersion) -> None: + + @property + def SVVersion(self) -> SystemVerilogVersion: + @SVVersion.setter + def SVVersion(self, value: SystemVerilogVersion) -> None: diff --git a/_sources/ProjectModel/Project.rst.txt b/_sources/ProjectModel/Project.rst.txt new file mode 100644 index 00000000..cc0b2022 --- /dev/null +++ b/_sources/ProjectModel/Project.rst.txt @@ -0,0 +1,77 @@ +.. _projectmodel-project: + +Project +####### + +Generic description of an EDA project. + +.. todo:: + + Write documentation. + + +.. rubric:: Class Relationship + +.. mermaid:: + + graph TD; + Project --> Design; + Design --> VHDLLibrary; + Design --> FileSet; + VHDLLibrary --> File; + FileSet --> File + + style Project fill:#ee9b00 + + +Condensed definition of class :class:`~pyEDAA.ProjectModel.Project` +=================================================================== + +.. code-block:: Python + + @export + class Project: + _name: str + _rootDirectory: Nullable[Path] + _designs: Dict[str, Design] + _vhdlVersion: VHDLVersion + _verilogVersion: VerilogVersion + _svVersion: SystemVerilogVersion + + def __init__( + self, + name: str, + rootDirectory: Path = Path("."), + vhdlVersion: VHDLVersion = None, + verilogVersion: VerilogVersion = None, + svVersion: SystemVerilogVersion = None + ): + + @property + def Name(self) -> str: + + @property + def RootDirectory(self) -> Path: + @RootDirectory.setter + def RootDirectory(self, value: Path) -> None: + + @property + def ResolvedPath(self) -> Path: + + @property + def Designs(self) -> Dict[str, Design]: + + @property + def VHDLVersion(self) -> VHDLVersion: + @VHDLVersion.setter + def VHDLVersion(self, value: VHDLVersion) -> None: + + @property + def VerilogVersion(self) -> VerilogVersion: + @VerilogVersion.setter + def VerilogVersion(self, value: VerilogVersion) -> None: + + @property + def SVVersion(self) -> SystemVerilogVersion: + @SVVersion.setter + def SVVersion(self, value: SystemVerilogVersion) -> None: diff --git a/_sources/ProjectModel/VHDLLibrary.rst.txt b/_sources/ProjectModel/VHDLLibrary.rst.txt new file mode 100644 index 00000000..fe4e8b02 --- /dev/null +++ b/_sources/ProjectModel/VHDLLibrary.rst.txt @@ -0,0 +1,67 @@ +.. _projectmodel-vhdllib: + +VHDL Library +############ + +Generic description of a VHDL library (group of VHDL files containing VHDL primary units). + +.. todo:: + + Write documentation. + + +.. rubric:: Class Relationship + +.. mermaid:: + + graph TD; + Project --> Design; + Design --> VHDLLibrary; + Design --> FileSet; + VHDLLibrary --> File; + FileSet --> File + + style VHDLLibrary fill:#ee9b00 + + +Condensed definition of class :class:`~pyEDAA.ProjectModel.VHDLLibrary` +======================================================================= + +.. code-block:: Python + + @export + class VHDLLibrary: + _name: str + _project: Nullable['Project'] + _design: Nullable['Design'] + _files: List[File] + _vhdlVersion: VHDLVersion + + def __init__( + self, + name: str, + project: 'Project' = None, + design: 'Design' = None, + vhdlVersion: VHDLVersion = None + ): + + @property + def Name(self) -> str: + + @property + def Project(self) -> Nullable['Project']: + @Project.setter + def Project(self, value: 'Project'): + + @property + def Design(self) -> Nullable['Design']: + @Design.setter + def Design(self, value: 'Design'): + + @property + def Files(self) -> Generator[File, None, None]: + + @property + def VHDLVersion(self) -> VHDLVersion: + @VHDLVersion.setter + def VHDLVersion(self, value: VHDLVersion) -> None: diff --git a/_sources/ProjectModel/index.rst.txt b/_sources/ProjectModel/index.rst.txt new file mode 100644 index 00000000..789b7be8 --- /dev/null +++ b/_sources/ProjectModel/index.rst.txt @@ -0,0 +1,43 @@ +.. _projectmodel: + +Project Model +############# + +.. rubric:: Design Goal + +* Clearly named classes that model the semantics of an EDA project. +* Child objects shall have a reference to their parent. + + +.. rubric:: Overall Hierarchy + +An EDA project contains one or multiple variants of a EDA design. +A design then has at least one but usually multiple file sets to group source files and apply settings or attributes to that group. + +.. mermaid:: + + graph TD; + Project-->Design_A; + Project-->Design_B; + Design_A-->VHDLLibrary_LA; + Design_A-->FileSet_DefaultA; + Design_A-->FileSet_A1; + Design_A-->FileSet_A2; + FileSet_A2-->FileSet_3 + Design_B-->VHDLLibrary_LB; + Design_B-->FileSet_DefaultB; + Design_B-->FileSet_B1; + Design_B-->FileSet_B2; + FileSet_B2-->FileSet_3 + + +.. rubric:: Elements of the Project Model + +.. toctree:: + :maxdepth: 1 + + Project + Design + VHDLLibrary + FileSet + File diff --git a/_sources/coverage/index.rst.txt b/_sources/coverage/index.rst.txt new file mode 100644 index 00000000..80bbad2e --- /dev/null +++ b/_sources/coverage/index.rst.txt @@ -0,0 +1,4 @@ +Coverage Report +############### + +*Placeholder for the Coverage report generated with* ``pytest`` *and* ``coverage``. diff --git a/_sources/genindex.rst.txt b/_sources/genindex.rst.txt new file mode 100644 index 00000000..c07da40d --- /dev/null +++ b/_sources/genindex.rst.txt @@ -0,0 +1,4 @@ +.. This file is a placeholder and will be replaced + +Index +##### diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt new file mode 100644 index 00000000..e346302e --- /dev/null +++ b/_sources/index.rst.txt @@ -0,0 +1,184 @@ +.. include:: shields.inc + +.. image:: _static/logo_on_light.svg + :height: 90 px + :align: center + :target: https://GitHub.com/edaa-org/pyEDAA.ProjectModel + +.. raw:: html + +
+ +.. raw:: latex + + \part{Introduction} + +.. only:: html + + | |SHIELD:svg:ProjectModel-github| |SHIELD:svg:ProjectModel-src-license| |SHIELD:svg:ProjectModel-ghp-doc| |SHIELD:svg:ProjectModel-doc-license| |SHIELD:svg:ProjectModel-gitter| + | |SHIELD:svg:ProjectModel-pypi-tag| |SHIELD:svg:ProjectModel-pypi-status| |SHIELD:svg:ProjectModel-pypi-python| + | |SHIELD:svg:ProjectModel-gha-test| |SHIELD:svg:ProjectModel-lib-status| |SHIELD:svg:ProjectModel-codacy-quality| |SHIELD:svg:ProjectModel-codacy-coverage| |SHIELD:svg:ProjectModel-codecov-coverage| + +.. Disabled shields: |SHIELD:svg:ProjectModel-lib-dep| |SHIELD:svg:ProjectModel-req-status| |SHIELD:svg:ProjectModel-lib-rank| + +.. only:: latex + + |SHIELD:png:ProjectModel-github| |SHIELD:png:ProjectModel-src-license| |SHIELD:png:ProjectModel-ghp-doc| |SHIELD:png:ProjectModel-doc-license| |SHIELD:svg:ProjectModel-gitter| + |SHIELD:png:ProjectModel-pypi-tag| |SHIELD:png:ProjectModel-pypi-status| |SHIELD:png:ProjectModel-pypi-python| + |SHIELD:png:ProjectModel-gha-test| |SHIELD:png:ProjectModel-lib-status| |SHIELD:png:ProjectModel-codacy-quality| |SHIELD:png:ProjectModel-codacy-coverage| |SHIELD:png:ProjectModel-codecov-coverage| + +.. Disabled shields: |SHIELD:png:ProjectModel-lib-dep| |SHIELD:png:ProjectModel-req-status| |SHIELD:png:ProjectModel-lib-rank| + +-------------------------------------------------------------------------------- + +The pyEDAA.ProjectModel Documentation +##################################### + +An abstract model of HDL design projects and EDA tooling. + + +.. _goals: + +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. + + +.. _usecase: + +Use Cases +********* + +* Describing HDL projects for open source simulation and synthesis tools: + `GHDL `__, + `Icarus Verilog `__, + `Verilator `__, + `Yosys `__, + `Verilog to Routing (VTR) `__, + `nextpnr `__, + etc. +* Managing IP cores and projects with `pyIPCMI `__. + + +.. _news: + +News +**** + +.. only:: html + + Oct. 2021 - Reading ``*.xpr`` and ``*.pro`` Files + ================================================= + +.. only:: latex + + .. rubric:: Reading ``*.xpr`` and ``*.pro`` Files + +* Xilinx Vivado's ``*.xpr`` and OSVVM's ``*.pro`` files can now be read. +* Filesets can be nested. +* The dataset can be validated. + + +.. only:: html + + Sep. 2021 - Extracted ProjectModel from pyIPCMI + =============================================== + +.. only:: latex + + .. rubric:: Extracted ProjectModel from pyIPCMI + +* The project model has been extracted from `pyIPCMI `__. +* ProjectModel became first citizen of `EDA² `__ and got integrated into the `pyEDAA` namespace at PyPI. + + +.. _contributors: + +Contributors +************ + +* `Patrick Lehmann `__ (Maintainer) +* `Unai Martinez-Corral `__ (Maintainer) +* `and more... `__ + + +License +******* + +.. only:: html + + This Python package (source code) is licensed under `Apache License 2.0 `__. |br| + The accompanying documentation is licensed under `Creative Commons - Attribution 4.0 (CC-BY 4.0) `__. + +.. only:: latex + + This Python package (source code) is licensed under **Apache License 2.0**. |br| + The accompanying documentation is licensed under **Creative Commons - Attribution 4.0 (CC-BY 4.0)**. + +------------------------------------ + +.. |docdate| date:: %d.%b %Y - %H:%M + +.. only:: html + + This document was generated on |docdate|. + + +.. toctree:: + :hidden: + + Used as a layer of EDA² ➚ + + +.. toctree:: + :caption: Introduction + :hidden: + + Installation + Dependency + + +.. raw:: latex + + \part{Main Documentation} + +.. toctree:: + :caption: Main Documentation + :hidden: + + ProjectModel/index + FileTypes/index + + +.. raw:: latex + + \part{References} + +.. toctree:: + :caption: References + :hidden: + + pyEDAA.ProjectModel/index + + +.. raw:: latex + + \part{Appendix} + +.. toctree:: + :caption: Appendix + :hidden: + + Coverage Report ➚ + Static Type Check Report ➚ + License + Doc-License + Glossary + genindex + py-modindex diff --git a/_sources/py-modindex.rst.txt b/_sources/py-modindex.rst.txt new file mode 100644 index 00000000..23167be6 --- /dev/null +++ b/_sources/py-modindex.rst.txt @@ -0,0 +1,4 @@ +.. This file is a placeholder and will be replaced + +Module Index +############ diff --git a/_sources/pyEDAA.ProjectModel/index.rst.txt b/_sources/pyEDAA.ProjectModel/index.rst.txt new file mode 100644 index 00000000..118a264a --- /dev/null +++ b/_sources/pyEDAA.ProjectModel/index.rst.txt @@ -0,0 +1,8 @@ +Python Class Reference +###################### + +Reference of all packages and modules: + +.. toctree:: + + pyEDAA.ProjectModel diff --git a/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Altera.Quartus.rst.txt b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Altera.Quartus.rst.txt new file mode 100644 index 00000000..6daa1fec --- /dev/null +++ b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Altera.Quartus.rst.txt @@ -0,0 +1,36 @@ +.. # Template modified by Patrick Lehmann + * removed automodule on top, because private members are activated for autodoc (no doubled documentation). + * Made sections like 'submodules' bold text, but no headlines to reduce number of ToC levels. + +====================================== +``pyEDAA.ProjectModel.Altera.Quartus`` +====================================== + +.. py:module:: pyEDAA.ProjectModel.Altera.Quartus + + +.. currentmodule:: pyEDAA.ProjectModel.Altera.Quartus + + +**Classes** + +- :py:class:`QuartusProjectFile`: + A Quartus project file (``*.qpf``). + +- :py:class:`SDCConstraintFile`: + A Quartus constraint file (Synopsys Design Constraints; ``*.sdc``). + + +.. autoclass:: QuartusProjectFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: QuartusProjectFile + :parts: 1 + +.. autoclass:: SDCConstraintFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: SDCConstraintFile + :parts: 1 diff --git a/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Altera.rst.txt b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Altera.rst.txt new file mode 100644 index 00000000..b0014038 --- /dev/null +++ b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Altera.rst.txt @@ -0,0 +1,20 @@ +.. # Template modified by Patrick Lehmann + * removed automodule on top, because private members are activated for autodoc (no doubled documentation). + * Made sections like 'submodules' bold text, but no headlines to reduce number of ToC levels. + +============================== +``pyEDAA.ProjectModel.Altera`` +============================== + +.. py:module:: pyEDAA.ProjectModel.Altera + + + +**Submodules** + + +.. toctree:: + + pyEDAA.ProjectModel.Altera.Quartus + +.. currentmodule:: pyEDAA.ProjectModel.Altera diff --git a/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Attributes.rst.txt b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Attributes.rst.txt new file mode 100644 index 00000000..82c84cec --- /dev/null +++ b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Attributes.rst.txt @@ -0,0 +1,26 @@ +.. # Template modified by Patrick Lehmann + * removed automodule on top, because private members are activated for autodoc (no doubled documentation). + * Made sections like 'submodules' bold text, but no headlines to reduce number of ToC levels. + +================================== +``pyEDAA.ProjectModel.Attributes`` +================================== + +.. py:module:: pyEDAA.ProjectModel.Attributes + + +.. currentmodule:: pyEDAA.ProjectModel.Attributes + + +**Classes** + +- :py:class:`KeyValueAttribute`: + Undocumented. + + +.. autoclass:: KeyValueAttribute + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: KeyValueAttribute + :parts: 1 diff --git a/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.GHDL.rst.txt b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.GHDL.rst.txt new file mode 100644 index 00000000..2a9c44f6 --- /dev/null +++ b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.GHDL.rst.txt @@ -0,0 +1,26 @@ +.. # Template modified by Patrick Lehmann + * removed automodule on top, because private members are activated for autodoc (no doubled documentation). + * Made sections like 'submodules' bold text, but no headlines to reduce number of ToC levels. + +============================ +``pyEDAA.ProjectModel.GHDL`` +============================ + +.. py:module:: pyEDAA.ProjectModel.GHDL + + +.. currentmodule:: pyEDAA.ProjectModel.GHDL + + +**Classes** + +- :py:class:`GHDLWaveformFile`: + GHDL's waveform file (``*.ghw``) supporting VHDL and Verilog simulation results. + + +.. autoclass:: GHDLWaveformFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: GHDLWaveformFile + :parts: 1 diff --git a/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Intel.QuartusPrime.rst.txt b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Intel.QuartusPrime.rst.txt new file mode 100644 index 00000000..dda32146 --- /dev/null +++ b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Intel.QuartusPrime.rst.txt @@ -0,0 +1,36 @@ +.. # Template modified by Patrick Lehmann + * removed automodule on top, because private members are activated for autodoc (no doubled documentation). + * Made sections like 'submodules' bold text, but no headlines to reduce number of ToC levels. + +========================================== +``pyEDAA.ProjectModel.Intel.QuartusPrime`` +========================================== + +.. py:module:: pyEDAA.ProjectModel.Intel.QuartusPrime + + +.. currentmodule:: pyEDAA.ProjectModel.Intel.QuartusPrime + + +**Classes** + +- :py:class:`QuartusProjectFile`: + A Quartus project file (``*.qpf``). + +- :py:class:`SDCConstraintFile`: + A Quartus constraint file (Synopsys Design Constraints; ``*.sdc``). + + +.. autoclass:: QuartusProjectFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: QuartusProjectFile + :parts: 1 + +.. autoclass:: SDCConstraintFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: SDCConstraintFile + :parts: 1 diff --git a/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Intel.rst.txt b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Intel.rst.txt new file mode 100644 index 00000000..7ee5c6ce --- /dev/null +++ b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Intel.rst.txt @@ -0,0 +1,20 @@ +.. # Template modified by Patrick Lehmann + * removed automodule on top, because private members are activated for autodoc (no doubled documentation). + * Made sections like 'submodules' bold text, but no headlines to reduce number of ToC levels. + +============================= +``pyEDAA.ProjectModel.Intel`` +============================= + +.. py:module:: pyEDAA.ProjectModel.Intel + + + +**Submodules** + + +.. toctree:: + + pyEDAA.ProjectModel.Intel.QuartusPrime + +.. currentmodule:: pyEDAA.ProjectModel.Intel diff --git a/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.ModelSim.rst.txt b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.ModelSim.rst.txt new file mode 100644 index 00000000..7f78d569 --- /dev/null +++ b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.ModelSim.rst.txt @@ -0,0 +1,46 @@ +.. # Template modified by Patrick Lehmann + * removed automodule on top, because private members are activated for autodoc (no doubled documentation). + * Made sections like 'submodules' bold text, but no headlines to reduce number of ToC levels. + +=============================================== +``pyEDAA.ProjectModel.MentorGraphics.ModelSim`` +=============================================== + +.. py:module:: pyEDAA.ProjectModel.MentorGraphics.ModelSim + + +.. currentmodule:: pyEDAA.ProjectModel.MentorGraphics.ModelSim + + +**Classes** + +- :py:class:`ModelSimProjectFile`: + Base-class of all tool-specific project files. + +- :py:class:`ModelSimINIFile`: + Base-class of all tool-specific setting files. + +- :py:class:`WaveDoFile`: + Base-class of all tool-specific waveform configuration files. + + +.. autoclass:: ModelSimProjectFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: ModelSimProjectFile + :parts: 1 + +.. autoclass:: ModelSimINIFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: ModelSimINIFile + :parts: 1 + +.. autoclass:: WaveDoFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: WaveDoFile + :parts: 1 diff --git a/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.QuestaSim.rst.txt b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.QuestaSim.rst.txt new file mode 100644 index 00000000..a2037c55 --- /dev/null +++ b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.QuestaSim.rst.txt @@ -0,0 +1,46 @@ +.. # Template modified by Patrick Lehmann + * removed automodule on top, because private members are activated for autodoc (no doubled documentation). + * Made sections like 'submodules' bold text, but no headlines to reduce number of ToC levels. + +================================================ +``pyEDAA.ProjectModel.MentorGraphics.QuestaSim`` +================================================ + +.. py:module:: pyEDAA.ProjectModel.MentorGraphics.QuestaSim + + +.. currentmodule:: pyEDAA.ProjectModel.MentorGraphics.QuestaSim + + +**Classes** + +- :py:class:`ModelSimProjectFile`: + Base-class of all tool-specific project files. + +- :py:class:`ModelSimINIFile`: + Base-class of all tool-specific setting files. + +- :py:class:`WaveDoFile`: + Base-class of all tool-specific waveform configuration files. + + +.. autoclass:: ModelSimProjectFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: ModelSimProjectFile + :parts: 1 + +.. autoclass:: ModelSimINIFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: ModelSimINIFile + :parts: 1 + +.. autoclass:: WaveDoFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: WaveDoFile + :parts: 1 diff --git a/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.rst.txt b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.rst.txt new file mode 100644 index 00000000..2ea420ee --- /dev/null +++ b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.rst.txt @@ -0,0 +1,21 @@ +.. # Template modified by Patrick Lehmann + * removed automodule on top, because private members are activated for autodoc (no doubled documentation). + * Made sections like 'submodules' bold text, but no headlines to reduce number of ToC levels. + +====================================== +``pyEDAA.ProjectModel.MentorGraphics`` +====================================== + +.. py:module:: pyEDAA.ProjectModel.MentorGraphics + + + +**Submodules** + + +.. toctree:: + + pyEDAA.ProjectModel.MentorGraphics.ModelSim + pyEDAA.ProjectModel.MentorGraphics.QuestaSim + +.. currentmodule:: pyEDAA.ProjectModel.MentorGraphics diff --git a/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.OSVVM.rst.txt b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.OSVVM.rst.txt new file mode 100644 index 00000000..59c9f259 --- /dev/null +++ b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.OSVVM.rst.txt @@ -0,0 +1,26 @@ +.. # Template modified by Patrick Lehmann + * removed automodule on top, because private members are activated for autodoc (no doubled documentation). + * Made sections like 'submodules' bold text, but no headlines to reduce number of ToC levels. + +============================= +``pyEDAA.ProjectModel.OSVVM`` +============================= + +.. py:module:: pyEDAA.ProjectModel.OSVVM + + +.. currentmodule:: pyEDAA.ProjectModel.OSVVM + + +**Classes** + +- :py:class:`OSVVMProjectFile`: + An OSVVM project file (``*.pro``). + + +.. autoclass:: OSVVMProjectFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: OSVVMProjectFile + :parts: 1 diff --git a/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.VHDL.rst.txt b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.VHDL.rst.txt new file mode 100644 index 00000000..127c1981 --- /dev/null +++ b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.VHDL.rst.txt @@ -0,0 +1,12 @@ +.. # Template modified by Patrick Lehmann + * removed automodule on top, because private members are activated for autodoc (no doubled documentation). + * Made sections like 'submodules' bold text, but no headlines to reduce number of ToC levels. + +============================ +``pyEDAA.ProjectModel.VHDL`` +============================ + +.. py:module:: pyEDAA.ProjectModel.VHDL + + +.. currentmodule:: pyEDAA.ProjectModel.VHDL diff --git a/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Verilog.rst.txt b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Verilog.rst.txt new file mode 100644 index 00000000..0c626261 --- /dev/null +++ b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Verilog.rst.txt @@ -0,0 +1,26 @@ +.. # Template modified by Patrick Lehmann + * removed automodule on top, because private members are activated for autodoc (no doubled documentation). + * Made sections like 'submodules' bold text, but no headlines to reduce number of ToC levels. + +=============================== +``pyEDAA.ProjectModel.Verilog`` +=============================== + +.. py:module:: pyEDAA.ProjectModel.Verilog + + +.. currentmodule:: pyEDAA.ProjectModel.Verilog + + +**Classes** + +- :py:class:`ValueChangeDumpFile`: + Verilog's waveform file (``*.vcd``) for exchanging value changes as defined by IEEE Std. 1364. + + +.. autoclass:: ValueChangeDumpFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: ValueChangeDumpFile + :parts: 1 diff --git a/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.ISE.rst.txt b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.ISE.rst.txt new file mode 100644 index 00000000..b9518792 --- /dev/null +++ b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.ISE.rst.txt @@ -0,0 +1,36 @@ +.. # Template modified by Patrick Lehmann + * removed automodule on top, because private members are activated for autodoc (no doubled documentation). + * Made sections like 'submodules' bold text, but no headlines to reduce number of ToC levels. + +================================== +``pyEDAA.ProjectModel.Xilinx.ISE`` +================================== + +.. py:module:: pyEDAA.ProjectModel.Xilinx.ISE + + +.. currentmodule:: pyEDAA.ProjectModel.Xilinx.ISE + + +**Classes** + +- :py:class:`ISEProjectFile`: + Base-class of all tool-specific project files. + +- :py:class:`UCFConstraintFile`: + Base-class of all constraint files. + + +.. autoclass:: ISEProjectFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: ISEProjectFile + :parts: 1 + +.. autoclass:: UCFConstraintFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: UCFConstraintFile + :parts: 1 diff --git a/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.Vivado.rst.txt b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.Vivado.rst.txt new file mode 100644 index 00000000..2cd98c6b --- /dev/null +++ b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.Vivado.rst.txt @@ -0,0 +1,106 @@ +.. # Template modified by Patrick Lehmann + * removed automodule on top, because private members are activated for autodoc (no doubled documentation). + * Made sections like 'submodules' bold text, but no headlines to reduce number of ToC levels. + +===================================== +``pyEDAA.ProjectModel.Xilinx.Vivado`` +===================================== + +.. py:module:: pyEDAA.ProjectModel.Xilinx.Vivado + + +.. currentmodule:: pyEDAA.ProjectModel.Xilinx.Vivado + + +**Classes** + +- :py:class:`UsedInAttribute`: + Undocumented. + +- :py:class:`File`: + A :term:`File` represents a file in a design. This :term:`base-class` is used + +- :py:class:`ConstraintFile`: + Base-class of all constraint files. + +- :py:class:`VerilogSourceFile`: + A Verilog source file (of any language version). + +- :py:class:`VHDLSourceFile`: + A VHDL source file (of any language version). + +- :py:class:`VivadoProjectFile`: + A Vivado project file (``*.xpr``). + +- :py:class:`XDCConstraintFile`: + A Vivado constraint file (Xilinx Design Constraints; ``*.xdc``). + +- :py:class:`IPCoreDescriptionFile`: + An XML file (``*.xml``). + +- :py:class:`IPCoreInstantiationFile`: + A Vivado IP core instantiation file (Xilinx IPCore Instance; ``*.xci``). + + +.. autoclass:: UsedInAttribute + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: UsedInAttribute + :parts: 1 + +.. autoclass:: File + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: File + :parts: 1 + +.. autoclass:: ConstraintFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: ConstraintFile + :parts: 1 + +.. autoclass:: VerilogSourceFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: VerilogSourceFile + :parts: 1 + +.. autoclass:: VHDLSourceFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: VHDLSourceFile + :parts: 1 + +.. autoclass:: VivadoProjectFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: VivadoProjectFile + :parts: 1 + +.. autoclass:: XDCConstraintFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: XDCConstraintFile + :parts: 1 + +.. autoclass:: IPCoreDescriptionFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: IPCoreDescriptionFile + :parts: 1 + +.. autoclass:: IPCoreInstantiationFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: IPCoreInstantiationFile + :parts: 1 diff --git a/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.rst.txt b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.rst.txt new file mode 100644 index 00000000..e73f2a01 --- /dev/null +++ b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.rst.txt @@ -0,0 +1,21 @@ +.. # Template modified by Patrick Lehmann + * removed automodule on top, because private members are activated for autodoc (no doubled documentation). + * Made sections like 'submodules' bold text, but no headlines to reduce number of ToC levels. + +============================== +``pyEDAA.ProjectModel.Xilinx`` +============================== + +.. py:module:: pyEDAA.ProjectModel.Xilinx + + + +**Submodules** + + +.. toctree:: + + pyEDAA.ProjectModel.Xilinx.ISE + pyEDAA.ProjectModel.Xilinx.Vivado + +.. currentmodule:: pyEDAA.ProjectModel.Xilinx diff --git a/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.rst.txt b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.rst.txt new file mode 100644 index 00000000..a425e57a --- /dev/null +++ b/_sources/pyEDAA.ProjectModel/pyEDAA.ProjectModel.rst.txt @@ -0,0 +1,502 @@ +.. # Template modified by Patrick Lehmann + * removed automodule on top, because private members are activated for autodoc (no doubled documentation). + * Made sections like 'submodules' bold text, but no headlines to reduce number of ToC levels. + +======================= +``pyEDAA.ProjectModel`` +======================= + +.. py:module:: pyEDAA.ProjectModel + + + +**Submodules** + + +.. toctree:: + + pyEDAA.ProjectModel.Altera + pyEDAA.ProjectModel.Attributes + pyEDAA.ProjectModel.GHDL + pyEDAA.ProjectModel.Intel + pyEDAA.ProjectModel.MentorGraphics + pyEDAA.ProjectModel.OSVVM + pyEDAA.ProjectModel.VHDL + pyEDAA.ProjectModel.Verilog + pyEDAA.ProjectModel.Xilinx + +.. currentmodule:: pyEDAA.ProjectModel + + +**Classes** + +- :py:class:`Attribute`: + Undocumented. + +- :py:class:`FileType`: + A :term:`meta-class` to construct *FileType* classes. + +- :py:class:`File`: + A :term:`File` represents a file in a design. This :term:`base-class` is used + +- :py:class:`HumanReadableContent`: + A file type representing human-readable contents. + +- :py:class:`XMLContent`: + A file type representing XML contents. + +- :py:class:`YAMLContent`: + A file type representing YAML contents. + +- :py:class:`JSONContent`: + A file type representing JSON contents. + +- :py:class:`INIContent`: + A file type representing INI contents. + +- :py:class:`TOMLContent`: + A file type representing TOML contents. + +- :py:class:`TCLContent`: + A file type representing content in TCL code. + +- :py:class:`SDCContent`: + A file type representing contents as Synopsys Design Constraints (SDC). + +- :py:class:`PythonContent`: + A file type representing contents as Python source code. + +- :py:class:`TextFile`: + A text file (``*.txt``). + +- :py:class:`LogFile`: + A log file (``*.log``). + +- :py:class:`XMLFile`: + An XML file (``*.xml``). + +- :py:class:`SourceFile`: + Base-class of all source files. + +- :py:class:`HDLSourceFile`: + Base-class of all HDL source files. + +- :py:class:`RDLSourceFile`: + Base-class of all RDL source files. + +- :py:class:`NetlistFile`: + Base-class of all netlist source files. + +- :py:class:`EDIFNetlistFile`: + Netlist file in EDIF (Electronic Design Interchange Format). + +- :py:class:`TCLSourceFile`: + A TCL source file. + +- :py:class:`VHDLSourceFile`: + A VHDL source file (of any language version). + +- :py:class:`VerilogBaseFile`: + Base-class of all HDL source files. + +- :py:class:`VerilogSourceFile`: + A Verilog source file (of any language version). + +- :py:class:`VerilogHeaderFile`: + A Verilog header file (of any language version). + +- :py:class:`SystemVerilogBaseFile`: + Base-class of all HDL source files. + +- :py:class:`SystemVerilogSourceFile`: + A SystemVerilog source file (of any language version). + +- :py:class:`SystemVerilogHeaderFile`: + A SystemVerilog header file (of any language version). + +- :py:class:`SystemRDLSourceFile`: + A SystemRDL source file (of any language version). + +- :py:class:`PythonSourceFile`: + A Python source file. + +- :py:class:`CocotbPythonFile`: + A Python source file used by Cocotb. + +- :py:class:`ConstraintFile`: + Base-class of all constraint files. + +- :py:class:`ProjectFile`: + Base-class of all tool-specific project files. + +- :py:class:`CSourceFile`: + Base-class of all ANSI-C source files. + +- :py:class:`CppSourceFile`: + Base-class of all ANSI-C++ source files. + +- :py:class:`SettingFile`: + Base-class of all tool-specific setting files. + +- :py:class:`SimulationAnalysisFile`: + Base-class of all tool-specific analysis files. + +- :py:class:`SimulationElaborationFile`: + Base-class of all tool-specific elaboration files. + +- :py:class:`SimulationStartFile`: + Base-class of all tool-specific simulation start-up files. + +- :py:class:`SimulationRunFile`: + Base-class of all tool-specific simulation run (execution) files. + +- :py:class:`WaveformConfigFile`: + Base-class of all tool-specific waveform configuration files. + +- :py:class:`WaveformDatabaseFile`: + Base-class of all tool-specific waveform database files. + +- :py:class:`WaveformExchangeFile`: + Base-class of all tool-independent waveform exchange files. + +- :py:class:`FileSet`: + A :term:`FileSet` represents a group of files. Filesets can have sub-filesets. + +- :py:class:`VHDLLibrary`: + A :term:`VHDLLibrary` represents a group of VHDL source files compiled into the same VHDL library. + +- :py:class:`Design`: + A :term:`Design` represents a group of filesets and the source files therein. + +- :py:class:`Project`: + A :term:`Project` represents a group of designs and the source files therein. + + +.. autoclass:: Attribute + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: Attribute + :parts: 1 + +.. autoclass:: FileType + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: FileType + :parts: 1 + +.. autoclass:: File + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: File + :parts: 1 + +.. autoclass:: HumanReadableContent + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: HumanReadableContent + :parts: 1 + +.. autoclass:: XMLContent + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: XMLContent + :parts: 1 + +.. autoclass:: YAMLContent + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: YAMLContent + :parts: 1 + +.. autoclass:: JSONContent + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: JSONContent + :parts: 1 + +.. autoclass:: INIContent + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: INIContent + :parts: 1 + +.. autoclass:: TOMLContent + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: TOMLContent + :parts: 1 + +.. autoclass:: TCLContent + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: TCLContent + :parts: 1 + +.. autoclass:: SDCContent + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: SDCContent + :parts: 1 + +.. autoclass:: PythonContent + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: PythonContent + :parts: 1 + +.. autoclass:: TextFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: TextFile + :parts: 1 + +.. autoclass:: LogFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: LogFile + :parts: 1 + +.. autoclass:: XMLFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: XMLFile + :parts: 1 + +.. autoclass:: SourceFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: SourceFile + :parts: 1 + +.. autoclass:: HDLSourceFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: HDLSourceFile + :parts: 1 + +.. autoclass:: RDLSourceFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: RDLSourceFile + :parts: 1 + +.. autoclass:: NetlistFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: NetlistFile + :parts: 1 + +.. autoclass:: EDIFNetlistFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: EDIFNetlistFile + :parts: 1 + +.. autoclass:: TCLSourceFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: TCLSourceFile + :parts: 1 + +.. autoclass:: VHDLSourceFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: VHDLSourceFile + :parts: 1 + +.. autoclass:: VerilogBaseFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: VerilogBaseFile + :parts: 1 + +.. autoclass:: VerilogSourceFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: VerilogSourceFile + :parts: 1 + +.. autoclass:: VerilogHeaderFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: VerilogHeaderFile + :parts: 1 + +.. autoclass:: SystemVerilogBaseFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: SystemVerilogBaseFile + :parts: 1 + +.. autoclass:: SystemVerilogSourceFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: SystemVerilogSourceFile + :parts: 1 + +.. autoclass:: SystemVerilogHeaderFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: SystemVerilogHeaderFile + :parts: 1 + +.. autoclass:: SystemRDLSourceFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: SystemRDLSourceFile + :parts: 1 + +.. autoclass:: PythonSourceFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: PythonSourceFile + :parts: 1 + +.. autoclass:: CocotbPythonFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: CocotbPythonFile + :parts: 1 + +.. autoclass:: ConstraintFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: ConstraintFile + :parts: 1 + +.. autoclass:: ProjectFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: ProjectFile + :parts: 1 + +.. autoclass:: CSourceFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: CSourceFile + :parts: 1 + +.. autoclass:: CppSourceFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: CppSourceFile + :parts: 1 + +.. autoclass:: SettingFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: SettingFile + :parts: 1 + +.. autoclass:: SimulationAnalysisFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: SimulationAnalysisFile + :parts: 1 + +.. autoclass:: SimulationElaborationFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: SimulationElaborationFile + :parts: 1 + +.. autoclass:: SimulationStartFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: SimulationStartFile + :parts: 1 + +.. autoclass:: SimulationRunFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: SimulationRunFile + :parts: 1 + +.. autoclass:: WaveformConfigFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: WaveformConfigFile + :parts: 1 + +.. autoclass:: WaveformDatabaseFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: WaveformDatabaseFile + :parts: 1 + +.. autoclass:: WaveformExchangeFile + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: WaveformExchangeFile + :parts: 1 + +.. autoclass:: FileSet + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: FileSet + :parts: 1 + +.. autoclass:: VHDLLibrary + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: VHDLLibrary + :parts: 1 + +.. autoclass:: Design + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: Design + :parts: 1 + +.. autoclass:: Project + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: Project + :parts: 1 diff --git a/_sources/typing/index.rst.txt b/_sources/typing/index.rst.txt new file mode 100644 index 00000000..97d4ae2a --- /dev/null +++ b/_sources/typing/index.rst.txt @@ -0,0 +1,4 @@ +Static Type Checking Report +########################### + +*Placeholder for the Static Type Checking report generated with* ``mypy``. diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 00000000..30fee9d0 --- /dev/null +++ b/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_static/css/badge_only.css b/_static/css/badge_only.css new file mode 100644 index 00000000..ec0f9a89 --- /dev/null +++ b/_static/css/badge_only.css @@ -0,0 +1 @@ +.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1f1f;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#262626;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #404040}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/_static/css/fonts/Roboto-Slab-Bold.woff b/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 00000000..6cb60000 Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/_static/css/fonts/Roboto-Slab-Bold.woff2 b/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 00000000..7059e231 Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/_static/css/fonts/Roboto-Slab-Regular.woff b/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 00000000..f815f63f Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/_static/css/fonts/Roboto-Slab-Regular.woff2 b/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 00000000..f2c76e5b Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/_static/css/fonts/fontawesome-webfont.eot b/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..e9f60ca9 Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/_static/css/fonts/fontawesome-webfont.svg b/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..855c845e --- /dev/null +++ b/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_static/css/fonts/fontawesome-webfont.ttf b/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..35acda2f Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/_static/css/fonts/fontawesome-webfont.woff b/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..400014a4 Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/_static/css/fonts/fontawesome-webfont.woff2 b/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 00000000..4d13fc60 Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/_static/css/fonts/lato-bold-italic.woff b/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 00000000..88ad05b9 Binary files /dev/null and b/_static/css/fonts/lato-bold-italic.woff differ diff --git a/_static/css/fonts/lato-bold-italic.woff2 b/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 00000000..c4e3d804 Binary files /dev/null and b/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/_static/css/fonts/lato-bold.woff b/_static/css/fonts/lato-bold.woff new file mode 100644 index 00000000..c6dff51f Binary files /dev/null and b/_static/css/fonts/lato-bold.woff differ diff --git a/_static/css/fonts/lato-bold.woff2 b/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 00000000..bb195043 Binary files /dev/null and b/_static/css/fonts/lato-bold.woff2 differ diff --git a/_static/css/fonts/lato-normal-italic.woff b/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 00000000..76114bc0 Binary files /dev/null and b/_static/css/fonts/lato-normal-italic.woff differ diff --git a/_static/css/fonts/lato-normal-italic.woff2 b/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 00000000..3404f37e Binary files /dev/null and b/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/_static/css/fonts/lato-normal.woff b/_static/css/fonts/lato-normal.woff new file mode 100644 index 00000000..ae1307ff Binary files /dev/null and b/_static/css/fonts/lato-normal.woff differ diff --git a/_static/css/fonts/lato-normal.woff2 b/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 00000000..3bf98433 Binary files /dev/null and b/_static/css/fonts/lato-normal.woff2 differ diff --git a/_static/css/theme.css b/_static/css/theme.css new file mode 100644 index 00000000..2d181942 --- /dev/null +++ b/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,.wy-nav-top a,.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:15px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.rst-content .wy-breadcrumbs li tt,.wy-breadcrumbs li .rst-content tt,.wy-breadcrumbs li code{padding:5px;border:none;background:none}.rst-content .wy-breadcrumbs li tt.literal,.wy-breadcrumbs li .rst-content tt.literal,.wy-breadcrumbs li code.literal{color:#404040}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:15px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:30px;display:inline-block;line-height:30px;padding:0 15px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#9b9b9b;height:30px;line-height:30px;padding:0 .809em;margin:6px 0 0;border-top:1px solid #9b9b9b;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4d4d4d;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#333;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:0;z-index:200;background-color:#333;text-align:center}.wy-side-nav-search input[type=text]{width:100%;border-radius:0;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#333;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.4045em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin:0 0 .809em;font-weight:400}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#333;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#333;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#333;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#333;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:1024px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey;font-size:95%;text-align:center}footer p{margin-bottom:0;font-size:95%}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,p{margin-bottom:12px}h1{display:none}.rst-content .toctree-wrapper>p.caption,h2{border-bottom:1px solid #e1e4e5;padding:0 0 3px;font-size:130%}h3{font-size:115%;text-decoration:underline}.section p,.simple li,section>p{text-align:justify}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1f1f;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#262626;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #404040}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.field-list>dt:after,html.writer-html5 .rst-content dl.footnote>dt:after{content:":"}html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.footnote>dt>span.brackets{margin-right:.5rem}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{font-style:italic}html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.footnote>dd p,html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{font-size:inherit;line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#b3b3b3;color:#333;border-top:3px solid #666;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:before{color:#666}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel{border:1px solid #737373;background:#b3b3b3;font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 00000000..d06a71d7 --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/_static/documentation_options.js b/_static/documentation_options.js new file mode 100644 index 00000000..240446d5 --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '0.5.0', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/_static/favicon.svg b/_static/favicon.svg new file mode 100644 index 00000000..97995b9d --- /dev/null +++ b/_static/favicon.svg @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/_static/file.png b/_static/file.png new file mode 100644 index 00000000..a858a410 Binary files /dev/null and b/_static/file.png differ diff --git a/_static/graphviz.css b/_static/graphviz.css new file mode 100644 index 00000000..8d81c02e --- /dev/null +++ b/_static/graphviz.css @@ -0,0 +1,19 @@ +/* + * graphviz.css + * ~~~~~~~~~~~~ + * + * Sphinx stylesheet -- graphviz extension. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +img.graphviz { + border: 0; + max-width: 100%; +} + +object.graphviz { + max-width: 100%; +} diff --git a/_static/js/badge_only.js b/_static/js/badge_only.js new file mode 100644 index 00000000..526d7234 --- /dev/null +++ b/_static/js/badge_only.js @@ -0,0 +1 @@ +!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=4)}({4:function(e,t,r){}}); \ No newline at end of file diff --git a/_static/js/html5shiv-printshiv.min.js b/_static/js/html5shiv-printshiv.min.js new file mode 100644 index 00000000..2b43bd06 --- /dev/null +++ b/_static/js/html5shiv-printshiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3-pre | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/_static/js/html5shiv.min.js b/_static/js/html5shiv.min.js new file mode 100644 index 00000000..cd1c674f --- /dev/null +++ b/_static/js/html5shiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/_static/js/theme.js b/_static/js/theme.js new file mode 100644 index 00000000..1fddb6ee --- /dev/null +++ b/_static/js/theme.js @@ -0,0 +1 @@ +!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/_static/logo_on_dark.svg b/_static/logo_on_dark.svg new file mode 100644 index 00000000..24e8576a --- /dev/null +++ b/_static/logo_on_dark.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/_static/logo_on_light.svg b/_static/logo_on_light.svg new file mode 100644 index 00000000..eac24d90 --- /dev/null +++ b/_static/logo_on_light.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/_static/minus.png b/_static/minus.png new file mode 100644 index 00000000..d96755fd Binary files /dev/null and b/_static/minus.png differ diff --git a/_static/plus.png b/_static/plus.png new file mode 100644 index 00000000..7107cec9 Binary files /dev/null and b/_static/plus.png differ diff --git a/_static/pygments.css b/_static/pygments.css new file mode 100644 index 00000000..6bae782c --- /dev/null +++ b/_static/pygments.css @@ -0,0 +1,85 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #49483e } +.highlight { background: #232629; color: #cccccc } +.highlight .c { color: #777777; font-style: italic } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .esc { color: #cccccc } /* Escape */ +.highlight .g { color: #cccccc } /* Generic */ +.highlight .k { color: #7686bb; font-weight: bold } /* Keyword */ +.highlight .l { color: #cccccc } /* Literal */ +.highlight .n { color: #cccccc } /* Name */ +.highlight .o { color: #cccccc } /* Operator */ +.highlight .x { color: #cccccc } /* Other */ +.highlight .p { color: #cccccc } /* Punctuation */ +.highlight .ch { color: #777777; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #777777; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #777777; font-style: italic } /* Comment.Preproc */ +.highlight .cpf { color: #777777; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #777777; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #777777; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #cccccc } /* Generic.Deleted */ +.highlight .ge { color: #cccccc } /* Generic.Emph */ +.highlight .ges { color: #cccccc } /* Generic.EmphStrong */ +.highlight .gr { color: #cccccc } /* Generic.Error */ +.highlight .gh { color: #cccccc } /* Generic.Heading */ +.highlight .gi { color: #cccccc } /* Generic.Inserted */ +.highlight .go { color: #cccccc } /* Generic.Output */ +.highlight .gp { color: #ffffff } /* Generic.Prompt */ +.highlight .gs { color: #cccccc } /* Generic.Strong */ +.highlight .gu { color: #cccccc } /* Generic.Subheading */ +.highlight .gt { color: #cccccc } /* Generic.Traceback */ +.highlight .kc { color: #7686bb; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #7686bb; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #7686bb; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #7686bb; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #7686bb; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #7686bb; font-weight: bold } /* Keyword.Type */ +.highlight .ld { color: #cccccc } /* Literal.Date */ +.highlight .m { color: #4FB8CC } /* Literal.Number */ +.highlight .s { color: #51cc99 } /* Literal.String */ +.highlight .na { color: #cccccc } /* Name.Attribute */ +.highlight .nb { color: #cccccc } /* Name.Builtin */ +.highlight .nc { color: #cccccc } /* Name.Class */ +.highlight .no { color: #cccccc } /* Name.Constant */ +.highlight .nd { color: #cccccc } /* Name.Decorator */ +.highlight .ni { color: #cccccc } /* Name.Entity */ +.highlight .ne { color: #cccccc } /* Name.Exception */ +.highlight .nf { color: #6a6aff } /* Name.Function */ +.highlight .nl { color: #cccccc } /* Name.Label */ +.highlight .nn { color: #cccccc } /* Name.Namespace */ +.highlight .nx { color: #e2828e } /* Name.Other */ +.highlight .py { color: #cccccc } /* Name.Property */ +.highlight .nt { color: #cccccc } /* Name.Tag */ +.highlight .nv { color: #7AB4DB; font-weight: bold } /* Name.Variable */ +.highlight .ow { color: #cccccc } /* Operator.Word */ +.highlight .pm { color: #cccccc } /* Punctuation.Marker */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #4FB8CC } /* Literal.Number.Bin */ +.highlight .mf { color: #4FB8CC } /* Literal.Number.Float */ +.highlight .mh { color: #4FB8CC } /* Literal.Number.Hex */ +.highlight .mi { color: #4FB8CC } /* Literal.Number.Integer */ +.highlight .mo { color: #4FB8CC } /* Literal.Number.Oct */ +.highlight .sa { color: #51cc99 } /* Literal.String.Affix */ +.highlight .sb { color: #51cc99 } /* Literal.String.Backtick */ +.highlight .sc { color: #51cc99 } /* Literal.String.Char */ +.highlight .dl { color: #51cc99 } /* Literal.String.Delimiter */ +.highlight .sd { color: #51cc99 } /* Literal.String.Doc */ +.highlight .s2 { color: #51cc99 } /* Literal.String.Double */ +.highlight .se { color: #51cc99 } /* Literal.String.Escape */ +.highlight .sh { color: #51cc99 } /* Literal.String.Heredoc */ +.highlight .si { color: #51cc99 } /* Literal.String.Interpol */ +.highlight .sx { color: #51cc99 } /* Literal.String.Other */ +.highlight .sr { color: #51cc99 } /* Literal.String.Regex */ +.highlight .s1 { color: #51cc99 } /* Literal.String.Single */ +.highlight .ss { color: #51cc99 } /* Literal.String.Symbol */ +.highlight .bp { color: #cccccc } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #6a6aff } /* Name.Function.Magic */ +.highlight .vc { color: #7AB4DB; font-weight: bold } /* Name.Variable.Class */ +.highlight .vg { color: #BE646C; font-weight: bold } /* Name.Variable.Global */ +.highlight .vi { color: #7AB4DB; font-weight: bold } /* Name.Variable.Instance */ +.highlight .vm { color: #7AB4DB; font-weight: bold } /* Name.Variable.Magic */ +.highlight .il { color: #4FB8CC } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/_static/searchtools.js b/_static/searchtools.js new file mode 100644 index 00000000..7918c3fa --- /dev/null +++ b/_static/searchtools.js @@ -0,0 +1,574 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + `Search finished, found ${resultCount} page(s) matching the search query.` + ); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() }); + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent !== undefined) return docContent.textContent; + console.warn( + "Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + /** + * execute search (requires search index to be loaded) + */ + query: (query) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + // array of [docname, title, anchor, descr, score, filename] + let results = []; + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + let score = Math.round(100 * queryLower.length / title.length) + results.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id] of foundEntries) { + let score = Math.round(100 * queryLower.length / entry.length) + results.push([ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // lookup as object + objectTerms.forEach((term) => + results.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + results.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item))); + + // now sort the results by score (in opposite order of appearance, since the + // display function below uses pop() to retrieve items) and then + // alphabetically + results.sort((a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; + }); + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + results = results.reverse(); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord) && !terms[word]) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord) && !titleTerms[word]) + arr.push({ files: titleTerms[word], score: Scorer.partialTitle }); + }); + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1) + fileMap.get(file).push(word); + else fileMap.set(file, [word]); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords) => { + const text = Search.htmlToText(htmlText); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js new file mode 100644 index 00000000..8a96c69a --- /dev/null +++ b/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/coverage/coverage_html.js b/coverage/coverage_html.js new file mode 100644 index 00000000..59348828 --- /dev/null +++ b/coverage/coverage_html.js @@ -0,0 +1,624 @@ +// Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 +// For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt + +// Coverage.py HTML report browser code. +/*jslint browser: true, sloppy: true, vars: true, plusplus: true, maxerr: 50, indent: 4 */ +/*global coverage: true, document, window, $ */ + +coverage = {}; + +// General helpers +function debounce(callback, wait) { + let timeoutId = null; + return function(...args) { + clearTimeout(timeoutId); + timeoutId = setTimeout(() => { + callback.apply(this, args); + }, wait); + }; +}; + +function checkVisible(element) { + const rect = element.getBoundingClientRect(); + const viewBottom = Math.max(document.documentElement.clientHeight, window.innerHeight); + const viewTop = 30; + return !(rect.bottom < viewTop || rect.top >= viewBottom); +} + +function on_click(sel, fn) { + const elt = document.querySelector(sel); + if (elt) { + elt.addEventListener("click", fn); + } +} + +// Helpers for table sorting +function getCellValue(row, column = 0) { + const cell = row.cells[column] // nosemgrep: eslint.detect-object-injection + if (cell.childElementCount == 1) { + const child = cell.firstElementChild + if (child instanceof HTMLTimeElement && child.dateTime) { + return child.dateTime + } else if (child instanceof HTMLDataElement && child.value) { + return child.value + } + } + return cell.innerText || cell.textContent; +} + +function rowComparator(rowA, rowB, column = 0) { + let valueA = getCellValue(rowA, column); + let valueB = getCellValue(rowB, column); + if (!isNaN(valueA) && !isNaN(valueB)) { + return valueA - valueB + } + return valueA.localeCompare(valueB, undefined, {numeric: true}); +} + +function sortColumn(th) { + // Get the current sorting direction of the selected header, + // clear state on other headers and then set the new sorting direction + const currentSortOrder = th.getAttribute("aria-sort"); + [...th.parentElement.cells].forEach(header => header.setAttribute("aria-sort", "none")); + if (currentSortOrder === "none") { + th.setAttribute("aria-sort", th.dataset.defaultSortOrder || "ascending"); + } else { + th.setAttribute("aria-sort", currentSortOrder === "ascending" ? "descending" : "ascending"); + } + + const column = [...th.parentElement.cells].indexOf(th) + + // Sort all rows and afterwards append them in order to move them in the DOM + Array.from(th.closest("table").querySelectorAll("tbody tr")) + .sort((rowA, rowB) => rowComparator(rowA, rowB, column) * (th.getAttribute("aria-sort") === "ascending" ? 1 : -1)) + .forEach(tr => tr.parentElement.appendChild(tr) ); +} + +// Find all the elements with data-shortcut attribute, and use them to assign a shortcut key. +coverage.assign_shortkeys = function () { + document.querySelectorAll("[data-shortcut]").forEach(element => { + document.addEventListener("keypress", event => { + if (event.target.tagName.toLowerCase() === "input") { + return; // ignore keypress from search filter + } + if (event.key === element.dataset.shortcut) { + element.click(); + } + }); + }); +}; + +// Create the events for the filter box. +coverage.wire_up_filter = function () { + // Cache elements. + const table = document.querySelector("table.index"); + const table_body_rows = table.querySelectorAll("tbody tr"); + const no_rows = document.getElementById("no_rows"); + + // Observe filter keyevents. + document.getElementById("filter").addEventListener("input", debounce(event => { + // Keep running total of each metric, first index contains number of shown rows + const totals = new Array(table.rows[0].cells.length).fill(0); + // Accumulate the percentage as fraction + totals[totals.length - 1] = { "numer": 0, "denom": 0 }; // nosemgrep: eslint.detect-object-injection + + // Hide / show elements. + table_body_rows.forEach(row => { + if (!row.cells[0].textContent.includes(event.target.value)) { + // hide + row.classList.add("hidden"); + return; + } + + // show + row.classList.remove("hidden"); + totals[0]++; + + for (let column = 1; column < totals.length; column++) { + // Accumulate dynamic totals + cell = row.cells[column] // nosemgrep: eslint.detect-object-injection + if (column === totals.length - 1) { + // Last column contains percentage + const [numer, denom] = cell.dataset.ratio.split(" "); + totals[column]["numer"] += parseInt(numer, 10); // nosemgrep: eslint.detect-object-injection + totals[column]["denom"] += parseInt(denom, 10); // nosemgrep: eslint.detect-object-injection + } else { + totals[column] += parseInt(cell.textContent, 10); // nosemgrep: eslint.detect-object-injection + } + } + }); + + // Show placeholder if no rows will be displayed. + if (!totals[0]) { + // Show placeholder, hide table. + no_rows.style.display = "block"; + table.style.display = "none"; + return; + } + + // Hide placeholder, show table. + no_rows.style.display = null; + table.style.display = null; + + const footer = table.tFoot.rows[0]; + // Calculate new dynamic sum values based on visible rows. + for (let column = 1; column < totals.length; column++) { + // Get footer cell element. + const cell = footer.cells[column]; // nosemgrep: eslint.detect-object-injection + + // Set value into dynamic footer cell element. + if (column === totals.length - 1) { + // Percentage column uses the numerator and denominator, + // and adapts to the number of decimal places. + const match = /\.([0-9]+)/.exec(cell.textContent); + const places = match ? match[1].length : 0; + const { numer, denom } = totals[column]; // nosemgrep: eslint.detect-object-injection + cell.dataset.ratio = `${numer} ${denom}`; + // Check denom to prevent NaN if filtered files contain no statements + cell.textContent = denom + ? `${(numer * 100 / denom).toFixed(places)}%` + : `${(100).toFixed(places)}%`; + } else { + cell.textContent = totals[column]; // nosemgrep: eslint.detect-object-injection + } + } + })); + + // Trigger change event on setup, to force filter on page refresh + // (filter value may still be present). + document.getElementById("filter").dispatchEvent(new Event("input")); +}; + +coverage.INDEX_SORT_STORAGE = "COVERAGE_INDEX_SORT_2"; + +// Loaded on index.html +coverage.index_ready = function () { + coverage.assign_shortkeys(); + coverage.wire_up_filter(); + document.querySelectorAll("[data-sortable] th[aria-sort]").forEach( + th => th.addEventListener("click", e => sortColumn(e.target)) + ); + + // Look for a localStorage item containing previous sort settings: + const stored_list = localStorage.getItem(coverage.INDEX_SORT_STORAGE); + + if (stored_list) { + const {column, direction} = JSON.parse(stored_list); + const th = document.querySelector("[data-sortable]").tHead.rows[0].cells[column]; // nosemgrep: eslint.detect-object-injection + th.setAttribute("aria-sort", direction === "ascending" ? "descending" : "ascending"); + th.click() + } + + // Watch for page unload events so we can save the final sort settings: + window.addEventListener("unload", function () { + const th = document.querySelector('[data-sortable] th[aria-sort="ascending"], [data-sortable] [aria-sort="descending"]'); + if (!th) { + return; + } + localStorage.setItem(coverage.INDEX_SORT_STORAGE, JSON.stringify({ + column: [...th.parentElement.cells].indexOf(th), + direction: th.getAttribute("aria-sort"), + })); + }); + + on_click(".button_prev_file", coverage.to_prev_file); + on_click(".button_next_file", coverage.to_next_file); + + on_click(".button_show_hide_help", coverage.show_hide_help); +}; + +// -- pyfile stuff -- + +coverage.LINE_FILTERS_STORAGE = "COVERAGE_LINE_FILTERS"; + +coverage.pyfile_ready = function () { + // If we're directed to a particular line number, highlight the line. + var frag = location.hash; + if (frag.length > 2 && frag[1] === "t") { + document.querySelector(frag).closest(".n").classList.add("highlight"); + coverage.set_sel(parseInt(frag.substr(2), 10)); + } else { + coverage.set_sel(0); + } + + on_click(".button_toggle_run", coverage.toggle_lines); + on_click(".button_toggle_mis", coverage.toggle_lines); + on_click(".button_toggle_exc", coverage.toggle_lines); + on_click(".button_toggle_par", coverage.toggle_lines); + + on_click(".button_next_chunk", coverage.to_next_chunk_nicely); + on_click(".button_prev_chunk", coverage.to_prev_chunk_nicely); + on_click(".button_top_of_page", coverage.to_top); + on_click(".button_first_chunk", coverage.to_first_chunk); + + on_click(".button_prev_file", coverage.to_prev_file); + on_click(".button_next_file", coverage.to_next_file); + on_click(".button_to_index", coverage.to_index); + + on_click(".button_show_hide_help", coverage.show_hide_help); + + coverage.filters = undefined; + try { + coverage.filters = localStorage.getItem(coverage.LINE_FILTERS_STORAGE); + } catch(err) {} + + if (coverage.filters) { + coverage.filters = JSON.parse(coverage.filters); + } + else { + coverage.filters = {run: false, exc: true, mis: true, par: true}; + } + + for (cls in coverage.filters) { + coverage.set_line_visibilty(cls, coverage.filters[cls]); // nosemgrep: eslint.detect-object-injection + } + + coverage.assign_shortkeys(); + coverage.init_scroll_markers(); + coverage.wire_up_sticky_header(); + + document.querySelectorAll("[id^=ctxs]").forEach( + cbox => cbox.addEventListener("click", coverage.expand_contexts) + ); + + // Rebuild scroll markers when the window height changes. + window.addEventListener("resize", coverage.build_scroll_markers); +}; + +coverage.toggle_lines = function (event) { + const btn = event.target.closest("button"); + const category = btn.value + const show = !btn.classList.contains("show_" + category); + coverage.set_line_visibilty(category, show); + coverage.build_scroll_markers(); + coverage.filters[category] = show; + try { + localStorage.setItem(coverage.LINE_FILTERS_STORAGE, JSON.stringify(coverage.filters)); + } catch(err) {} +}; + +coverage.set_line_visibilty = function (category, should_show) { + const cls = "show_" + category; + const btn = document.querySelector(".button_toggle_" + category); + if (btn) { + if (should_show) { + document.querySelectorAll("#source ." + category).forEach(e => e.classList.add(cls)); + btn.classList.add(cls); + } + else { + document.querySelectorAll("#source ." + category).forEach(e => e.classList.remove(cls)); + btn.classList.remove(cls); + } + } +}; + +// Return the nth line div. +coverage.line_elt = function (n) { + return document.getElementById("t" + n)?.closest("p"); +}; + +// Set the selection. b and e are line numbers. +coverage.set_sel = function (b, e) { + // The first line selected. + coverage.sel_begin = b; + // The next line not selected. + coverage.sel_end = (e === undefined) ? b+1 : e; +}; + +coverage.to_top = function () { + coverage.set_sel(0, 1); + coverage.scroll_window(0); +}; + +coverage.to_first_chunk = function () { + coverage.set_sel(0, 1); + coverage.to_next_chunk(); +}; + +coverage.to_prev_file = function () { + window.location = document.getElementById("prevFileLink").href; +} + +coverage.to_next_file = function () { + window.location = document.getElementById("nextFileLink").href; +} + +coverage.to_index = function () { + location.href = document.getElementById("indexLink").href; +} + +coverage.show_hide_help = function () { + const helpCheck = document.getElementById("help_panel_state") + helpCheck.checked = !helpCheck.checked; +} + +// Return a string indicating what kind of chunk this line belongs to, +// or null if not a chunk. +coverage.chunk_indicator = function (line_elt) { + const classes = line_elt?.className; + if (!classes) { + return null; + } + const match = classes.match(/\bshow_\w+\b/); + if (!match) { + return null; + } + return match[0]; +}; + +coverage.to_next_chunk = function () { + const c = coverage; + + // Find the start of the next colored chunk. + var probe = c.sel_end; + var chunk_indicator, probe_line; + while (true) { + probe_line = c.line_elt(probe); + if (!probe_line) { + return; + } + chunk_indicator = c.chunk_indicator(probe_line); + if (chunk_indicator) { + break; + } + probe++; + } + + // There's a next chunk, `probe` points to it. + var begin = probe; + + // Find the end of this chunk. + var next_indicator = chunk_indicator; + while (next_indicator === chunk_indicator) { + probe++; + probe_line = c.line_elt(probe); + next_indicator = c.chunk_indicator(probe_line); + } + c.set_sel(begin, probe); + c.show_selection(); +}; + +coverage.to_prev_chunk = function () { + const c = coverage; + + // Find the end of the prev colored chunk. + var probe = c.sel_begin-1; + var probe_line = c.line_elt(probe); + if (!probe_line) { + return; + } + var chunk_indicator = c.chunk_indicator(probe_line); + while (probe > 1 && !chunk_indicator) { + probe--; + probe_line = c.line_elt(probe); + if (!probe_line) { + return; + } + chunk_indicator = c.chunk_indicator(probe_line); + } + + // There's a prev chunk, `probe` points to its last line. + var end = probe+1; + + // Find the beginning of this chunk. + var prev_indicator = chunk_indicator; + while (prev_indicator === chunk_indicator) { + probe--; + if (probe <= 0) { + return; + } + probe_line = c.line_elt(probe); + prev_indicator = c.chunk_indicator(probe_line); + } + c.set_sel(probe+1, end); + c.show_selection(); +}; + +// Returns 0, 1, or 2: how many of the two ends of the selection are on +// the screen right now? +coverage.selection_ends_on_screen = function () { + if (coverage.sel_begin === 0) { + return 0; + } + + const begin = coverage.line_elt(coverage.sel_begin); + const end = coverage.line_elt(coverage.sel_end-1); + + return ( + (checkVisible(begin) ? 1 : 0) + + (checkVisible(end) ? 1 : 0) + ); +}; + +coverage.to_next_chunk_nicely = function () { + if (coverage.selection_ends_on_screen() === 0) { + // The selection is entirely off the screen: + // Set the top line on the screen as selection. + + // This will select the top-left of the viewport + // As this is most likely the span with the line number we take the parent + const line = document.elementFromPoint(0, 0).parentElement; + if (line.parentElement !== document.getElementById("source")) { + // The element is not a source line but the header or similar + coverage.select_line_or_chunk(1); + } else { + // We extract the line number from the id + coverage.select_line_or_chunk(parseInt(line.id.substring(1), 10)); + } + } + coverage.to_next_chunk(); +}; + +coverage.to_prev_chunk_nicely = function () { + if (coverage.selection_ends_on_screen() === 0) { + // The selection is entirely off the screen: + // Set the lowest line on the screen as selection. + + // This will select the bottom-left of the viewport + // As this is most likely the span with the line number we take the parent + const line = document.elementFromPoint(document.documentElement.clientHeight-1, 0).parentElement; + if (line.parentElement !== document.getElementById("source")) { + // The element is not a source line but the header or similar + coverage.select_line_or_chunk(coverage.lines_len); + } else { + // We extract the line number from the id + coverage.select_line_or_chunk(parseInt(line.id.substring(1), 10)); + } + } + coverage.to_prev_chunk(); +}; + +// Select line number lineno, or if it is in a colored chunk, select the +// entire chunk +coverage.select_line_or_chunk = function (lineno) { + var c = coverage; + var probe_line = c.line_elt(lineno); + if (!probe_line) { + return; + } + var the_indicator = c.chunk_indicator(probe_line); + if (the_indicator) { + // The line is in a highlighted chunk. + // Search backward for the first line. + var probe = lineno; + var indicator = the_indicator; + while (probe > 0 && indicator === the_indicator) { + probe--; + probe_line = c.line_elt(probe); + if (!probe_line) { + break; + } + indicator = c.chunk_indicator(probe_line); + } + var begin = probe + 1; + + // Search forward for the last line. + probe = lineno; + indicator = the_indicator; + while (indicator === the_indicator) { + probe++; + probe_line = c.line_elt(probe); + indicator = c.chunk_indicator(probe_line); + } + + coverage.set_sel(begin, probe); + } + else { + coverage.set_sel(lineno); + } +}; + +coverage.show_selection = function () { + // Highlight the lines in the chunk + document.querySelectorAll("#source .highlight").forEach(e => e.classList.remove("highlight")); + for (let probe = coverage.sel_begin; probe < coverage.sel_end; probe++) { + coverage.line_elt(probe).querySelector(".n").classList.add("highlight"); + } + + coverage.scroll_to_selection(); +}; + +coverage.scroll_to_selection = function () { + // Scroll the page if the chunk isn't fully visible. + if (coverage.selection_ends_on_screen() < 2) { + const element = coverage.line_elt(coverage.sel_begin); + coverage.scroll_window(element.offsetTop - 60); + } +}; + +coverage.scroll_window = function (to_pos) { + window.scroll({top: to_pos, behavior: "smooth"}); +}; + +coverage.init_scroll_markers = function () { + // Init some variables + coverage.lines_len = document.querySelectorAll("#source > p").length; + + // Build html + coverage.build_scroll_markers(); +}; + +coverage.build_scroll_markers = function () { + const temp_scroll_marker = document.getElementById("scroll_marker") + if (temp_scroll_marker) temp_scroll_marker.remove(); + // Don't build markers if the window has no scroll bar. + if (document.body.scrollHeight <= window.innerHeight) { + return; + } + + const marker_scale = window.innerHeight / document.body.scrollHeight; + const line_height = Math.min(Math.max(3, window.innerHeight / coverage.lines_len), 10); + + let previous_line = -99, last_mark, last_top; + + const scroll_marker = document.createElement("div"); + scroll_marker.id = "scroll_marker"; + document.getElementById("source").querySelectorAll( + "p.show_run, p.show_mis, p.show_exc, p.show_exc, p.show_par" + ).forEach(element => { + const line_top = Math.floor(element.offsetTop * marker_scale); + const line_number = parseInt(element.querySelector(".n a").id.substr(1)); + + if (line_number === previous_line + 1) { + // If this solid missed block just make previous mark higher. + last_mark.style.height = `${line_top + line_height - last_top}px`; + } else { + // Add colored line in scroll_marker block. + last_mark = document.createElement("div"); + last_mark.id = `m${line_number}`; + last_mark.classList.add("marker"); + last_mark.style.height = `${line_height}px`; + last_mark.style.top = `${line_top}px`; + scroll_marker.append(last_mark); + last_top = line_top; + } + + previous_line = line_number; + }); + + // Append last to prevent layout calculation + document.body.append(scroll_marker); +}; + +coverage.wire_up_sticky_header = function () { + const header = document.querySelector("header"); + const header_bottom = ( + header.querySelector(".content h2").getBoundingClientRect().top - + header.getBoundingClientRect().top + ); + + function updateHeader() { + if (window.scrollY > header_bottom) { + header.classList.add("sticky"); + } else { + header.classList.remove("sticky"); + } + } + + window.addEventListener("scroll", updateHeader); + updateHeader(); +}; + +coverage.expand_contexts = function (e) { + var ctxs = e.target.parentNode.querySelector(".ctxs"); + + if (!ctxs.classList.contains("expanded")) { + var ctxs_text = ctxs.textContent; + var width = Number(ctxs_text[0]); + ctxs.textContent = ""; + for (var i = 1; i < ctxs_text.length; i += width) { + key = ctxs_text.substring(i, i + width).trim(); + ctxs.appendChild(document.createTextNode(contexts[key])); + ctxs.appendChild(document.createElement("br")); + } + ctxs.classList.add("expanded"); + } +}; + +document.addEventListener("DOMContentLoaded", () => { + if (document.body.classList.contains("indexfile")) { + coverage.index_ready(); + } else { + coverage.pyfile_ready(); + } +}); diff --git a/coverage/d_bb657af29d23493a_Attributes_py.html b/coverage/d_bb657af29d23493a_Attributes_py.html new file mode 100644 index 00000000..81cedfe0 --- /dev/null +++ b/coverage/d_bb657af29d23493a_Attributes_py.html @@ -0,0 +1,152 @@ + + + + + Coverage for pyEDAA/ProjectModel/Attributes.py: 100% + + + + + +
+
+

+ Coverage for pyEDAA/ProjectModel/Attributes.py: + 100% +

+ +

+ 15 statements   + + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.3.0, + created at 2023-08-24 21:52 +0000 +

+ +
+
+
+

1# ==================================================================================================================== # 

+

2# _____ ____ _ _ ____ _ _ __ __ _ _ # 

+

3# _ __ _ _| ____| _ \ / \ / \ | _ \ _ __ ___ (_) ___ ___| |_| \/ | ___ __| | ___| | # 

+

4# | '_ \| | | | _| | | | |/ _ \ / _ \ | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ | # 

+

5# | |_) | |_| | |___| |_| / ___ \ / ___ \ _| __/| | | (_) | | __/ (__| |_| | | | (_) | (_| | __/ | # 

+

6# | .__/ \__, |_____|____/_/ \_\/_/ \_(_)_| |_| \___// |\___|\___|\__|_| |_|\___/ \__,_|\___|_| # 

+

7# |_| |___/ |__/ # 

+

8# ==================================================================================================================== # 

+

9# Authors: # 

+

10# Patrick Lehmann # 

+

11# # 

+

12# License: # 

+

13# ==================================================================================================================== # 

+

14# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany # 

+

15# # 

+

16# Licensed under the Apache License, Version 2.0 (the "License"); # 

+

17# you may not use this file except in compliance with the License. # 

+

18# You may obtain a copy of the License at # 

+

19# # 

+

20# http://www.apache.org/licenses/LICENSE-2.0 # 

+

21# # 

+

22# Unless required by applicable law or agreed to in writing, software # 

+

23# distributed under the License is distributed on an "AS IS" BASIS, # 

+

24# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # 

+

25# See the License for the specific language governing permissions and # 

+

26# limitations under the License. # 

+

27# # 

+

28# SPDX-License-Identifier: Apache-2.0 # 

+

29# ==================================================================================================================== # 

+

30# 

+

31"""A set of common attributes to store meta information on ProjectModel entities (project, design, fileset, file, ...).""" 

+

32from typing import Dict 

+

33from pyTooling.Decorators import export 

+

34 

+

35from pyEDAA.ProjectModel import Attribute 

+

36 

+

37 

+

38@export 

+

39class KeyValueAttribute(Attribute): 

+

40 KEY = "ID" 

+

41 

+

42 _keyValuePairs: Dict[str, str] 

+

43 

+

44 def __init__(self): 

+

45 super().__init__() 

+

46 

+

47 self._keyValuePairs = {} 

+

48 

+

49 def __getitem__(self, item: str) -> str: 

+

50 return self._keyValuePairs[item] 

+

51 

+

52 def __setitem__(self, key: str, value: str) -> None: 

+

53 self._keyValuePairs[key] = value 

+
+ + + diff --git a/coverage/d_bb657af29d23493a___init___py.html b/coverage/d_bb657af29d23493a___init___py.html new file mode 100644 index 00000000..e2e42b9c --- /dev/null +++ b/coverage/d_bb657af29d23493a___init___py.html @@ -0,0 +1,1952 @@ + + + + + Coverage for pyEDAA/ProjectModel/__init__.py: 73% + + + + + +
+
+

+ Coverage for pyEDAA/ProjectModel/__init__.py: + 73% +

+ +

+ 1064 statements   + + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.3.0, + created at 2023-08-24 21:52 +0000 +

+ +
+
+
+

1# ==================================================================================================================== # 

+

2# _____ ____ _ _ ____ _ _ __ __ _ _ # 

+

3# _ __ _ _| ____| _ \ / \ / \ | _ \ _ __ ___ (_) ___ ___| |_| \/ | ___ __| | ___| | # 

+

4# | '_ \| | | | _| | | | |/ _ \ / _ \ | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ | # 

+

5# | |_) | |_| | |___| |_| / ___ \ / ___ \ _| __/| | | (_) | | __/ (__| |_| | | | (_) | (_| | __/ | # 

+

6# | .__/ \__, |_____|____/_/ \_\/_/ \_(_)_| |_| \___// |\___|\___|\__|_| |_|\___/ \__,_|\___|_| # 

+

7# |_| |___/ |__/ # 

+

8# ==================================================================================================================== # 

+

9# Authors: # 

+

10# Patrick Lehmann # 

+

11# # 

+

12# License: # 

+

13# ==================================================================================================================== # 

+

14# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany # 

+

15# Copyright 2014-2016 Technische Universität Dresden - Germany, Chair of VLSI-Design, Diagnostics and Architecture # 

+

16# # 

+

17# Licensed under the Apache License, Version 2.0 (the "License"); # 

+

18# you may not use this file except in compliance with the License. # 

+

19# You may obtain a copy of the License at # 

+

20# # 

+

21# http://www.apache.org/licenses/LICENSE-2.0 # 

+

22# # 

+

23# Unless required by applicable law or agreed to in writing, software # 

+

24# distributed under the License is distributed on an "AS IS" BASIS, # 

+

25# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # 

+

26# See the License for the specific language governing permissions and # 

+

27# limitations under the License. # 

+

28# # 

+

29# SPDX-License-Identifier: Apache-2.0 # 

+

30# ==================================================================================================================== # 

+

31# 

+

32"""An abstract model of EDA tool projects.""" 

+

33__author__ = "Patrick Lehmann" 

+

34__email__ = "Paebbels@gmail.com" 

+

35__copyright__ = "2014-2023, Patrick Lehmann, Unai Martinez-Corral" 

+

36__license__ = "Apache License, Version 2.0" 

+

37__version__ = "0.5.0" 

+

38__keywords__ = ["eda project", "model", "abstract", "xilinx", "vivado", "osvvm", "file set", "file group", "test bench", "test harness"] 

+

39 

+

40from os.path import relpath as path_relpath 

+

41from pathlib import Path as pathlib_Path 

+

42from typing import Dict, Union, Optional as Nullable, List, Iterable, Generator, Tuple, Any as typing_Any, Type, Set, Any 

+

43 

+

44from pyTooling.Decorators import export 

+

45from pyTooling.MetaClasses import ExtendedType 

+

46from pyTooling.Graph import Graph, Vertex 

+

47from pySVModel import SystemVerilogVersion 

+

48from pyVHDLModel import VHDLVersion 

+

49from pySystemRDLModel import SystemRDLVersion 

+

50 

+

51 

+

52@export 

+

53class Attribute(metaclass=ExtendedType): 

+

54 KEY: str 

+

55 VALUE_TYPE: typing_Any 

+

56 

+

57 @staticmethod 

+

58 def resolve(obj: typing_Any, key: Type['Attribute']): 

+

59 if isinstance(obj, File): 59 ↛ 61line 59 didn't jump to line 61, because the condition on line 59 was never false

+

60 return obj._fileSet[key] 

+

61 elif isinstance(obj, FileSet): 

+

62 return obj._design[key] 

+

63 elif isinstance(obj, Design): 

+

64 return obj._project[key] 

+

65 else: 

+

66 raise Exception("Resolution error") 

+

67 

+

68 

+

69@export 

+

70class FileType(ExtendedType): 

+

71 """ 

+

72 A :term:`meta-class` to construct *FileType* classes. 

+

73 

+

74 Modifications done by this meta-class: 

+

75 * Register all classes of type :class:`FileType` or derived variants in a class field :attr:`FileType.FileTypes` in this meta-class. 

+

76 """ 

+

77 

+

78 FileTypes: Dict[str, 'FileType'] = {} #: Dictionary of all classes of type :class:`FileType` or derived variants 

+

79 Any: 'FileType' 

+

80 

+

81 def __init__(cls, name: str, bases: Tuple[type, ...], dictionary: Dict[str, typing_Any], **kwargs): 

+

82 super().__init__(name, bases, dictionary, **kwargs) 

+

83 cls.Any = cls 

+

84 

+

85 def __new__(cls, className, baseClasses, classMembers: Dict, *args, **kwargs): 

+

86 fileType = super().__new__(cls, className, baseClasses, classMembers, *args, **kwargs) 

+

87 cls.FileTypes[className] = fileType 

+

88 return fileType 

+

89 

+

90 def __getattr__(cls, item) -> 'FileType': 

+

91 if item[:2] != "__" and item[-2:] != "__": 

+

92 return cls.FileTypes[item] 

+

93 else: 

+

94 return super().__getattribute__(item) 

+

95 

+

96 def __contains__(cls, item) -> bool: 

+

97 return issubclass(item, cls) 

+

98 

+

99 

+

100@export 

+

101class File(metaclass=FileType, slots=True): 

+

102 """ 

+

103 A :term:`File` represents a file in a design. This :term:`base-class` is used 

+

104 for all derived file classes. 

+

105 

+

106 A file can be created standalone and later associated to a fileset, design and 

+

107 project. Or a fileset, design and/or project can be associated immediately 

+

108 while creating a file. 

+

109 

+

110 :arg path: Relative or absolute path to the file. 

+

111 :arg project: Project the file is associated with. 

+

112 :arg design: Design the file is associated with. 

+

113 :arg fileSet: Fileset the file is associated with. 

+

114 """ 

+

115 

+

116 _path: pathlib_Path 

+

117 _fileType: 'FileType' 

+

118 _project: Nullable['Project'] 

+

119 _design: Nullable['Design'] 

+

120 _fileSet: Nullable['FileSet'] 

+

121 _attributes: Dict[Type[Attribute], typing_Any] 

+

122 

+

123 def __init__( 

+

124 self, 

+

125 path: pathlib_Path, 

+

126 project: 'Project' = None, 

+

127 design: 'Design' = None, 

+

128 fileSet: 'FileSet' = None 

+

129 ): 

+

130 self._fileType = getattr(FileTypes, self.__class__.__name__) 

+

131 self._path = path 

+

132 if project is not None: 

+

133 self._project = project 

+

134 self._design = design 

+

135 if fileSet is not None: 135 ↛ 136line 135 didn't jump to line 136, because the condition on line 135 was never true

+

136 self.FileSet = fileSet 

+

137 elif design is not None: 

+

138 self._project = design._project 

+

139 self._design = design 

+

140 self.FileSet = design.DefaultFileSet if fileSet is None else fileSet 

+

141 elif fileSet is not None: 

+

142 design = fileSet._design 

+

143 if design is not None: 

+

144 self._project = design._project 

+

145 else: 

+

146 self._project = None 

+

147 self._design = design 

+

148 self.FileSet = fileSet 

+

149 else: 

+

150 self._project = None 

+

151 self._design = None 

+

152 self._fileSet = None 

+

153 

+

154 self._attributes = {} 

+

155 self._registerAttributes() 

+

156 

+

157 def _registerAttributes(self): 

+

158 pass 

+

159 

+

160 @property 

+

161 def FileType(self) -> 'FileType': 

+

162 """Read-only property to return the file type of this file.""" 

+

163 return self._fileType 

+

164 

+

165 @property 

+

166 def Path(self) -> pathlib_Path: 

+

167 """Read-only property returning the path of this file.""" 

+

168 return self._path 

+

169 

+

170 # TODO: setter? 

+

171 

+

172 @property 

+

173 def ResolvedPath(self) -> pathlib_Path: 

+

174 """Read-only property returning the resolved path of this file.""" 

+

175 if self._path.is_absolute(): 175 ↛ 176line 175 didn't jump to line 176, because the condition on line 175 was never true

+

176 return self._path.resolve() 

+

177 elif self._fileSet is not None: 177 ↛ 187line 177 didn't jump to line 187, because the condition on line 177 was never false

+

178 path = (self._fileSet.ResolvedPath / self._path).resolve() 

+

179 

+

180 if path.is_absolute(): 180 ↛ 184line 180 didn't jump to line 184, because the condition on line 180 was never false

+

181 return path 

+

182 else: 

+

183 # WORKAROUND: https://stackoverflow.com/questions/67452690/pathlib-path-relative-to-vs-os-path-relpath 

+

184 return pathlib_Path(path_relpath(path, pathlib_Path.cwd())) 

+

185 else: 

+

186 # TODO: message and exception type 

+

187 raise Exception("") 

+

188 

+

189 @property 

+

190 def Project(self) -> Nullable['Project']: 

+

191 """Property setting or returning the project this file is used in.""" 

+

192 return self._project 

+

193 

+

194 @Project.setter 

+

195 def Project(self, value: 'Project') -> None: 

+

196 self._project = value 

+

197 

+

198 if self._fileSet is None: 198 ↛ exitline 198 didn't return from function 'Project', because the condition on line 198 was never false

+

199 self._project.DefaultDesign.DefaultFileSet.AddFile(self) 

+

200 

+

201 @property 

+

202 def Design(self) -> Nullable['Design']: 

+

203 """Property setting or returning the design this file is used in.""" 

+

204 return self._design 

+

205 

+

206 @Design.setter 

+

207 def Design(self, value: 'Design') -> None: 

+

208 self._design = value 

+

209 

+

210 if self._fileSet is None: 210 ↛ 213line 210 didn't jump to line 213, because the condition on line 210 was never false

+

211 self._design.DefaultFileSet.AddFile(self) 

+

212 

+

213 if self._project is None: 213 ↛ 215line 213 didn't jump to line 215, because the condition on line 213 was never false

+

214 self._project = value._project 

+

215 elif self._project is not value._project: 

+

216 raise Exception("The design's project is not identical to the already assigned project.") 

+

217 

+

218 @property 

+

219 def FileSet(self) -> Nullable['FileSet']: 

+

220 """Property setting or returning the fileset this file is used in.""" 

+

221 return self._fileSet 

+

222 

+

223 @FileSet.setter 

+

224 def FileSet(self, value: 'FileSet') -> None: 

+

225 self._fileSet = value 

+

226 value._files.append(self) 

+

227 

+

228 def Validate(self): 

+

229 """Validate this file.""" 

+

230 if self._path is None: 230 ↛ 231line 230 didn't jump to line 231, because the condition on line 230 was never true

+

231 raise Exception("Validation: File has no path.") 

+

232 try: 

+

233 path = self.ResolvedPath 

+

234 except Exception as ex: 

+

235 raise Exception(f"Validation: File '{self._path}' could not compute resolved path.") from ex 

+

236 if not path.exists(): 236 ↛ 237line 236 didn't jump to line 237, because the condition on line 236 was never true

+

237 raise Exception(f"Validation: File '{self._path}' (={path}) does not exist.") 

+

238 if not path.is_file(): 238 ↛ 239line 238 didn't jump to line 239, because the condition on line 238 was never true

+

239 raise Exception(f"Validation: File '{self._path}' (={path}) is not a file.") 

+

240 

+

241 if self._fileSet is None: 241 ↛ 242line 241 didn't jump to line 242, because the condition on line 241 was never true

+

242 raise Exception(f"Validation: File '{self._path}' has no fileset.") 

+

243 if self._design is None: 243 ↛ 244line 243 didn't jump to line 244, because the condition on line 243 was never true

+

244 raise Exception(f"Validation: File '{self._path}' has no design.") 

+

245 if self._project is None: 245 ↛ 246line 245 didn't jump to line 246, because the condition on line 245 was never true

+

246 raise Exception(f"Validation: File '{self._path}' has no project.") 

+

247 

+

248 def __len__(self) -> int: 

+

249 """ 

+

250 Returns number of attributes set on this file. 

+

251 

+

252 :returns: The number if attributes set on this file. 

+

253 """ 

+

254 return len(self._attributes) 

+

255 

+

256 def __getitem__(self, key: Type[Attribute]) -> Any: 

+

257 """Index access for returning attributes on this file. 

+

258 

+

259 :param key: The attribute type. 

+

260 :returns: The attribute's value. 

+

261 :raises TypeError: When parameter 'key' is not a subclass of Attribute. 

+

262 """ 

+

263 if not issubclass(key, Attribute): 263 ↛ 264line 263 didn't jump to line 264, because the condition on line 263 was never true

+

264 raise TypeError("Parameter 'key' is not an 'Attribute'.") 

+

265 

+

266 try: 

+

267 return self._attributes[key] 

+

268 except KeyError: 

+

269 return key.resolve(self, key) 

+

270 

+

271 def __setitem__(self, key: Type[Attribute], value: typing_Any) -> None: 

+

272 """ 

+

273 Index access for adding or setting attributes on this file. 

+

274 

+

275 :param key: The attribute type. 

+

276 :param value: The attributes value. 

+

277 :raises TypeError: When parameter 'key' is not a subclass of Attribute. 

+

278 """ 

+

279 if not issubclass(key, Attribute): 279 ↛ 280line 279 didn't jump to line 280, because the condition on line 279 was never true

+

280 raise TypeError("Parameter 'key' is not an 'Attribute'.") 

+

281 

+

282 self._attributes[key] = value 

+

283 

+

284 def __delitem__(self, key: Type[Attribute]) -> None: 

+

285 """ 

+

286 Index access for deleting attributes on this file. 

+

287 

+

288 :param key: The attribute type. 

+

289 """ 

+

290 if not issubclass(key, Attribute): 

+

291 raise TypeError("Parameter 'key' is not an 'Attribute'.") 

+

292 

+

293 del self._attributes[key] 

+

294 

+

295 def __str__(self) -> str: 

+

296 return f"{self._path}" 

+

297 

+

298 

+

299FileTypes = File 

+

300 

+

301 

+

302@export 

+

303class HumanReadableContent(metaclass=ExtendedType, mixin=True): 

+

304 """A file type representing human-readable contents.""" 

+

305 

+

306 

+

307@export 

+

308class XMLContent(HumanReadableContent, mixin=True): 

+

309 """A file type representing XML contents.""" 

+

310 

+

311 

+

312@export 

+

313class YAMLContent(HumanReadableContent, mixin=True): 

+

314 """A file type representing YAML contents.""" 

+

315 

+

316 

+

317@export 

+

318class JSONContent(HumanReadableContent, mixin=True): 

+

319 """A file type representing JSON contents.""" 

+

320 

+

321 

+

322@export 

+

323class INIContent(HumanReadableContent, mixin=True): 

+

324 """A file type representing INI contents.""" 

+

325 

+

326 

+

327@export 

+

328class TOMLContent(HumanReadableContent, mixin=True): 

+

329 """A file type representing TOML contents.""" 

+

330 

+

331 

+

332@export 

+

333class TCLContent(HumanReadableContent, mixin=True): 

+

334 """A file type representing content in TCL code.""" 

+

335 

+

336 

+

337@export 

+

338class SDCContent(TCLContent, mixin=True): 

+

339 """A file type representing contents as Synopsys Design Constraints (SDC).""" 

+

340 

+

341 

+

342@export 

+

343class PythonContent(HumanReadableContent, mixin=True): 

+

344 """A file type representing contents as Python source code.""" 

+

345 

+

346 

+

347@export 

+

348class TextFile(File, HumanReadableContent): 

+

349 """A text file (``*.txt``).""" 

+

350 

+

351 

+

352@export 

+

353class LogFile(File, HumanReadableContent): 

+

354 """A log file (``*.log``).""" 

+

355 

+

356 

+

357@export 

+

358class XMLFile(File, XMLContent): 

+

359 """An XML file (``*.xml``).""" 

+

360 

+

361 

+

362@export 

+

363class SourceFile(File): 

+

364 """Base-class of all source files.""" 

+

365 

+

366 

+

367@export 

+

368class HDLSourceFile(SourceFile): 

+

369 """Base-class of all HDL source files.""" 

+

370 

+

371 

+

372@export 

+

373class RDLSourceFile(SourceFile): 

+

374 """Base-class of all RDL source files.""" 

+

375 

+

376 

+

377@export 

+

378class NetlistFile(SourceFile): 

+

379 """Base-class of all netlist source files.""" 

+

380 

+

381 

+

382@export 

+

383class EDIFNetlistFile(NetlistFile): 

+

384 """Netlist file in EDIF (Electronic Design Interchange Format).""" 

+

385 

+

386 

+

387@export 

+

388class TCLSourceFile(SourceFile, TCLContent): 

+

389 """A TCL source file.""" 

+

390 

+

391 

+

392@export 

+

393class VHDLSourceFile(HDLSourceFile, HumanReadableContent): 

+

394 """ 

+

395 A VHDL source file (of any language version). 

+

396 

+

397 :arg path: Relative or absolute path to the file. 

+

398 :arg vhdlLibrary: VHDLLibrary this VHDL source file is associated wih. 

+

399 :arg vhdlVersion: VHDLVersion this VHDL source file is associated wih. 

+

400 :arg project: Project the file is associated with. 

+

401 :arg design: Design the file is associated with. 

+

402 :arg fileSet: Fileset the file is associated with. 

+

403 """ 

+

404 

+

405 _vhdlLibrary: Nullable['VHDLLibrary'] 

+

406 _vhdlVersion: VHDLVersion 

+

407 

+

408 def __init__(self, path: pathlib_Path, vhdlLibrary: Union[str, 'VHDLLibrary'] = None, vhdlVersion: VHDLVersion = None, project: 'Project' = None, design: 'Design' = None, fileSet: 'FileSet' = None): 

+

409 super().__init__(path, project, design, fileSet) 

+

410 

+

411 if isinstance(vhdlLibrary, str): 411 ↛ 412line 411 didn't jump to line 412, because the condition on line 411 was never true

+

412 if design is not None: 

+

413 try: 

+

414 vhdlLibrary = design.VHDLLibraries[vhdlLibrary] 

+

415 except KeyError as ex: 

+

416 raise Exception(f"VHDL library '{vhdlLibrary}' not found in design '{design.Name}'.") from ex 

+

417 elif project is not None: 

+

418 try: 

+

419 vhdlLibrary = project.DefaultDesign.VHDLLibraries[vhdlLibrary] 

+

420 except KeyError as ex: 

+

421 raise Exception(f"VHDL library '{vhdlLibrary}' not found in default design '{project.DefaultDesign.Name}'.") from ex 

+

422 else: 

+

423 raise Exception(f"Can't lookup VHDL library because neither 'project' nor 'design' is given as a parameter.") 

+

424 elif isinstance(vhdlLibrary, VHDLLibrary): 

+

425 self._vhdlLibrary = vhdlLibrary 

+

426 vhdlLibrary.AddFile(self) 

+

427 elif vhdlLibrary is None: 427 ↛ 430line 427 didn't jump to line 430, because the condition on line 427 was never false

+

428 self._vhdlLibrary = None 

+

429 else: 

+

430 raise TypeError(f"Parameter 'vhdlLibrary' is neither a 'str' nor 'VHDLibrary'.") 

+

431 

+

432 self._vhdlVersion = vhdlVersion 

+

433 

+

434 def Validate(self) -> None: 

+

435 """Validate this VHDL source file.""" 

+

436 super().Validate() 

+

437 

+

438 try: 

+

439 _ = self.VHDLLibrary 

+

440 except Exception as ex: 

+

441 raise Exception(f"Validation: VHDLSourceFile '{self._path}' (={self.ResolvedPath}) has no VHDLLibrary assigned.") from ex 

+

442 try: 

+

443 _ = self.VHDLVersion 

+

444 except Exception as ex: 

+

445 raise Exception(f"Validation: VHDLSourceFile '{self._path}' (={self.ResolvedPath}) has no VHDLVersion assigned.") from ex 

+

446 

+

447 @property 

+

448 def VHDLLibrary(self) -> 'VHDLLibrary': 

+

449 """Property setting or returning the VHDL library this VHDL source file is used in.""" 

+

450 if self._vhdlLibrary is not None: 

+

451 return self._vhdlLibrary 

+

452 elif self._fileSet is not None: 

+

453 return self._fileSet.VHDLLibrary 

+

454 else: 

+

455 raise Exception("VHDLLibrary was neither set locally nor globally.") 

+

456 

+

457 @VHDLLibrary.setter 

+

458 def VHDLLibrary(self, value: 'VHDLLibrary') -> None: 

+

459 self._vhdlLibrary = value 

+

460 value._files.append(self) 

+

461 

+

462 @property 

+

463 def VHDLVersion(self) -> VHDLVersion: 

+

464 """Property setting or returning the VHDL version this VHDL source file is used in.""" 

+

465 if self._vhdlVersion is not None: 

+

466 return self._vhdlVersion 

+

467 elif self._fileSet is not None: 

+

468 return self._fileSet.VHDLVersion 

+

469 else: 

+

470 raise Exception("VHDLVersion was neither set locally nor globally.") 

+

471 

+

472 @VHDLVersion.setter 

+

473 def VHDLVersion(self, value: VHDLVersion) -> None: 

+

474 self._vhdlVersion = value 

+

475 

+

476 def __repr__(self) -> str: 

+

477 return f"<VHDL file: '{self.ResolvedPath}'; lib: '{self.VHDLLibrary}'; version: {self.VHDLVersion}>" 

+

478 

+

479 

+

480class VerilogMixIn(metaclass=ExtendedType, mixin=True): 

+

481 @property 

+

482 def VerilogVersion(self) -> SystemVerilogVersion: 

+

483 """Property setting or returning the Verilog version this Verilog source file is used in.""" 

+

484 if self._version is not None: 

+

485 return self._version 

+

486 elif self._fileSet is not None: 

+

487 return self._fileSet.VerilogVersion 

+

488 else: 

+

489 raise Exception("VerilogVersion was neither set locally nor globally.") 

+

490 

+

491 @VerilogVersion.setter 

+

492 def VerilogVersion(self, value: SystemVerilogVersion) -> None: 

+

493 self._version = value 

+

494 

+

495 

+

496class SystemVerilogMixIn(metaclass=ExtendedType, mixin=True): 

+

497 @property 

+

498 def SVVersion(self) -> SystemVerilogVersion: 

+

499 """Property setting or returning the SystemVerilog version this SystemVerilog source file is used in.""" 

+

500 if self._version is not None: 

+

501 return self._version 

+

502 elif self._fileSet is not None: 

+

503 return self._fileSet.SVVersion 

+

504 else: 

+

505 raise Exception("SVVersion was neither set locally nor globally.") 

+

506 

+

507 @SVVersion.setter 

+

508 def SVVersion(self, value: SystemVerilogVersion) -> None: 

+

509 self._version = value 

+

510 

+

511 

+

512@export 

+

513class VerilogBaseFile(HDLSourceFile, HumanReadableContent): 

+

514 _version: SystemVerilogVersion 

+

515 

+

516 def __init__(self, path: pathlib_Path, version: SystemVerilogVersion = None, project: 'Project' = None, design: 'Design' = None, fileSet: 'FileSet' = None): 

+

517 super().__init__(path, project, design, fileSet) 

+

518 

+

519 self._version = version 

+

520 

+

521 

+

522@export 

+

523class VerilogSourceFile(VerilogBaseFile, VerilogMixIn): 

+

524 """A Verilog source file (of any language version).""" 

+

525 

+

526 

+

527@export 

+

528class VerilogHeaderFile(VerilogBaseFile, VerilogMixIn): 

+

529 """A Verilog header file (of any language version).""" 

+

530 

+

531 

+

532@export 

+

533class SystemVerilogBaseFile(VerilogBaseFile): 

+

534 ... 

+

535 

+

536 

+

537@export 

+

538class SystemVerilogSourceFile(SystemVerilogBaseFile, SystemVerilogMixIn): 

+

539 """A SystemVerilog source file (of any language version).""" 

+

540 

+

541 

+

542@export 

+

543class SystemVerilogHeaderFile(SystemVerilogBaseFile, SystemVerilogMixIn): 

+

544 """A SystemVerilog header file (of any language version).""" 

+

545 

+

546 

+

547@export 

+

548class SystemRDLSourceFile(RDLSourceFile, HumanReadableContent): 

+

549 """A SystemRDL source file (of any language version).""" 

+

550 

+

551 _srdlVersion: SystemRDLVersion 

+

552 

+

553 def __init__(self, path: pathlib_Path, srdlVersion: SystemRDLVersion = None, project: 'Project' = None, design: 'Design' = None, fileSet: 'FileSet' = None): 

+

554 super().__init__(path, project, design, fileSet) 

+

555 

+

556 self._srdlVersion = srdlVersion 

+

557 

+

558 @property 

+

559 def SystemRDLVersion(self) -> SystemRDLVersion: 

+

560 """Property setting or returning the SystemRDL version this SystemRDL source file is used in.""" 

+

561 if self._srdlVersion is not None: 

+

562 return self._srdlVersion 

+

563 elif self._fileSet is not None: 

+

564 return self._fileSet.SRDLVersion 

+

565 else: 

+

566 raise Exception("SRDLVersion was neither set locally nor globally.") 

+

567 

+

568 @SystemRDLVersion.setter 

+

569 def SystemRDLVersion(self, value: SystemRDLVersion) -> None: 

+

570 self._srdlVersion = value 

+

571 

+

572 

+

573@export 

+

574class PythonSourceFile(SourceFile, PythonContent): 

+

575 """A Python source file.""" 

+

576 

+

577 

+

578# TODO: move to a Cocotb module 

+

579@export 

+

580class CocotbPythonFile(PythonSourceFile): 

+

581 """A Python source file used by Cocotb.""" 

+

582 

+

583 

+

584@export 

+

585class ConstraintFile(File, HumanReadableContent): 

+

586 """Base-class of all constraint files.""" 

+

587 

+

588 

+

589@export 

+

590class ProjectFile(File): 

+

591 """Base-class of all tool-specific project files.""" 

+

592 

+

593 

+

594@export 

+

595class CSourceFile(SourceFile): 

+

596 """Base-class of all ANSI-C source files.""" 

+

597 

+

598 

+

599@export 

+

600class CppSourceFile(SourceFile): 

+

601 """Base-class of all ANSI-C++ source files.""" 

+

602 

+

603 

+

604@export 

+

605class SettingFile(File): 

+

606 """Base-class of all tool-specific setting files.""" 

+

607 

+

608 

+

609@export 

+

610class SimulationAnalysisFile(File): 

+

611 """Base-class of all tool-specific analysis files.""" 

+

612 

+

613 

+

614@export 

+

615class SimulationElaborationFile(File): 

+

616 """Base-class of all tool-specific elaboration files.""" 

+

617 

+

618 

+

619@export 

+

620class SimulationStartFile(File): 

+

621 """Base-class of all tool-specific simulation start-up files.""" 

+

622 

+

623 

+

624@export 

+

625class SimulationRunFile(File): 

+

626 """Base-class of all tool-specific simulation run (execution) files.""" 

+

627 

+

628 

+

629@export 

+

630class WaveformConfigFile(File): 

+

631 """Base-class of all tool-specific waveform configuration files.""" 

+

632 

+

633 

+

634@export 

+

635class WaveformDatabaseFile(File): 

+

636 """Base-class of all tool-specific waveform database files.""" 

+

637 

+

638 

+

639@export 

+

640class WaveformExchangeFile(File): 

+

641 """Base-class of all tool-independent waveform exchange files.""" 

+

642 

+

643 

+

644@export 

+

645class FileSet(metaclass=ExtendedType, slots=True): 

+

646 """ 

+

647 A :term:`FileSet` represents a group of files. Filesets can have sub-filesets. 

+

648 

+

649 The order of insertion is preserved. A fileset can be created standalone and 

+

650 later associated to another fileset, design and/or project. Or a fileset, 

+

651 design and/or project can be associated immediately while creating the 

+

652 fileset. 

+

653 

+

654 :arg name: Name of this fileset. 

+

655 :arg topLevel: Name of the fileset's toplevel. 

+

656 :arg directory: Path of this fileset (absolute or relative to a parent fileset or design). 

+

657 :arg project: Project the file is associated with. 

+

658 :arg design: Design the file is associated with. 

+

659 :arg parent: Parent fileset if this fileset is nested. 

+

660 :arg vhdlLibrary: Default VHDL library for files in this fileset, if not specified for the file itself. 

+

661 :arg vhdlVersion: Default VHDL version for files in this fileset, if not specified for the file itself. 

+

662 :arg verilogVersion: Default Verilog version for files in this fileset, if not specified for the file itself. 

+

663 :arg svVersion: Default SystemVerilog version for files in this fileset, if not specified for the file itself. 

+

664 :arg srdlVersion: Default SystemRDL version for files in this fileset, if not specified for the file itself. 

+

665 """ 

+

666 

+

667 _name: str 

+

668 _topLevel: Nullable[str] 

+

669 _project: Nullable['Project'] 

+

670 _design: Nullable['Design'] 

+

671 _directory: pathlib_Path 

+

672 _parent: Nullable['FileSet'] 

+

673 _fileSets: Dict[str, 'FileSet'] 

+

674 _files: List[File] 

+

675 _set: Set 

+

676 _attributes: Dict[Type[Attribute], typing_Any] 

+

677 _vhdlLibraries: Dict[str, 'VHDLLibrary'] 

+

678 _vhdlLibrary: 'VHDLLibrary' 

+

679 _vhdlVersion: VHDLVersion 

+

680 _verilogVersion: SystemVerilogVersion 

+

681 _svVersion: SystemVerilogVersion 

+

682 _srdlVersion: SystemRDLVersion 

+

683 

+

684 def __init__( 

+

685 self, 

+

686 name: str, 

+

687 topLevel: str = None, 

+

688 directory: pathlib_Path = pathlib_Path("."), 

+

689 project: 'Project' = None, 

+

690 design: 'Design' = None, 

+

691 parent: Nullable['FileSet'] = None, 

+

692 vhdlLibrary: Union[str, 'VHDLLibrary'] = None, 

+

693 vhdlVersion: VHDLVersion = None, 

+

694 verilogVersion: SystemVerilogVersion = None, 

+

695 svVersion: SystemVerilogVersion = None, 

+

696 srdlVersion: SystemRDLVersion = None 

+

697 ): 

+

698 self._name = name 

+

699 self._topLevel = topLevel 

+

700 if project is not None: 

+

701 self._project = project 

+

702 self._design = design if design is not None else project.DefaultDesign 

+

703 

+

704 elif design is not None: 

+

705 self._project = design._project 

+

706 self._design = design 

+

707 else: 

+

708 self._project = None 

+

709 self._design = None 

+

710 self._directory = directory 

+

711 self._parent = parent 

+

712 self._fileSets = {} 

+

713 self._files = [] 

+

714 self._set = set() 

+

715 

+

716 if design is not None: 

+

717 design._fileSets[name] = self 

+

718 

+

719 self._attributes = {} 

+

720 self._vhdlLibraries = {} 

+

721 

+

722 # TODO: handle if vhdlLibrary is a string 

+

723 self._vhdlLibrary = vhdlLibrary 

+

724 self._vhdlVersion = vhdlVersion 

+

725 self._verilogVersion = verilogVersion 

+

726 self._svVersion = svVersion 

+

727 self._srdlVersion = srdlVersion 

+

728 

+

729 @property 

+

730 def Name(self) -> str: 

+

731 """Property setting or returning the fileset's name.""" 

+

732 return self._name 

+

733 

+

734 @Name.setter 

+

735 def Name(self, value: str) -> None: 

+

736 self._name = value 

+

737 

+

738 @property 

+

739 def TopLevel(self) -> str: 

+

740 """Property setting or returning the fileset's toplevel.""" 

+

741 return self._topLevel 

+

742 

+

743 @TopLevel.setter 

+

744 def TopLevel(self, value: str) -> None: 

+

745 self._topLevel = value 

+

746 

+

747 @property 

+

748 def Project(self) -> Nullable['Project']: 

+

749 """Property setting or returning the project this fileset is used in.""" 

+

750 return self._project 

+

751 

+

752 @Project.setter 

+

753 def Project(self, value: 'Project') -> None: 

+

754 self._project = value 

+

755 

+

756 @property 

+

757 def Design(self) -> Nullable['Design']: 

+

758 """Property setting or returning the design this fileset is used in.""" 

+

759 if self._design is not None: 

+

760 return self._design 

+

761 elif self._parent is not None: 761 ↛ 762line 761 didn't jump to line 762, because the condition on line 761 was never true

+

762 return self._parent.Design 

+

763 else: 

+

764 return None 

+

765 # TODO: raise exception instead 

+

766 # QUESTION: how to handle if design and parent is set? 

+

767 

+

768 @Design.setter 

+

769 def Design(self, value: 'Design') -> None: 

+

770 self._design = value 

+

771 if self._project is None: 771 ↛ 773line 771 didn't jump to line 773, because the condition on line 771 was never false

+

772 self._project = value._project 

+

773 elif self._project is not value._project: 

+

774 raise Exception("The design's project is not identical to the already assigned project.") 

+

775 

+

776 @property 

+

777 def Directory(self) -> pathlib_Path: 

+

778 """Property setting or returning the directory this fileset is located in.""" 

+

779 return self._directory 

+

780 

+

781 @Directory.setter 

+

782 def Directory(self, value: pathlib_Path) -> None: 

+

783 self._directory = value 

+

784 

+

785 @property 

+

786 def ResolvedPath(self) -> pathlib_Path: 

+

787 """Read-only property returning the resolved path of this fileset.""" 

+

788 if self._directory.is_absolute(): 788 ↛ 789line 788 didn't jump to line 789, because the condition on line 788 was never true

+

789 return self._directory.resolve() 

+

790 else: 

+

791 if self._parent is not None: 791 ↛ 792line 791 didn't jump to line 792, because the condition on line 791 was never true

+

792 directory = self._parent.ResolvedPath 

+

793 elif self._design is not None: 793 ↛ 795line 793 didn't jump to line 795, because the condition on line 793 was never false

+

794 directory = self._design.ResolvedPath 

+

795 elif self._project is not None: 

+

796 directory = self._project.ResolvedPath 

+

797 else: 

+

798 # TODO: message and exception type 

+

799 raise Exception("") 

+

800 

+

801 directory = (directory / self._directory).resolve() 

+

802 if directory.is_absolute(): 802 ↛ 806line 802 didn't jump to line 806, because the condition on line 802 was never false

+

803 return directory 

+

804 else: 

+

805 # WORKAROUND: https://stackoverflow.com/questions/67452690/pathlib-path-relative-to-vs-os-path-relpath 

+

806 return pathlib_Path(path_relpath(directory, pathlib_Path.cwd())) 

+

807 

+

808 @property 

+

809 def Parent(self) -> Nullable['FileSet']: 

+

810 """Property setting or returning the parent fileset this fileset is used in.""" 

+

811 return self._parent 

+

812 

+

813 @Parent.setter 

+

814 def Parent(self, value: 'FileSet') -> None: 

+

815 self._parent = value 

+

816 value._fileSets[self._name] = self 

+

817 # TODO: check it it already exists 

+

818 # QUESTION: make an Add fileset method? 

+

819 

+

820 @property 

+

821 def FileSets(self) -> Dict[str, 'FileSet']: 

+

822 """Read-only property returning the dictionary of sub-filesets.""" 

+

823 return self._fileSets 

+

824 

+

825 def Files(self, fileType: FileType = FileTypes.Any, fileSet: Union[bool, str, 'FileSet'] = None) -> Generator[File, None, None]: 

+

826 """ 

+

827 Method returning the files of this fileset. 

+

828 

+

829 :arg fileType: A filter for file types. Default: ``Any``. 

+

830 :arg fileSet: Specifies how to handle sub-filesets. 

+

831 """ 

+

832 if fileSet is False: 832 ↛ 833line 832 didn't jump to line 833, because the condition on line 832 was never true

+

833 for file in self._files: 

+

834 if file.FileType in fileType: 

+

835 yield file 

+

836 elif fileSet is None: 836 ↛ 844line 836 didn't jump to line 844, because the condition on line 836 was never false

+

837 for fileSet in self._fileSets.values(): 837 ↛ 838line 837 didn't jump to line 838, because the loop on line 837 never started

+

838 for file in fileSet.Files(fileType): 

+

839 yield file 

+

840 for file in self._files: 

+

841 if file.FileType in fileType: 

+

842 yield file 

+

843 else: 

+

844 if isinstance(fileSet, str): 

+

845 fileSetName = fileSet 

+

846 try: 

+

847 fileSet = self._fileSets[fileSetName] 

+

848 except KeyError as ex: 

+

849 raise Exception(f"Fileset {fileSetName} not bound to fileset {self.Name}.") from ex 

+

850 elif not isinstance(fileSet, FileSet): 

+

851 raise TypeError("Parameter 'fileSet' is not of type 'str' or 'FileSet' nor value 'None'.") 

+

852 

+

853 for file in fileSet.Files(fileType): 

+

854 yield file 

+

855 

+

856 def AddFileSet(self, fileSet: "FileSet") -> None: 

+

857 """ 

+

858 Method to add a single sub-fileset to this fileset. 

+

859 

+

860 :arg fileSet: A fileset to add to this fileset as sub-fileset. 

+

861 """ 

+

862 if not isinstance(fileSet, FileSet): 862 ↛ 863line 862 didn't jump to line 863, because the condition on line 862 was never true

+

863 raise ValueError("Parameter 'fileSet' is not of type ProjectModel.FileSet.") 

+

864 elif fileSet in self._fileSets: 864 ↛ 865line 864 didn't jump to line 865, because the condition on line 864 was never true

+

865 raise Exception("Sub-fileset already contains this fileset.") 

+

866 elif fileSet.Name in self._fileSets.keys(): 866 ↛ 867line 866 didn't jump to line 867, because the condition on line 866 was never true

+

867 raise Exception(f"Fileset already contains a sub-fileset named '{fileSet.Name}'.") 

+

868 

+

869 self._fileSets[fileSet.Name] = fileSet 

+

870 fileSet._parent = self 

+

871 

+

872 def AddFileSets(self, fileSets: Iterable["FileSet"]) -> None: 

+

873 """ 

+

874 Method to add a multiple sub-filesets to this fileset. 

+

875 

+

876 :arg fileSets: An iterable of filesets to add each to the fileset. 

+

877 """ 

+

878 for fileSet in fileSets: 

+

879 self.AddFileSet(fileSet) 

+

880 

+

881 @property 

+

882 def FileSetCount(self) -> int: 

+

883 """Returns number of file sets excl. sub-filesets.""" 

+

884 return len(self._fileSets) 

+

885 

+

886 @property 

+

887 def TotalFileSetCount(self) -> int: 

+

888 """Returns number of file sets incl. sub-filesets.""" 

+

889 fileSetCount = len(self._fileSets) 

+

890 for fileSet in self._fileSets.values(): 

+

891 fileSetCount += fileSet.TotalFileSetCount 

+

892 

+

893 return fileSetCount 

+

894 

+

895 def AddFile(self, file: File) -> None: 

+

896 """ 

+

897 Method to add a single file to this fileset. 

+

898 

+

899 :arg file: A file to add to this fileset. 

+

900 """ 

+

901 if not isinstance(file, File): 

+

902 raise TypeError("Parameter 'file' is not of type ProjectModel.File.") 

+

903 elif file._fileSet is not None: 

+

904 ex = ValueError(f"File '{file.Path!s}' is already part of fileset '{file.FileSet.Name}'.") 

+

905 ex.add_note(f"A file can't be assigned to another fileset.") 

+

906 raise ex 

+

907 elif file in self._set: 907 ↛ 908line 907 didn't jump to line 908, because the condition on line 907 was never true

+

908 ex = ValueError(f"File '{file.Path!s}' is already part of this fileset.") 

+

909 ex.add_note(f"A file can't be added twice to a fileset.") 

+

910 raise ex 

+

911 

+

912 self._files.append(file) 

+

913 self._set.add(file) 

+

914 file._fileSet = self 

+

915 

+

916 def AddFiles(self, files: Iterable[File]) -> None: 

+

917 """ 

+

918 Method to add a multiple files to this fileset. 

+

919 

+

920 :arg files: An iterable of files to add each to the fileset. 

+

921 """ 

+

922 for file in files: 

+

923 self.AddFile(file) 

+

924 

+

925 @property 

+

926 def FileCount(self) -> int: 

+

927 """Returns number of files excl. sub-filesets.""" 

+

928 return len(self._files) 

+

929 

+

930 @property 

+

931 def TotalFileCount(self) -> int: 

+

932 """Returns number of files incl. the files in sub-filesets.""" 

+

933 fileCount = len(self._files) 

+

934 for fileSet in self._fileSets.values(): 

+

935 fileCount += fileSet.FileCount 

+

936 

+

937 return fileCount 

+

938 

+

939 def Validate(self) -> None: 

+

940 """Validate this fileset.""" 

+

941 if self._name is None or self._name == "": 941 ↛ 942line 941 didn't jump to line 942, because the condition on line 941 was never true

+

942 raise Exception("Validation: FileSet has no name.") 

+

943 

+

944 if self._directory is None: 944 ↛ 945line 944 didn't jump to line 945, because the condition on line 944 was never true

+

945 raise Exception(f"Validation: FileSet '{self._name}' has no directory.") 

+

946 try: 

+

947 path = self.ResolvedPath 

+

948 except Exception as ex: 

+

949 raise Exception(f"Validation: FileSet '{self._name}' could not compute resolved path.") from ex 

+

950 if not path.exists(): 950 ↛ 951line 950 didn't jump to line 951, because the condition on line 950 was never true

+

951 raise Exception(f"Validation: FileSet '{self._name}'s directory '{path}' does not exist.") 

+

952 if not path.is_dir(): 952 ↛ 953line 952 didn't jump to line 953, because the condition on line 952 was never true

+

953 raise Exception(f"Validation: FileSet '{self._name}'s directory '{path}' is not a directory.") 

+

954 

+

955 if self._design is None: 955 ↛ 956line 955 didn't jump to line 956, because the condition on line 955 was never true

+

956 raise Exception(f"Validation: FileSet '{self._directory}' has no design.") 

+

957 if self._project is None: 957 ↛ 958line 957 didn't jump to line 958, because the condition on line 957 was never true

+

958 raise Exception(f"Validation: FileSet '{self._directory}' has no project.") 

+

959 

+

960 for fileSet in self._fileSets.values(): 960 ↛ 961line 960 didn't jump to line 961, because the loop on line 960 never started

+

961 fileSet.Validate() 

+

962 for file in self._files: 962 ↛ 963line 962 didn't jump to line 963, because the loop on line 962 never started

+

963 file.Validate() 

+

964 

+

965 def GetOrCreateVHDLLibrary(self, name) -> 'VHDLLibrary': 

+

966 if name in self._vhdlLibraries: 

+

967 return self._vhdlLibraries[name] 

+

968 elif name in self._design._vhdlLibraries: 

+

969 library = self._design._vhdlLibraries[name] 

+

970 self._vhdlLibraries[name] = library 

+

971 return library 

+

972 else: 

+

973 library = VHDLLibrary(name, design=self._design, vhdlVersion=self._vhdlVersion) 

+

974 self._vhdlLibraries[name] = library 

+

975 return library 

+

976 

+

977 @property 

+

978 def VHDLLibrary(self) -> 'VHDLLibrary': 

+

979 """Property setting or returning the VHDL library of this fileset.""" 

+

980 if self._vhdlLibrary is not None: 

+

981 return self._vhdlLibrary 

+

982 elif self._parent is not None: 982 ↛ 984line 982 didn't jump to line 984, because the condition on line 982 was never false

+

983 return self._parent.VHDLLibrary 

+

984 elif self._design is not None: 

+

985 return self._design.VHDLLibrary 

+

986 else: 

+

987 raise Exception("VHDLLibrary was neither set locally nor globally.") 

+

988 

+

989 @VHDLLibrary.setter 

+

990 def VHDLLibrary(self, value: 'VHDLLibrary') -> None: 

+

991 self._vhdlLibrary = value 

+

992 

+

993 @property 

+

994 def VHDLVersion(self) -> VHDLVersion: 

+

995 """Property setting or returning the VHDL version of this fileset.""" 

+

996 if self._vhdlVersion is not None: 

+

997 return self._vhdlVersion 

+

998 elif self._parent is not None: 

+

999 return self._parent.VHDLVersion 

+

1000 elif self._design is not None: 1000 ↛ 1003line 1000 didn't jump to line 1003, because the condition on line 1000 was never false

+

1001 return self._design.VHDLVersion 

+

1002 else: 

+

1003 raise Exception("VHDLVersion was neither set locally nor globally.") 

+

1004 

+

1005 @VHDLVersion.setter 

+

1006 def VHDLVersion(self, value: VHDLVersion) -> None: 

+

1007 self._vhdlVersion = value 

+

1008 

+

1009 @property 

+

1010 def VerilogVersion(self) -> SystemVerilogVersion: 

+

1011 """Property setting or returning the Verilog version of this fileset.""" 

+

1012 if self._verilogVersion is not None: 

+

1013 return self._verilogVersion 

+

1014 elif self._parent is not None: 

+

1015 return self._parent.VerilogVersion 

+

1016 elif self._design is not None: 1016 ↛ 1019line 1016 didn't jump to line 1019, because the condition on line 1016 was never false

+

1017 return self._design.VerilogVersion 

+

1018 else: 

+

1019 raise Exception("VerilogVersion was neither set locally nor globally.") 

+

1020 

+

1021 @VerilogVersion.setter 

+

1022 def VerilogVersion(self, value: SystemVerilogVersion) -> None: 

+

1023 self._verilogVersion = value 

+

1024 

+

1025 @property 

+

1026 def SVVersion(self) -> SystemVerilogVersion: 

+

1027 """Property setting or returning the SystemVerilog version of this fileset.""" 

+

1028 if self._svVersion is not None: 

+

1029 return self._svVersion 

+

1030 elif self._parent is not None: 

+

1031 return self._parent.SVVersion 

+

1032 elif self._design is not None: 1032 ↛ 1035line 1032 didn't jump to line 1035, because the condition on line 1032 was never false

+

1033 return self._design.SVVersion 

+

1034 else: 

+

1035 raise Exception("SVVersion was neither set locally nor globally.") 

+

1036 

+

1037 @SVVersion.setter 

+

1038 def SVVersion(self, value: SystemVerilogVersion) -> None: 

+

1039 self._svVersion = value 

+

1040 

+

1041 @property 

+

1042 def SRDLVersion(self) -> SystemRDLVersion: 

+

1043 if self._srdlVersion is not None: 

+

1044 return self._srdlVersion 

+

1045 elif self._parent is not None: 

+

1046 return self._parent.SRDLVersion 

+

1047 elif self._design is not None: 

+

1048 return self._design.SRDLVersion 

+

1049 else: 

+

1050 raise Exception("SRDLVersion was neither set locally nor globally.") 

+

1051 

+

1052 @SRDLVersion.setter 

+

1053 def SRDLVersion(self, value: SystemRDLVersion) -> None: 

+

1054 self._srdlVersion = value 

+

1055 

+

1056 def __len__(self) -> int: 

+

1057 """ 

+

1058 Returns number of attributes set on this fileset. 

+

1059 

+

1060 :returns: The number if attributes set on this fileset. 

+

1061 """ 

+

1062 return len(self._attributes) 

+

1063 

+

1064 def __getitem__(self, key: Type[Attribute]) -> Any: 

+

1065 """Index access for returning attributes on this fileset. 

+

1066 

+

1067 :param key: The attribute type. 

+

1068 :returns: The attribute's value. 

+

1069 :raises TypeError: When parameter 'key' is not a subclass of Attribute. 

+

1070 """ 

+

1071 if not issubclass(key, Attribute): 1071 ↛ 1072line 1071 didn't jump to line 1072, because the condition on line 1071 was never true

+

1072 raise TypeError("Parameter 'key' is not an 'Attribute'.") 

+

1073 

+

1074 try: 

+

1075 return self._attributes[key] 

+

1076 except KeyError: 

+

1077 return key.resolve(self, key) 

+

1078 

+

1079 def __setitem__(self, key: Type[Attribute], value: typing_Any) -> None: 

+

1080 """ 

+

1081 Index access for adding or setting attributes on this fileset. 

+

1082 

+

1083 :param key: The attribute type. 

+

1084 :param value: The attributes value. 

+

1085 :raises TypeError: When parameter 'key' is not a subclass of Attribute. 

+

1086 """ 

+

1087 if not issubclass(key, Attribute): 1087 ↛ 1088line 1087 didn't jump to line 1088, because the condition on line 1087 was never true

+

1088 raise TypeError("Parameter 'key' is not an 'Attribute'.") 

+

1089 

+

1090 self._attributes[key] = value 

+

1091 

+

1092 def __delitem__(self, key: Type[Attribute]) -> None: 

+

1093 """ 

+

1094 Index access for deleting attributes on this fileset. 

+

1095 

+

1096 :param key: The attribute type. 

+

1097 """ 

+

1098 if not issubclass(key, Attribute): 1098 ↛ 1099line 1098 didn't jump to line 1099, because the condition on line 1098 was never true

+

1099 raise TypeError("Parameter 'key' is not an 'Attribute'.") 

+

1100 

+

1101 del self._attributes[key] 

+

1102 

+

1103 def __str__(self) -> str: 

+

1104 """Returns the fileset's name.""" 

+

1105 return self._name 

+

1106 

+

1107 

+

1108@export 

+

1109class VHDLLibrary(metaclass=ExtendedType, slots=True): 

+

1110 """ 

+

1111 A :term:`VHDLLibrary` represents a group of VHDL source files compiled into the same VHDL library. 

+

1112 

+

1113 :arg name: The VHDL libraries' name. 

+

1114 :arg project: Project the VHDL library is associated with. 

+

1115 :arg design: Design the VHDL library is associated with. 

+

1116 :arg vhdlVersion: Default VHDL version for files in this VHDL library, if not specified for the file itself. 

+

1117 """ 

+

1118 

+

1119 _name: str 

+

1120 _project: Nullable['Project'] 

+

1121 _design: Nullable['Design'] 

+

1122 _files: List[File] 

+

1123 _vhdlVersion: VHDLVersion 

+

1124 

+

1125 _dependencyNode: Vertex 

+

1126 

+

1127 def __init__( 

+

1128 self, 

+

1129 name: str, 

+

1130 project: 'Project' = None, 

+

1131 design: 'Design' = None, 

+

1132 vhdlVersion: VHDLVersion = None 

+

1133 ): 

+

1134 self._name = name 

+

1135 if project is not None: 

+

1136 self._project = project 

+

1137 self._design = project._defaultDesign if design is None else design 

+

1138 self._dependencyNode = Vertex(value=self, graph=self._design._vhdlLibraryDependencyGraph) 

+

1139 

+

1140 if name in self._design._vhdlLibraries: 1140 ↛ 1141line 1140 didn't jump to line 1141, because the condition on line 1140 was never true

+

1141 raise Exception(f"Library '{name}' already in design '{self._design.Name}'.") 

+

1142 else: 

+

1143 self._design._vhdlLibraries[name] = self 

+

1144 

+

1145 elif design is not None: 

+

1146 self._project = design._project 

+

1147 self._design = design 

+

1148 self._dependencyNode = Vertex(value=self, graph=design._vhdlLibraryDependencyGraph) 

+

1149 

+

1150 if name in design._vhdlLibraries: 1150 ↛ 1151line 1150 didn't jump to line 1151, because the condition on line 1150 was never true

+

1151 raise Exception(f"Library '{name}' already in design '{design.Name}'.") 

+

1152 else: 

+

1153 design._vhdlLibraries[name] = self 

+

1154 

+

1155 else: 

+

1156 self._project = None 

+

1157 self._design = None 

+

1158 self._dependencyNode = None 

+

1159 

+

1160 self._files = [] 

+

1161 self._vhdlVersion = vhdlVersion 

+

1162 

+

1163 @property 

+

1164 def Name(self) -> str: 

+

1165 return self._name 

+

1166 

+

1167 @property 

+

1168 def Project(self) -> Nullable['Project']: 

+

1169 """Property setting or returning the project this VHDL library is used in.""" 

+

1170 return self._project 

+

1171 

+

1172 @Project.setter 

+

1173 def Project(self, value: 'Project') -> None: 

+

1174 if not isinstance(value, Project): 1174 ↛ 1175line 1174 didn't jump to line 1175, because the condition on line 1174 was never true

+

1175 raise TypeError("Parameter 'value' is not of type 'Project'.") 

+

1176 

+

1177 if value is None: 1177 ↛ 1179line 1177 didn't jump to line 1179, because the condition on line 1177 was never true

+

1178 # TODO: unlink VHDLLibrary from project 

+

1179 self._project = None 

+

1180 else: 

+

1181 self._project = value 

+

1182 if self._design is None: 1182 ↛ exitline 1182 didn't return from function 'Project', because the condition on line 1182 was never false

+

1183 self._design = value._defaultDesign 

+

1184 

+

1185 @property 

+

1186 def Design(self) -> Nullable['Design']: 

+

1187 """Property setting or returning the design this VHDL library is used in.""" 

+

1188 return self._design 

+

1189 

+

1190 @Design.setter 

+

1191 def Design(self, value: 'Design') -> None: 

+

1192 if not isinstance(value, Design): 

+

1193 raise TypeError("Parameter 'value' is not of type 'Design'.") 

+

1194 

+

1195 if value is None: 

+

1196 # TODO: unlink VHDLLibrary from design 

+

1197 self._design = None 

+

1198 else: 

+

1199 if self._design is None: 

+

1200 self._design = value 

+

1201 self._dependencyNode = Vertex(value=self, graph=self._design._vhdlLibraryDependencyGraph) 

+

1202 elif self._design is not value: 

+

1203 # TODO: move VHDLLibrary to other design 

+

1204 # TODO: create new vertex in dependency graph and remove vertex from old graph 

+

1205 self._design = value 

+

1206 else: 

+

1207 pass 

+

1208 

+

1209 if self._project is None: 

+

1210 self._project = value._project 

+

1211 elif self._project is not value._project: 

+

1212 raise Exception("The design's project is not identical to the already assigned project.") 

+

1213 

+

1214 @property 

+

1215 def Files(self) -> Generator[File, None, None]: 

+

1216 """Read-only property to return all files in this VHDL library.""" 

+

1217 for file in self._files: 

+

1218 yield file 

+

1219 

+

1220 @property 

+

1221 def VHDLVersion(self) -> VHDLVersion: 

+

1222 """Property setting or returning the VHDL version of this VHDL library.""" 

+

1223 if self._vhdlVersion is not None: 

+

1224 return self._vhdlVersion 

+

1225 elif self._design is not None: 1225 ↛ 1228line 1225 didn't jump to line 1228, because the condition on line 1225 was never false

+

1226 return self._design.VHDLVersion 

+

1227 else: 

+

1228 raise Exception("VHDLVersion is not set on VHDLLibrary nor parent object.") 

+

1229 

+

1230 @VHDLVersion.setter 

+

1231 def VHDLVersion(self, value: VHDLVersion) -> None: 

+

1232 self._vhdlVersion = value 

+

1233 

+

1234 def AddDependency(self, library: 'VHDLLibrary') -> None: 

+

1235 library.parent = self 

+

1236 

+

1237 def AddFile(self, vhdlFile: VHDLSourceFile) -> None: 

+

1238 if not isinstance(vhdlFile, VHDLSourceFile): 1238 ↛ 1239line 1238 didn't jump to line 1239, because the condition on line 1238 was never true

+

1239 raise TypeError(f"Parameter 'vhdlFile' is not a 'VHDLSourceFile'.") 

+

1240 

+

1241 self._files.append(vhdlFile) 

+

1242 

+

1243 def AddFiles(self, vhdlFiles: Iterable[VHDLSourceFile]) -> None: 

+

1244 for vhdlFile in vhdlFiles: 

+

1245 if not isinstance(vhdlFile, VHDLSourceFile): 

+

1246 raise TypeError(f"Item '{vhdlFile}' in parameter 'vhdlFiles' is not a 'VHDLSourceFile'.") 

+

1247 

+

1248 self._files.append(vhdlFile) 

+

1249 

+

1250 @property 

+

1251 def FileCount(self) -> int: 

+

1252 """Returns number of files.""" 

+

1253 return len(self._files) 

+

1254 

+

1255 def __len__(self) -> int: 

+

1256 """ 

+

1257 Returns number of attributes set on this VHDL library. 

+

1258 

+

1259 :returns: The number if attributes set on this VHDL library. 

+

1260 """ 

+

1261 return len(self._attributes) 

+

1262 

+

1263 def __getitem__(self, key: Type[Attribute]) -> Any: 

+

1264 """Index access for returning attributes on this VHDL library. 

+

1265 

+

1266 :param key: The attribute type. 

+

1267 :returns: The attribute's value. 

+

1268 :raises TypeError: When parameter 'key' is not a subclass of Attribute. 

+

1269 """ 

+

1270 if not issubclass(key, Attribute): 

+

1271 raise TypeError("Parameter 'key' is not an 'Attribute'.") 

+

1272 

+

1273 try: 

+

1274 return self._attributes[key] 

+

1275 except KeyError: 

+

1276 return key.resolve(self, key) 

+

1277 

+

1278 def __setitem__(self, key: Type[Attribute], value: typing_Any) -> None: 

+

1279 """ 

+

1280 Index access for adding or setting attributes on this VHDL library. 

+

1281 

+

1282 :param key: The attribute type. 

+

1283 :param value: The attributes value. 

+

1284 :raises TypeError: When parameter 'key' is not a subclass of Attribute. 

+

1285 """ 

+

1286 if not issubclass(key, Attribute): 

+

1287 raise TypeError("Parameter 'key' is not an 'Attribute'.") 

+

1288 

+

1289 self._attributes[key] = value 

+

1290 

+

1291 def __delitem__(self, key: Type[Attribute]) -> None: 

+

1292 """ 

+

1293 Index access for deleting attributes on this VHDL library. 

+

1294 

+

1295 :param key: The attribute type. 

+

1296 """ 

+

1297 if not issubclass(key, Attribute): 

+

1298 raise TypeError("Parameter 'key' is not an 'Attribute'.") 

+

1299 

+

1300 del self._attributes[key] 

+

1301 

+

1302 def __str__(self) -> str: 

+

1303 """Returns the VHDL library's name.""" 

+

1304 return self._name 

+

1305 

+

1306 

+

1307@export 

+

1308class Design(metaclass=ExtendedType, slots=True): 

+

1309 """ 

+

1310 A :term:`Design` represents a group of filesets and the source files therein. 

+

1311 

+

1312 Each design contains at least one fileset - the :term:`default fileset`. For 

+

1313 designs with VHDL source files, a independent `VHDLLibraries` overlay structure 

+

1314 exists. 

+

1315 

+

1316 :arg name: The design's name. 

+

1317 :arg topLevel: Name of the design's toplevel. 

+

1318 :arg directory: Path of this design (absolute or relative to the project). 

+

1319 :arg project: Project the design is associated with. 

+

1320 :arg vhdlVersion: Default VHDL version for files in this design, if not specified for the file itself. 

+

1321 :arg verilogVersion: Default Verilog version for files in this design, if not specified for the file itself. 

+

1322 :arg svVersion: Default SystemVerilog version for files in this design, if not specified for the file itself. 

+

1323 :arg srdlVersion: Default SystemRDL version for files in this fileset, if not specified for the file itself. 

+

1324 """ 

+

1325 

+

1326 _name: str 

+

1327 _topLevel: Nullable[str] 

+

1328 _project: Nullable['Project'] 

+

1329 _directory: pathlib_Path 

+

1330 _fileSets: Dict[str, FileSet] 

+

1331 _defaultFileSet: Nullable[FileSet] 

+

1332 _attributes: Dict[Type[Attribute], typing_Any] 

+

1333 

+

1334 _vhdlLibraries: Dict[str, VHDLLibrary] 

+

1335 _vhdlVersion: VHDLVersion 

+

1336 _verilogVersion: SystemVerilogVersion 

+

1337 _svVersion: SystemVerilogVersion 

+

1338 _srdlVersion: SystemRDLVersion 

+

1339 _externalVHDLLibraries: List 

+

1340 

+

1341 _vhdlLibraryDependencyGraph: Graph 

+

1342 _fileDependencyGraph: Graph 

+

1343 

+

1344 def __init__( 

+

1345 self, 

+

1346 name: str, 

+

1347 topLevel: str = None, 

+

1348 directory: pathlib_Path = pathlib_Path("."), 

+

1349 project: 'Project' = None, 

+

1350 vhdlVersion: VHDLVersion = None, 

+

1351 verilogVersion: SystemVerilogVersion = None, 

+

1352 svVersion: SystemVerilogVersion = None, 

+

1353 srdlVersion: SystemRDLVersion = None 

+

1354 ): 

+

1355 self._name = name 

+

1356 self._topLevel = topLevel 

+

1357 self._project = project 

+

1358 if project is not None: 

+

1359 project._designs[name] = self 

+

1360 self._directory = directory 

+

1361 self._fileSets = {} 

+

1362 self._defaultFileSet = FileSet("default", project=project, design=self) 

+

1363 self._attributes = {} 

+

1364 self._vhdlLibraries = {} 

+

1365 self._vhdlVersion = vhdlVersion 

+

1366 self._verilogVersion = verilogVersion 

+

1367 self._svVersion = svVersion 

+

1368 self._srdlVersion = srdlVersion 

+

1369 self._externalVHDLLibraries = [] 

+

1370 

+

1371 self._vhdlLibraryDependencyGraph = Graph() 

+

1372 self._fileDependencyGraph = Graph() 

+

1373 

+

1374 @property 

+

1375 def Name(self) -> str: 

+

1376 """Property setting or returning the design's name.""" 

+

1377 return self._name 

+

1378 

+

1379 @Name.setter 

+

1380 def Name(self, value: str) -> None: 

+

1381 self._name = value 

+

1382 

+

1383 @property 

+

1384 def TopLevel(self) -> str: 

+

1385 """Property setting or returning the fileset's toplevel.""" 

+

1386 return self._topLevel 

+

1387 

+

1388 @TopLevel.setter 

+

1389 def TopLevel(self, value: str) -> None: 

+

1390 self._topLevel = value 

+

1391 

+

1392 @property 

+

1393 def Project(self) -> Nullable['Project']: 

+

1394 """Property setting or returning the project this design is used in.""" 

+

1395 return self._project 

+

1396 

+

1397 @Project.setter 

+

1398 def Project(self, value: 'Project') -> None: 

+

1399 self._project = value 

+

1400 

+

1401 @property 

+

1402 def Directory(self) -> pathlib_Path: 

+

1403 """Property setting or returning the directory this design is located in.""" 

+

1404 return self._directory 

+

1405 

+

1406 @Directory.setter 

+

1407 def Directory(self, value: pathlib_Path) -> None: 

+

1408 self._directory = value 

+

1409 

+

1410 @property 

+

1411 def ResolvedPath(self) -> pathlib_Path: 

+

1412 """Read-only property returning the resolved path of this fileset.""" 

+

1413 if self._directory.is_absolute(): 1413 ↛ 1414line 1413 didn't jump to line 1414, because the condition on line 1413 was never true

+

1414 return self._directory.resolve() 

+

1415 elif self._project is not None: 1415 ↛ 1425line 1415 didn't jump to line 1425, because the condition on line 1415 was never false

+

1416 path = (self._project.ResolvedPath / self._directory).resolve() 

+

1417 

+

1418 if path.is_absolute(): 1418 ↛ 1422line 1418 didn't jump to line 1422, because the condition on line 1418 was never false

+

1419 return path 

+

1420 else: 

+

1421 # WORKAROUND: https://stackoverflow.com/questions/67452690/pathlib-path-relative-to-vs-os-path-relpath 

+

1422 return pathlib_Path(path_relpath(path, pathlib_Path.cwd())) 

+

1423 else: 

+

1424 # TODO: message and exception type 

+

1425 raise Exception("") 

+

1426 

+

1427 @property 

+

1428 def DefaultFileSet(self) -> FileSet: 

+

1429 """Property setting or returning the default fileset of this design.""" 

+

1430 return self._defaultFileSet 

+

1431 

+

1432 @DefaultFileSet.setter 

+

1433 def DefaultFileSet(self, value: Union[str, FileSet]) -> None: 

+

1434 if isinstance(value, str): 

+

1435 if value not in self._fileSets.keys(): 

+

1436 raise Exception(f"Fileset '{value}' is not in this design.") 

+

1437 

+

1438 self._defaultFileSet = self._fileSets[value] 

+

1439 elif isinstance(value, FileSet): 

+

1440 if value not in self.FileSets: 

+

1441 raise Exception(f"Fileset '{value}' is not associated to this design.") 

+

1442 

+

1443 self._defaultFileSet = value 

+

1444 else: 

+

1445 raise ValueError("Unsupported parameter type for 'value'.") 

+

1446 

+

1447 # TODO: return generator with another method 

+

1448 @property 

+

1449 def FileSets(self) -> Dict[str, FileSet]: 

+

1450 """Read-only property returning the dictionary of filesets.""" 

+

1451 return self._fileSets 

+

1452 

+

1453 def Files(self, fileType: FileType = FileTypes.Any, fileSet: Union[str, FileSet] = None) -> Generator[File, None, None]: 

+

1454 """ 

+

1455 Method returning the files of this design. 

+

1456 

+

1457 :arg fileType: A filter for file types. Default: ``Any``. 

+

1458 :arg fileSet: Specifies if all files from all filesets (``fileSet=None``) are files from a single fileset are returned. 

+

1459 """ 

+

1460 if fileSet is None: 

+

1461 for fileSet in self._fileSets.values(): 

+

1462 for file in fileSet.Files(fileType): 

+

1463 yield file 

+

1464 else: 

+

1465 if isinstance(fileSet, str): 1465 ↛ 1470line 1465 didn't jump to line 1470, because the condition on line 1465 was never false

+

1466 try: 

+

1467 fileSet = self._fileSets[fileSet] 

+

1468 except KeyError as ex: 

+

1469 raise Exception(f"Fileset {fileSet.Name} not bound to design {self.Name}.") from ex 

+

1470 elif not isinstance(fileSet, FileSet): 

+

1471 raise TypeError("Parameter 'fileSet' is not of type 'str' or 'FileSet' nor value 'None'.") 

+

1472 

+

1473 for file in fileSet.Files(fileType): 

+

1474 yield file 

+

1475 

+

1476 def Validate(self) -> None: 

+

1477 """Validate this design.""" 

+

1478 if self._name is None or self._name == "": 1478 ↛ 1479line 1478 didn't jump to line 1479, because the condition on line 1478 was never true

+

1479 raise Exception("Validation: Design has no name.") 

+

1480 

+

1481 if self._directory is None: 1481 ↛ 1482line 1481 didn't jump to line 1482, because the condition on line 1481 was never true

+

1482 raise Exception(f"Validation: Design '{self._name}' has no directory.") 

+

1483 try: 

+

1484 path = self.ResolvedPath 

+

1485 except Exception as ex: 

+

1486 raise Exception(f"Validation: Design '{self._name}' could not compute resolved path.") from ex 

+

1487 if not path.exists(): 1487 ↛ 1488line 1487 didn't jump to line 1488, because the condition on line 1487 was never true

+

1488 raise Exception(f"Validation: Design '{self._name}'s directory '{path}' does not exist.") 

+

1489 if not path.is_dir(): 1489 ↛ 1490line 1489 didn't jump to line 1490, because the condition on line 1489 was never true

+

1490 raise Exception(f"Validation: Design '{self._name}'s directory '{path}' is not a directory.") 

+

1491 

+

1492 if len(self._fileSets) == 0: 1492 ↛ 1493line 1492 didn't jump to line 1493, because the condition on line 1492 was never true

+

1493 raise Exception(f"Validation: Design '{self._name}' has no fileset.") 

+

1494 try: 

+

1495 if self._defaultFileSet is not self._fileSets[self._defaultFileSet.Name]: 1495 ↛ 1496line 1495 didn't jump to line 1496, because the condition on line 1495 was never true

+

1496 raise Exception(f"Validation: Design '{self._name}'s default fileset is the same as listed in filesets.") 

+

1497 except KeyError as ex: 

+

1498 raise Exception(f"Validation: Design '{self._name}'s default fileset is not in list of filesets.") from ex 

+

1499 if self._project is None: 1499 ↛ 1500line 1499 didn't jump to line 1500, because the condition on line 1499 was never true

+

1500 raise Exception(f"Validation: Design '{self._path}' has no project.") 

+

1501 

+

1502 for fileSet in self._fileSets.values(): 

+

1503 fileSet.Validate() 

+

1504 

+

1505 @property 

+

1506 def VHDLLibraries(self) -> Dict[str, VHDLLibrary]: 

+

1507 return self._vhdlLibraries 

+

1508 

+

1509 @property 

+

1510 def VHDLVersion(self) -> VHDLVersion: 

+

1511 if self._vhdlVersion is not None: 

+

1512 return self._vhdlVersion 

+

1513 elif self._project is not None: 1513 ↛ 1516line 1513 didn't jump to line 1516, because the condition on line 1513 was never false

+

1514 return self._project.VHDLVersion 

+

1515 else: 

+

1516 raise Exception("VHDLVersion was neither set locally nor globally.") 

+

1517 

+

1518 @VHDLVersion.setter 

+

1519 def VHDLVersion(self, value: VHDLVersion) -> None: 

+

1520 self._vhdlVersion = value 

+

1521 

+

1522 @property 

+

1523 def VerilogVersion(self) -> SystemVerilogVersion: 

+

1524 if self._verilogVersion is not None: 

+

1525 return self._verilogVersion 

+

1526 elif self._project is not None: 1526 ↛ 1529line 1526 didn't jump to line 1529, because the condition on line 1526 was never false

+

1527 return self._project.VerilogVersion 

+

1528 else: 

+

1529 raise Exception("VerilogVersion was neither set locally nor globally.") 

+

1530 

+

1531 @VerilogVersion.setter 

+

1532 def VerilogVersion(self, value: SystemVerilogVersion) -> None: 

+

1533 self._verilogVersion = value 

+

1534 

+

1535 @property 

+

1536 def SVVersion(self) -> SystemVerilogVersion: 

+

1537 if self._svVersion is not None: 

+

1538 return self._svVersion 

+

1539 elif self._project is not None: 1539 ↛ 1542line 1539 didn't jump to line 1542, because the condition on line 1539 was never false

+

1540 return self._project.SVVersion 

+

1541 else: 

+

1542 raise Exception("SVVersion was neither set locally nor globally.") 

+

1543 

+

1544 @SVVersion.setter 

+

1545 def SVVersion(self, value: SystemVerilogVersion) -> None: 

+

1546 self._svVersion = value 

+

1547 

+

1548 @property 

+

1549 def SRDLVersion(self) -> SystemRDLVersion: 

+

1550 if self._srdlVersion is not None: 

+

1551 return self._srdlVersion 

+

1552 elif self._project is not None: 

+

1553 return self._project.SRDLVersion 

+

1554 else: 

+

1555 raise Exception("SRDLVersion was neither set locally nor globally.") 

+

1556 

+

1557 @SRDLVersion.setter 

+

1558 def SRDLVersion(self, value: SystemRDLVersion) -> None: 

+

1559 self._srdlVersion = value 

+

1560 

+

1561 @property 

+

1562 def ExternalVHDLLibraries(self) -> List: 

+

1563 return self._externalVHDLLibraries 

+

1564 

+

1565 def AddFileSet(self, fileSet: FileSet) -> None: 

+

1566 if not isinstance(fileSet, FileSet): 

+

1567 raise ValueError("Parameter 'fileSet' is not of type ProjectModel.FileSet.") 

+

1568 elif fileSet in self._fileSets: 

+

1569 raise Exception("Design already contains this fileset.") 

+

1570 elif fileSet.Name in self._fileSets.keys(): 

+

1571 raise Exception(f"Design already contains a fileset named '{fileSet.Name}'.") 

+

1572 

+

1573 self._fileSets[fileSet.Name] = fileSet 

+

1574 fileSet.Design = self 

+

1575 fileSet._parent = self 

+

1576 

+

1577 def AddFileSets(self, fileSets: Iterable[FileSet]) -> None: 

+

1578 for fileSet in fileSets: 

+

1579 self.AddFileSet(fileSet) 

+

1580 

+

1581 @property 

+

1582 def FileSetCount(self) -> int: 

+

1583 """Returns number of file sets excl. sub-filesets.""" 

+

1584 return len(self._fileSets) 

+

1585 

+

1586 @property 

+

1587 def TotalFileSetCount(self) -> int: 

+

1588 """Returns number of file sets incl. sub-filesets.""" 

+

1589 fileSetCount = len(self._fileSets) 

+

1590 for fileSet in self._fileSets.values(): 

+

1591 fileSetCount += fileSet.TotalFileSetCount 

+

1592 

+

1593 return fileSetCount 

+

1594 

+

1595 def AddFile(self, file: File) -> None: 

+

1596 if file.FileSet is None: 1596 ↛ 1599line 1596 didn't jump to line 1599, because the condition on line 1596 was never false

+

1597 self._defaultFileSet.AddFile(file) 

+

1598 else: 

+

1599 raise ValueError(f"File '{file.Path!s}' is already part of fileset '{file.FileSet.Name}' and can't be assigned via Design to a default fileset.") 

+

1600 

+

1601 def AddFiles(self, files: Iterable[File]) -> None: 

+

1602 for file in files: 

+

1603 self.AddFile(file) 

+

1604 

+

1605 def AddVHDLLibrary(self, vhdlLibrary: VHDLLibrary) -> None: 

+

1606 if vhdlLibrary.Name in self._vhdlLibraries: 

+

1607 if self._vhdlLibraries[vhdlLibrary.Name] is vhdlLibrary: 

+

1608 raise Exception(f"The VHDLLibrary '{vhdlLibrary.Name}' was already added to the design.") 

+

1609 else: 

+

1610 raise Exception(f"A VHDLLibrary with same name ('{vhdlLibrary.Name}') already exists for this design.") 

+

1611 

+

1612 

+

1613 def __len__(self) -> int: 

+

1614 """ 

+

1615 Returns number of attributes set on this design. 

+

1616 

+

1617 :returns: The number if attributes set on this design. 

+

1618 """ 

+

1619 return len(self._attributes) 

+

1620 

+

1621 def __getitem__(self, key: Type[Attribute]) -> Any: 

+

1622 """Index access for returning attributes on this design. 

+

1623 

+

1624 :param key: The attribute type. 

+

1625 :returns: The attribute's value. 

+

1626 :raises TypeError: When parameter 'key' is not a subclass of Attribute. 

+

1627 """ 

+

1628 if not issubclass(key, Attribute): 

+

1629 raise TypeError("Parameter 'key' is not an 'Attribute'.") 

+

1630 

+

1631 try: 

+

1632 return self._attributes[key] 

+

1633 except KeyError: 

+

1634 return key.resolve(self, key) 

+

1635 

+

1636 def __setitem__(self, key: Type[Attribute], value: typing_Any) -> None: 

+

1637 """ 

+

1638 Index access for adding or setting attributes on this design. 

+

1639 

+

1640 :param key: The attribute type. 

+

1641 :param value: The attributes value. 

+

1642 :raises TypeError: When parameter 'key' is not a subclass of Attribute. 

+

1643 """ 

+

1644 if not issubclass(key, Attribute): 

+

1645 raise TypeError("Parameter 'key' is not an 'Attribute'.") 

+

1646 

+

1647 self._attributes[key] = value 

+

1648 

+

1649 def __delitem__(self, key: Type[Attribute]) -> None: 

+

1650 """ 

+

1651 Index access for deleting attributes on this design. 

+

1652 

+

1653 :param key: The attribute type. 

+

1654 """ 

+

1655 if not issubclass(key, Attribute): 

+

1656 raise TypeError("Parameter 'key' is not an 'Attribute'.") 

+

1657 

+

1658 del self._attributes[key] 

+

1659 

+

1660 def __str__(self) -> str: 

+

1661 return self._name 

+

1662 

+

1663 

+

1664@export 

+

1665class Project(metaclass=ExtendedType, slots=True): 

+

1666 """ 

+

1667 A :term:`Project` represents a group of designs and the source files therein. 

+

1668 

+

1669 :arg name: The project's name. 

+

1670 :arg rootDirectory: Base-path to the project. 

+

1671 :arg vhdlVersion: Default VHDL version for files in this project, if not specified for the file itself. 

+

1672 :arg verilogVersion: Default Verilog version for files in this project, if not specified for the file itself. 

+

1673 :arg svVersion: Default SystemVerilog version for files in this project, if not specified for the file itself. 

+

1674 """ 

+

1675 

+

1676 _name: str 

+

1677 _rootDirectory: pathlib_Path 

+

1678 _designs: Dict[str, Design] 

+

1679 _defaultDesign: Design 

+

1680 _attributes: Dict[Type[Attribute], typing_Any] 

+

1681 

+

1682 _vhdlVersion: VHDLVersion 

+

1683 _verilogVersion: SystemVerilogVersion 

+

1684 _svVersion: SystemVerilogVersion 

+

1685 _srdlVersion: SystemRDLVersion 

+

1686 

+

1687 def __init__( 

+

1688 self, 

+

1689 name: str, 

+

1690 rootDirectory: pathlib_Path = pathlib_Path("."), 

+

1691 vhdlVersion: VHDLVersion = None, 

+

1692 verilogVersion: SystemVerilogVersion = None, 

+

1693 svVersion: SystemVerilogVersion = None 

+

1694 ): 

+

1695 self._name = name 

+

1696 self._rootDirectory = rootDirectory 

+

1697 self._designs = {} 

+

1698 self._defaultDesign = Design("default", project=self) 

+

1699 self._attributes = {} 

+

1700 self._vhdlVersion = vhdlVersion 

+

1701 self._verilogVersion = verilogVersion 

+

1702 self._svVersion = svVersion 

+

1703 

+

1704 @property 

+

1705 def Name(self) -> str: 

+

1706 """Property setting or returning the project's name.""" 

+

1707 return self._name 

+

1708 

+

1709 @property 

+

1710 def RootDirectory(self) -> pathlib_Path: 

+

1711 """Property setting or returning the root directory this project is located in.""" 

+

1712 return self._rootDirectory 

+

1713 

+

1714 @RootDirectory.setter 

+

1715 def RootDirectory(self, value: pathlib_Path) -> None: 

+

1716 self._rootDirectory = value 

+

1717 

+

1718 @property 

+

1719 def ResolvedPath(self) -> pathlib_Path: 

+

1720 """Read-only property returning the resolved path of this fileset.""" 

+

1721 path = self._rootDirectory.resolve() 

+

1722 if self._rootDirectory.is_absolute(): 

+

1723 return path 

+

1724 else: 

+

1725 # WORKAROUND: https://stackoverflow.com/questions/67452690/pathlib-path-relative-to-vs-os-path-relpath 

+

1726 return pathlib_Path(path_relpath(path, pathlib_Path.cwd())) 

+

1727 

+

1728 # TODO: return generator with another method 

+

1729 @property 

+

1730 def Designs(self) -> Dict[str, Design]: 

+

1731 return self._designs 

+

1732 

+

1733 @property 

+

1734 def DefaultDesign(self) -> Design: 

+

1735 return self._defaultDesign 

+

1736 

+

1737 def Validate(self) -> None: 

+

1738 """Validate this project.""" 

+

1739 if self._name is None or self._name == "": 1739 ↛ 1740line 1739 didn't jump to line 1740, because the condition on line 1739 was never true

+

1740 raise Exception("Validation: Project has no name.") 

+

1741 

+

1742 if self._rootDirectory is None: 1742 ↛ 1743line 1742 didn't jump to line 1743, because the condition on line 1742 was never true

+

1743 raise Exception(f"Validation: Project '{self._name}' has no root directory.") 

+

1744 try: 

+

1745 path = self.ResolvedPath 

+

1746 except Exception as ex: 

+

1747 raise Exception(f"Validation: Project '{self._name}' could not compute resolved path.") from ex 

+

1748 if not path.exists(): 1748 ↛ 1749line 1748 didn't jump to line 1749, because the condition on line 1748 was never true

+

1749 raise Exception(f"Validation: Project '{self._name}'s directory '{path}' does not exist.") 

+

1750 if not path.is_dir(): 1750 ↛ 1751line 1750 didn't jump to line 1751, because the condition on line 1750 was never true

+

1751 raise Exception(f"Validation: Project '{self._name}'s directory '{path}' is not a directory.") 

+

1752 

+

1753 if len(self._designs) == 0: 1753 ↛ 1754line 1753 didn't jump to line 1754, because the condition on line 1753 was never true

+

1754 raise Exception(f"Validation: Project '{self._name}' has no design.") 

+

1755 try: 

+

1756 if self._defaultDesign is not self._designs[self._defaultDesign.Name]: 1756 ↛ 1757line 1756 didn't jump to line 1757, because the condition on line 1756 was never true

+

1757 raise Exception(f"Validation: Project '{self._name}'s default design is the same as listed in designs.") 

+

1758 except KeyError as ex: 

+

1759 raise Exception(f"Validation: Project '{self._name}'s default design is not in list of designs.") from ex 

+

1760 

+

1761 for design in self._designs.values(): 

+

1762 design.Validate() 

+

1763 

+

1764 @property 

+

1765 def DesignCount(self) -> int: 

+

1766 """Returns number of designs.""" 

+

1767 return len(self._designs) 

+

1768 

+

1769 @property 

+

1770 def VHDLVersion(self) -> VHDLVersion: 

+

1771 # TODO: check for None and return exception 

+

1772 return self._vhdlVersion 

+

1773 

+

1774 @VHDLVersion.setter 

+

1775 def VHDLVersion(self, value: VHDLVersion) -> None: 

+

1776 self._vhdlVersion = value 

+

1777 

+

1778 @property 

+

1779 def VerilogVersion(self) -> SystemVerilogVersion: 

+

1780 # TODO: check for None and return exception 

+

1781 return self._verilogVersion 

+

1782 

+

1783 @VerilogVersion.setter 

+

1784 def VerilogVersion(self, value: SystemVerilogVersion) -> None: 

+

1785 self._verilogVersion = value 

+

1786 

+

1787 @property 

+

1788 def SVVersion(self) -> SystemVerilogVersion: 

+

1789 # TODO: check for None and return exception 

+

1790 return self._svVersion 

+

1791 

+

1792 @SVVersion.setter 

+

1793 def SVVersion(self, value: SystemVerilogVersion) -> None: 

+

1794 self._svVersion = value 

+

1795 

+

1796 @property 

+

1797 def SRDLVersion(self) -> SystemRDLVersion: 

+

1798 # TODO: check for None and return exception 

+

1799 return self._srdlVersion 

+

1800 

+

1801 @SRDLVersion.setter 

+

1802 def SRDLVersion(self, value: SystemRDLVersion) -> None: 

+

1803 self._srdlVersion = value 

+

1804 

+

1805 def __len__(self) -> int: 

+

1806 """ 

+

1807 Returns number of attributes set on this project. 

+

1808 

+

1809 :returns: The number if attributes set on this project. 

+

1810 """ 

+

1811 return len(self._attributes) 

+

1812 

+

1813 def __getitem__(self, key: Type[Attribute]) -> Any: 

+

1814 """Index access for returning attributes on this project. 

+

1815 

+

1816 :param key: The attribute type. 

+

1817 :returns: The attribute's value. 

+

1818 :raises TypeError: When parameter 'key' is not a subclass of Attribute. 

+

1819 """ 

+

1820 if not issubclass(key, Attribute): 

+

1821 raise TypeError("Parameter 'key' is not an 'Attribute'.") 

+

1822 

+

1823 try: 

+

1824 return self._attributes[key] 

+

1825 except KeyError: 

+

1826 return key.resolve(self, key) 

+

1827 

+

1828 def __setitem__(self, key: Type[Attribute], value: typing_Any) -> None: 

+

1829 """ 

+

1830 Index access for adding or setting attributes on this project. 

+

1831 

+

1832 :param key: The attribute type. 

+

1833 :param value: The attributes value. 

+

1834 :raises TypeError: When parameter 'key' is not a subclass of Attribute. 

+

1835 """ 

+

1836 if not issubclass(key, Attribute): 

+

1837 raise TypeError("Parameter 'key' is not an 'Attribute'.") 

+

1838 

+

1839 self._attributes[key] = value 

+

1840 

+

1841 def __delitem__(self, key: Type[Attribute]) -> None: 

+

1842 """ 

+

1843 Index access for deleting attributes on this project. 

+

1844 

+

1845 :param key: The attribute type. 

+

1846 """ 

+

1847 if not issubclass(key, Attribute): 

+

1848 raise TypeError("Parameter 'key' is not an 'Attribute'.") 

+

1849 

+

1850 del self._attributes[key] 

+

1851 

+

1852 def __str__(self) -> str: 

+

1853 return self._name 

+
+ + + diff --git a/coverage/d_f31a6c1cb708999d_Vivado_py.html b/coverage/d_f31a6c1cb708999d_Vivado_py.html new file mode 100644 index 00000000..ab708519 --- /dev/null +++ b/coverage/d_f31a6c1cb708999d_Vivado_py.html @@ -0,0 +1,304 @@ + + + + + Coverage for pyEDAA/ProjectModel/Xilinx/Vivado.py: 88% + + + + + +
+
+

+ Coverage for pyEDAA/ProjectModel/Xilinx/Vivado.py: + 88% +

+ +

+ 121 statements   + + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.3.0, + created at 2023-08-24 21:52 +0000 +

+ +
+
+
+

1# ==================================================================================================================== # 

+

2# _____ ____ _ _ ____ _ _ __ __ _ _ # 

+

3# _ __ _ _| ____| _ \ / \ / \ | _ \ _ __ ___ (_) ___ ___| |_| \/ | ___ __| | ___| | # 

+

4# | '_ \| | | | _| | | | |/ _ \ / _ \ | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ | # 

+

5# | |_) | |_| | |___| |_| / ___ \ / ___ \ _| __/| | | (_) | | __/ (__| |_| | | | (_) | (_| | __/ | # 

+

6# | .__/ \__, |_____|____/_/ \_\/_/ \_(_)_| |_| \___// |\___|\___|\__|_| |_|\___/ \__,_|\___|_| # 

+

7# |_| |___/ |__/ # 

+

8# ==================================================================================================================== # 

+

9# Authors: # 

+

10# Patrick Lehmann # 

+

11# # 

+

12# License: # 

+

13# ==================================================================================================================== # 

+

14# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany # 

+

15# # 

+

16# Licensed under the Apache License, Version 2.0 (the "License"); # 

+

17# you may not use this file except in compliance with the License. # 

+

18# You may obtain a copy of the License at # 

+

19# # 

+

20# http://www.apache.org/licenses/LICENSE-2.0 # 

+

21# # 

+

22# Unless required by applicable law or agreed to in writing, software # 

+

23# distributed under the License is distributed on an "AS IS" BASIS, # 

+

24# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # 

+

25# See the License for the specific language governing permissions and # 

+

26# limitations under the License. # 

+

27# # 

+

28# SPDX-License-Identifier: Apache-2.0 # 

+

29# ==================================================================================================================== # 

+

30# 

+

31"""Specific file types and attributes for Xilinx Vivado.""" 

+

32from pathlib import Path 

+

33from typing import Iterable 

+

34 

+

35from xml.dom import minidom, Node 

+

36 

+

37from pyTooling.MetaClasses import ExtendedType 

+

38from pyVHDLModel import VHDLVersion 

+

39from pyTooling.Decorators import export 

+

40 

+

41from pyEDAA.ProjectModel import ProjectFile, XMLFile, XMLContent, SDCContent, Project, FileSet, Attribute, Design 

+

42from pyEDAA.ProjectModel import File as Model_File 

+

43from pyEDAA.ProjectModel import ConstraintFile as Model_ConstraintFile 

+

44from pyEDAA.ProjectModel import VerilogSourceFile as Model_VerilogSourceFile 

+

45from pyEDAA.ProjectModel import VHDLSourceFile as Model_VHDLSourceFile 

+

46 

+

47 

+

48@export 

+

49class UsedInAttribute(Attribute): 

+

50 KEY = "UsedIn" 

+

51 VALUE_TYPE = Iterable[str] 

+

52 

+

53 

+

54@export 

+

55class File(Model_File): 

+

56 pass 

+

57 

+

58 

+

59class VivadoFileMixIn(metaclass=ExtendedType, mixin=True): 

+

60 def _registerAttributes(self): 

+

61 self._attributes[UsedInAttribute] = [] 

+

62 

+

63 

+

64@export 

+

65class ConstraintFile(Model_ConstraintFile, VivadoFileMixIn): 

+

66 def _registerAttributes(self): 

+

67 super()._registerAttributes() 

+

68 VivadoFileMixIn._registerAttributes(self) 

+

69 

+

70 

+

71@export 

+

72class VerilogSourceFile(Model_VerilogSourceFile): 

+

73 def _registerAttributes(self): 

+

74 super()._registerAttributes() 

+

75 VivadoFileMixIn._registerAttributes(self) 

+

76 

+

77 

+

78@export 

+

79class VHDLSourceFile(Model_VHDLSourceFile): 

+

80 def _registerAttributes(self): 

+

81 super()._registerAttributes() 

+

82 VivadoFileMixIn._registerAttributes(self) 

+

83 

+

84 

+

85@export 

+

86class VivadoProjectFile(ProjectFile, XMLContent): 

+

87 """A Vivado project file (``*.xpr``).""" 

+

88 

+

89 _xprProject: Project 

+

90 

+

91 def __init__( 

+

92 self, 

+

93 path: Path, 

+

94 project: Project = None, 

+

95 design: Design = None, 

+

96 fileSet: FileSet = None 

+

97 ): 

+

98 super().__init__(path, project, design, fileSet) 

+

99 

+

100 self._xprProject = None 

+

101 

+

102 @property 

+

103 def ProjectModel(self) -> Project: 

+

104 return self._xprProject 

+

105 

+

106 def Parse(self): 

+

107 if not self._path.exists(): 107 ↛ 108line 107 didn't jump to line 108, because the condition on line 107 was never true

+

108 raise Exception(f"Vivado project file '{self._path!s}' not found.") from FileNotFoundError(f"File '{self._path!s}' not found.") 

+

109 

+

110 try: 

+

111 root = minidom.parse(str(self._path)).documentElement 

+

112 except Exception as ex: 

+

113 raise Exception(f"Couldn't open '{self._path!s}'.") from ex 

+

114 

+

115 self._xprProject = Project(self._path.stem, rootDirectory=self._path.parent) 

+

116 self._ParseRootElement(root) 

+

117 

+

118 def _ParseRootElement(self, root): 

+

119 for rootNode in root.childNodes: 119 ↛ exitline 119 didn't return from function '_ParseRootElement', because the loop on line 119 didn't complete

+

120 if rootNode.nodeName == "FileSets": 

+

121 self._ParseFileSets(rootNode) 

+

122 break 

+

123 

+

124 def _ParseFileSets(self, filesetsNode): 

+

125 for fileSetsNode in filesetsNode.childNodes: 

+

126 if fileSetsNode.nodeType == Node.ELEMENT_NODE and fileSetsNode.tagName == "FileSet": 

+

127 self._ParseFileSet(fileSetsNode) 

+

128 

+

129 def _ParseFileSet(self, filesetNode): 

+

130 filesetName = filesetNode.getAttribute("Name") 

+

131 fileset = FileSet(filesetName, design=self._xprProject.DefaultDesign) 

+

132 

+

133 for fileNode in filesetNode.childNodes: 

+

134 if fileNode.nodeType == Node.ELEMENT_NODE: 

+

135 if fileNode.tagName == "File": 

+

136 self._ParseFile(fileNode, fileset) 

+

137 elif fileNode.nodeType == Node.ELEMENT_NODE and fileNode.tagName == "Config": 

+

138 self._ParseFileSetConfig(fileNode, fileset) 

+

139 

+

140 def _ParseFile(self, fileNode, fileset): 

+

141 croppedPath = fileNode.getAttribute("Path").replace("$PPRDIR/", "") 

+

142 filePath = Path(croppedPath) 

+

143 if filePath.suffix in (".vhd", ".vhdl"): 

+

144 self._ParseVHDLFile(fileNode, filePath, fileset) 

+

145 elif filePath.suffix == ".xdc": 145 ↛ 147line 145 didn't jump to line 147, because the condition on line 145 was never false

+

146 self._ParseXDCFile(fileNode, filePath, fileset) 

+

147 elif filePath.suffix == ".v": 

+

148 self._ParseVerilogFile(fileNode, filePath, fileset) 

+

149 elif filePath.suffix == ".xci": 

+

150 self._ParseXCIFile(fileNode, filePath, fileset) 

+

151 else: 

+

152 self._ParseDefaultFile(fileNode, filePath, fileset) 

+

153 

+

154 def _ParseVHDLFile(self, fileNode, path, fileset): 

+

155 vhdlFile = VHDLSourceFile(path) 

+

156 fileset.AddFile(vhdlFile) 

+

157 usedInAttr = vhdlFile[UsedInAttribute] 

+

158 

+

159 for childNode in fileNode.childNodes: 

+

160 if childNode.nodeType == Node.ELEMENT_NODE and childNode.tagName == "FileInfo": 

+

161 if childNode.getAttribute("SFType") == "VHDL2008": 

+

162 vhdlFile.VHDLVersion = VHDLVersion.VHDL2008 

+

163 else: 

+

164 vhdlFile.VHDLVersion = VHDLVersion.VHDL93 

+

165 

+

166 for fileAttribute in childNode.childNodes: 

+

167 if fileAttribute.nodeType == Node.ELEMENT_NODE and fileAttribute.tagName == "Attr": 

+

168 if fileAttribute.getAttribute("Name") == "Library": 

+

169 libraryName = fileAttribute.getAttribute("Val") 

+

170 vhdlFile.VHDLLibrary = fileset.GetOrCreateVHDLLibrary(libraryName) 

+

171 elif fileAttribute.getAttribute("Val") == "UsedIn": 171 ↛ 172line 171 didn't jump to line 172, because the condition on line 171 was never true

+

172 usedInAttr.append(fileAttribute.getAttribute("Val")) 

+

173 

+

174 def _ParseDefaultFile(self, _, path, fileset): 

+

175 File(path, fileSet=fileset) 

+

176 

+

177 def _ParseXDCFile(self, _, path, fileset): 

+

178 XDCConstraintFile(path, fileSet=fileset) 

+

179 

+

180 def _ParseVerilogFile(self, _, path, fileset): 

+

181 VerilogSourceFile(path, fileSet=fileset) 

+

182 

+

183 def _ParseXCIFile(self, _, path, fileset): 

+

184 IPCoreInstantiationFile(path, fileSet=fileset) 

+

185 

+

186 def _ParseFileSetConfig(self, fileNode, fileset): 

+

187 for option in fileNode.childNodes: 

+

188 if option.nodeType == Node.ELEMENT_NODE and option.tagName == "Option": 

+

189 if option.getAttribute("Name") == "TopModule": 

+

190 fileset.TopLevel = option.getAttribute("Val") 

+

191 

+

192 

+

193@export 

+

194class XDCConstraintFile(ConstraintFile, SDCContent): 

+

195 """A Vivado constraint file (Xilinx Design Constraints; ``*.xdc``).""" 

+

196 

+

197 

+

198@export 

+

199class IPCoreDescriptionFile(XMLFile): 

+

200 pass 

+

201 

+

202 

+

203@export 

+

204class IPCoreInstantiationFile(XMLFile): 

+

205 """A Vivado IP core instantiation file (Xilinx IPCore Instance; ``*.xci``).""" 

+
+ + + diff --git a/coverage/d_f31a6c1cb708999d___init___py.html b/coverage/d_f31a6c1cb708999d___init___py.html new file mode 100644 index 00000000..f0df9b0a --- /dev/null +++ b/coverage/d_f31a6c1cb708999d___init___py.html @@ -0,0 +1,130 @@ + + + + + Coverage for pyEDAA/ProjectModel/Xilinx/__init__.py: 100% + + + + + +
+
+

+ Coverage for pyEDAA/ProjectModel/Xilinx/__init__.py: + 100% +

+ +

+ 1 statements   + + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.3.0, + created at 2023-08-24 21:52 +0000 +

+ +
+
+
+

1# ==================================================================================================================== # 

+

2# _____ ____ _ _ ____ _ _ __ __ _ _ # 

+

3# _ __ _ _| ____| _ \ / \ / \ | _ \ _ __ ___ (_) ___ ___| |_| \/ | ___ __| | ___| | # 

+

4# | '_ \| | | | _| | | | |/ _ \ / _ \ | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ | # 

+

5# | |_) | |_| | |___| |_| / ___ \ / ___ \ _| __/| | | (_) | | __/ (__| |_| | | | (_) | (_| | __/ | # 

+

6# | .__/ \__, |_____|____/_/ \_\/_/ \_(_)_| |_| \___// |\___|\___|\__|_| |_|\___/ \__,_|\___|_| # 

+

7# |_| |___/ |__/ # 

+

8# ==================================================================================================================== # 

+

9# Authors: # 

+

10# Patrick Lehmann # 

+

11# # 

+

12# License: # 

+

13# ==================================================================================================================== # 

+

14# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany # 

+

15# # 

+

16# Licensed under the Apache License, Version 2.0 (the "License"); # 

+

17# you may not use this file except in compliance with the License. # 

+

18# You may obtain a copy of the License at # 

+

19# # 

+

20# http://www.apache.org/licenses/LICENSE-2.0 # 

+

21# # 

+

22# Unless required by applicable law or agreed to in writing, software # 

+

23# distributed under the License is distributed on an "AS IS" BASIS, # 

+

24# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # 

+

25# See the License for the specific language governing permissions and # 

+

26# limitations under the License. # 

+

27# # 

+

28# SPDX-License-Identifier: Apache-2.0 # 

+

29# ==================================================================================================================== # 

+

30# 

+

31"""A vendor specific package for Xilinx.""" 

+
+ + + diff --git a/coverage/favicon_32.png b/coverage/favicon_32.png new file mode 100644 index 00000000..8649f047 Binary files /dev/null and b/coverage/favicon_32.png differ diff --git a/coverage/index.html b/coverage/index.html new file mode 100644 index 00000000..62b52e7a --- /dev/null +++ b/coverage/index.html @@ -0,0 +1,137 @@ + + + + + Code Coverage of pyEDAA.ProjectModel + + + + + +
+
+

Code Coverage of pyEDAA.ProjectModel: + 75% +

+ +
+ +
+

+ coverage.py v7.3.0, + created at 2023-08-24 21:52 +0000 +

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Modulestatementsmissingexcludedbranchespartialcoverage
pyEDAA/ProjectModel/Attributes.py150020100%
pyEDAA/ProjectModel/Xilinx/Vivado.py12114066488%
pyEDAA/ProjectModel/Xilinx/__init__.py10000100%
pyEDAA/ProjectModel/__init__.py106427106387473%
Total120128507067875%
+

+ No items found using the specified filter. +

+
+ + + diff --git a/coverage/keybd_closed.png b/coverage/keybd_closed.png new file mode 100644 index 00000000..ba119c47 Binary files /dev/null and b/coverage/keybd_closed.png differ diff --git a/coverage/keybd_open.png b/coverage/keybd_open.png new file mode 100644 index 00000000..a8bac6c9 Binary files /dev/null and b/coverage/keybd_open.png differ diff --git a/coverage/status.json b/coverage/status.json new file mode 100644 index 00000000..d5efff6b --- /dev/null +++ b/coverage/status.json @@ -0,0 +1 @@ +{"format":2,"version":"7.3.0","globals":"4f6d1111ff6046ef71afc1c84401bcc0","files":{"d_bb657af29d23493a_Attributes_py":{"hash":"2d109a6f130898ae14d80216b05d4985","index":{"nums":[0,1,15,0,0,2,0,0],"html_filename":"d_bb657af29d23493a_Attributes_py.html","relative_filename":"pyEDAA/ProjectModel/Attributes.py"}},"d_f31a6c1cb708999d_Vivado_py":{"hash":"af20e5045bf37245dd542f7cd81670c7","index":{"nums":[0,1,121,0,14,66,4,8],"html_filename":"d_f31a6c1cb708999d_Vivado_py.html","relative_filename":"pyEDAA/ProjectModel/Xilinx/Vivado.py"}},"d_f31a6c1cb708999d___init___py":{"hash":"c6180f9a62d25d25641f0fd1e83c025b","index":{"nums":[0,1,1,0,0,0,0,0],"html_filename":"d_f31a6c1cb708999d___init___py.html","relative_filename":"pyEDAA/ProjectModel/Xilinx/__init__.py"}},"d_bb657af29d23493a___init___py":{"hash":"aa2e16bc4c746c41931c33d94589563e","index":{"nums":[0,1,1064,0,271,638,74,184],"html_filename":"d_bb657af29d23493a___init___py.html","relative_filename":"pyEDAA/ProjectModel/__init__.py"}}}} \ No newline at end of file diff --git a/coverage/style.css b/coverage/style.css new file mode 100644 index 00000000..11b24c4e --- /dev/null +++ b/coverage/style.css @@ -0,0 +1,309 @@ +@charset "UTF-8"; +/* Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 */ +/* For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt */ +/* Don't edit this .css file. Edit the .scss file instead! */ +html, body, h1, h2, h3, p, table, td, th { margin: 0; padding: 0; border: 0; font-weight: inherit; font-style: inherit; font-size: 100%; font-family: inherit; vertical-align: baseline; } + +body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; font-size: 1em; background: #fff; color: #000; } + +@media (prefers-color-scheme: dark) { body { background: #1e1e1e; } } + +@media (prefers-color-scheme: dark) { body { color: #eee; } } + +html > body { font-size: 16px; } + +a:active, a:focus { outline: 2px dashed #007acc; } + +p { font-size: .875em; line-height: 1.4em; } + +table { border-collapse: collapse; } + +td { vertical-align: top; } + +table tr.hidden { display: none !important; } + +p#no_rows { display: none; font-size: 1.2em; } + +a.nav { text-decoration: none; color: inherit; } + +a.nav:hover { text-decoration: underline; color: inherit; } + +.hidden { display: none; } + +header { background: #f8f8f8; width: 100%; z-index: 2; border-bottom: 1px solid #ccc; } + +@media (prefers-color-scheme: dark) { header { background: black; } } + +@media (prefers-color-scheme: dark) { header { border-color: #333; } } + +header .content { padding: 1rem 3.5rem; } + +header h2 { margin-top: .5em; font-size: 1em; } + +header p.text { margin: .5em 0 -.5em; color: #666; font-style: italic; } + +@media (prefers-color-scheme: dark) { header p.text { color: #aaa; } } + +header.sticky { position: fixed; left: 0; right: 0; height: 2.5em; } + +header.sticky .text { display: none; } + +header.sticky h1, header.sticky h2 { font-size: 1em; margin-top: 0; display: inline-block; } + +header.sticky .content { padding: 0.5rem 3.5rem; } + +header.sticky .content p { font-size: 1em; } + +header.sticky ~ #source { padding-top: 6.5em; } + +main { position: relative; z-index: 1; } + +footer { margin: 1rem 3.5rem; } + +footer .content { padding: 0; color: #666; font-style: italic; } + +@media (prefers-color-scheme: dark) { footer .content { color: #aaa; } } + +#index { margin: 1rem 0 0 3.5rem; } + +h1 { font-size: 1.25em; display: inline-block; } + +#filter_container { float: right; margin: 0 2em 0 0; } + +#filter_container input { width: 10em; padding: 0.2em 0.5em; border: 2px solid #ccc; background: #fff; color: #000; } + +@media (prefers-color-scheme: dark) { #filter_container input { border-color: #444; } } + +@media (prefers-color-scheme: dark) { #filter_container input { background: #1e1e1e; } } + +@media (prefers-color-scheme: dark) { #filter_container input { color: #eee; } } + +#filter_container input:focus { border-color: #007acc; } + +header button { font-family: inherit; font-size: inherit; border: 1px solid; border-radius: .2em; color: inherit; padding: .1em .5em; margin: 1px calc(.1em + 1px); cursor: pointer; border-color: #ccc; } + +@media (prefers-color-scheme: dark) { header button { border-color: #444; } } + +header button:active, header button:focus { outline: 2px dashed #007acc; } + +header button.run { background: #eeffee; } + +@media (prefers-color-scheme: dark) { header button.run { background: #373d29; } } + +header button.run.show_run { background: #dfd; border: 2px solid #00dd00; margin: 0 .1em; } + +@media (prefers-color-scheme: dark) { header button.run.show_run { background: #373d29; } } + +header button.mis { background: #ffeeee; } + +@media (prefers-color-scheme: dark) { header button.mis { background: #4b1818; } } + +header button.mis.show_mis { background: #fdd; border: 2px solid #ff0000; margin: 0 .1em; } + +@media (prefers-color-scheme: dark) { header button.mis.show_mis { background: #4b1818; } } + +header button.exc { background: #f7f7f7; } + +@media (prefers-color-scheme: dark) { header button.exc { background: #333; } } + +header button.exc.show_exc { background: #eee; border: 2px solid #808080; margin: 0 .1em; } + +@media (prefers-color-scheme: dark) { header button.exc.show_exc { background: #333; } } + +header button.par { background: #ffffd5; } + +@media (prefers-color-scheme: dark) { header button.par { background: #650; } } + +header button.par.show_par { background: #ffa; border: 2px solid #bbbb00; margin: 0 .1em; } + +@media (prefers-color-scheme: dark) { header button.par.show_par { background: #650; } } + +#help_panel, #source p .annotate.long { display: none; position: absolute; z-index: 999; background: #ffffcc; border: 1px solid #888; border-radius: .2em; color: #333; padding: .25em .5em; } + +#source p .annotate.long { white-space: normal; float: right; top: 1.75em; right: 1em; height: auto; } + +#help_panel_wrapper { float: right; position: relative; } + +#keyboard_icon { margin: 5px; } + +#help_panel_state { display: none; } + +#help_panel { top: 25px; right: 0; padding: .75em; border: 1px solid #883; color: #333; } + +#help_panel .keyhelp p { margin-top: .75em; } + +#help_panel .legend { font-style: italic; margin-bottom: 1em; } + +.indexfile #help_panel { width: 25em; } + +.pyfile #help_panel { width: 18em; } + +#help_panel_state:checked ~ #help_panel { display: block; } + +kbd { border: 1px solid black; border-color: #888 #333 #333 #888; padding: .1em .35em; font-family: SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-weight: bold; background: #eee; border-radius: 3px; } + +#source { padding: 1em 0 1em 3.5rem; font-family: SFMono-Regular, Menlo, Monaco, Consolas, monospace; } + +#source p { position: relative; white-space: pre; } + +#source p * { box-sizing: border-box; } + +#source p .n { float: left; text-align: right; width: 3.5rem; box-sizing: border-box; margin-left: -3.5rem; padding-right: 1em; color: #999; } + +@media (prefers-color-scheme: dark) { #source p .n { color: #777; } } + +#source p .n.highlight { background: #ffdd00; } + +#source p .n a { margin-top: -4em; padding-top: 4em; text-decoration: none; color: #999; } + +@media (prefers-color-scheme: dark) { #source p .n a { color: #777; } } + +#source p .n a:hover { text-decoration: underline; color: #999; } + +@media (prefers-color-scheme: dark) { #source p .n a:hover { color: #777; } } + +#source p .t { display: inline-block; width: 100%; box-sizing: border-box; margin-left: -.5em; padding-left: 0.3em; border-left: 0.2em solid #fff; } + +@media (prefers-color-scheme: dark) { #source p .t { border-color: #1e1e1e; } } + +#source p .t:hover { background: #f2f2f2; } + +@media (prefers-color-scheme: dark) { #source p .t:hover { background: #282828; } } + +#source p .t:hover ~ .r .annotate.long { display: block; } + +#source p .t .com { color: #008000; font-style: italic; line-height: 1px; } + +@media (prefers-color-scheme: dark) { #source p .t .com { color: #6a9955; } } + +#source p .t .key { font-weight: bold; line-height: 1px; } + +#source p .t .str { color: #0451a5; } + +@media (prefers-color-scheme: dark) { #source p .t .str { color: #9cdcfe; } } + +#source p.mis .t { border-left: 0.2em solid #ff0000; } + +#source p.mis.show_mis .t { background: #fdd; } + +@media (prefers-color-scheme: dark) { #source p.mis.show_mis .t { background: #4b1818; } } + +#source p.mis.show_mis .t:hover { background: #f2d2d2; } + +@media (prefers-color-scheme: dark) { #source p.mis.show_mis .t:hover { background: #532323; } } + +#source p.run .t { border-left: 0.2em solid #00dd00; } + +#source p.run.show_run .t { background: #dfd; } + +@media (prefers-color-scheme: dark) { #source p.run.show_run .t { background: #373d29; } } + +#source p.run.show_run .t:hover { background: #d2f2d2; } + +@media (prefers-color-scheme: dark) { #source p.run.show_run .t:hover { background: #404633; } } + +#source p.exc .t { border-left: 0.2em solid #808080; } + +#source p.exc.show_exc .t { background: #eee; } + +@media (prefers-color-scheme: dark) { #source p.exc.show_exc .t { background: #333; } } + +#source p.exc.show_exc .t:hover { background: #e2e2e2; } + +@media (prefers-color-scheme: dark) { #source p.exc.show_exc .t:hover { background: #3c3c3c; } } + +#source p.par .t { border-left: 0.2em solid #bbbb00; } + +#source p.par.show_par .t { background: #ffa; } + +@media (prefers-color-scheme: dark) { #source p.par.show_par .t { background: #650; } } + +#source p.par.show_par .t:hover { background: #f2f2a2; } + +@media (prefers-color-scheme: dark) { #source p.par.show_par .t:hover { background: #6d5d0c; } } + +#source p .r { position: absolute; top: 0; right: 2.5em; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; } + +#source p .annotate { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; color: #666; padding-right: .5em; } + +@media (prefers-color-scheme: dark) { #source p .annotate { color: #ddd; } } + +#source p .annotate.short:hover ~ .long { display: block; } + +#source p .annotate.long { width: 30em; right: 2.5em; } + +#source p input { display: none; } + +#source p input ~ .r label.ctx { cursor: pointer; border-radius: .25em; } + +#source p input ~ .r label.ctx::before { content: "▶ "; } + +#source p input ~ .r label.ctx:hover { background: #e8f4ff; color: #666; } + +@media (prefers-color-scheme: dark) { #source p input ~ .r label.ctx:hover { background: #0f3a42; } } + +@media (prefers-color-scheme: dark) { #source p input ~ .r label.ctx:hover { color: #aaa; } } + +#source p input:checked ~ .r label.ctx { background: #d0e8ff; color: #666; border-radius: .75em .75em 0 0; padding: 0 .5em; margin: -.25em 0; } + +@media (prefers-color-scheme: dark) { #source p input:checked ~ .r label.ctx { background: #056; } } + +@media (prefers-color-scheme: dark) { #source p input:checked ~ .r label.ctx { color: #aaa; } } + +#source p input:checked ~ .r label.ctx::before { content: "▼ "; } + +#source p input:checked ~ .ctxs { padding: .25em .5em; overflow-y: scroll; max-height: 10.5em; } + +#source p label.ctx { color: #999; display: inline-block; padding: 0 .5em; font-size: .8333em; } + +@media (prefers-color-scheme: dark) { #source p label.ctx { color: #777; } } + +#source p .ctxs { display: block; max-height: 0; overflow-y: hidden; transition: all .2s; padding: 0 .5em; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; white-space: nowrap; background: #d0e8ff; border-radius: .25em; margin-right: 1.75em; text-align: right; } + +@media (prefers-color-scheme: dark) { #source p .ctxs { background: #056; } } + +#index { font-family: SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 0.875em; } + +#index table.index { margin-left: -.5em; } + +#index td, #index th { text-align: right; width: 5em; padding: .25em .5em; border-bottom: 1px solid #eee; } + +@media (prefers-color-scheme: dark) { #index td, #index th { border-color: #333; } } + +#index td.name, #index th.name { text-align: left; width: auto; } + +#index th { font-style: italic; color: #333; cursor: pointer; } + +@media (prefers-color-scheme: dark) { #index th { color: #ddd; } } + +#index th:hover { background: #eee; } + +@media (prefers-color-scheme: dark) { #index th:hover { background: #333; } } + +#index th[aria-sort="ascending"], #index th[aria-sort="descending"] { white-space: nowrap; background: #eee; padding-left: .5em; } + +@media (prefers-color-scheme: dark) { #index th[aria-sort="ascending"], #index th[aria-sort="descending"] { background: #333; } } + +#index th[aria-sort="ascending"]::after { font-family: sans-serif; content: " ↑"; } + +#index th[aria-sort="descending"]::after { font-family: sans-serif; content: " ↓"; } + +#index td.name a { text-decoration: none; color: inherit; } + +#index tr.total td, #index tr.total_dynamic td { font-weight: bold; border-top: 1px solid #ccc; border-bottom: none; } + +#index tr.file:hover { background: #eee; } + +@media (prefers-color-scheme: dark) { #index tr.file:hover { background: #333; } } + +#index tr.file:hover td.name { text-decoration: underline; color: inherit; } + +#scroll_marker { position: fixed; z-index: 3; right: 0; top: 0; width: 16px; height: 100%; background: #fff; border-left: 1px solid #eee; will-change: transform; } + +@media (prefers-color-scheme: dark) { #scroll_marker { background: #1e1e1e; } } + +@media (prefers-color-scheme: dark) { #scroll_marker { border-color: #333; } } + +#scroll_marker .marker { background: #ccc; position: absolute; min-height: 3px; width: 100%; } + +@media (prefers-color-scheme: dark) { #scroll_marker .marker { background: #444; } } diff --git a/genindex.html b/genindex.html new file mode 100644 index 00000000..de957466 --- /dev/null +++ b/genindex.html @@ -0,0 +1,715 @@ + + + + + + Index — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ + +

Index

+ +
+ _ + | A + | B + | D + | F + | H + | I + | J + | K + | L + | M + | N + | P + | R + | S + | T + | U + | V + | X + | Y + +
+

_

+ + + +
+ +

A

+ + + +
+ +

B

+ + +
+ +

D

+ + + +
+ +

F

+ + + +
+ +

H

+ + +
+ +

I

+ + +
+ +

J

+ + +
+ +

K

+ + +
+ +

L

+ + +
+ +

M

+ + + +
+ +

N

+ + +
+ +

P

+ + + +
    +
  • + pyEDAA.ProjectModel.MentorGraphics + +
  • +
  • + pyEDAA.ProjectModel.MentorGraphics.ModelSim + +
  • +
  • + pyEDAA.ProjectModel.MentorGraphics.QuestaSim + +
  • +
  • + pyEDAA.ProjectModel.OSVVM + +
  • +
  • + pyEDAA.ProjectModel.Verilog + +
  • +
  • + pyEDAA.ProjectModel.VHDL + +
  • +
  • + pyEDAA.ProjectModel.Xilinx + +
  • +
  • + pyEDAA.ProjectModel.Xilinx.ISE + +
  • +
  • + pyEDAA.ProjectModel.Xilinx.Vivado + +
  • +
  • PythonContent (class in pyEDAA.ProjectModel) +
  • +
+ +

R

+ + + +
+ +

S

+ + + +
+ +

T

+ + + +
+ +

U

+ + +
+ +

V

+ + + +
+ +

X

+ + +
+ +

Y

+ + +
+ + + +
+
+
+ +
+ +
+

© Copyright 2014-2023, Patrick Lehmann, Unai Martinez-Corral. + Last updated on 24.08.2023. +

+
Built with Sphinx using a + theme + provided by Build the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 00000000..0e937523 --- /dev/null +++ b/index.html @@ -0,0 +1,202 @@ + + + + + + + The pyEDAA.ProjectModel Documentation — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+
+ + _images/logo_on_light.svg +
+
Sourcecode on GitHub Code license Documentation - Read Now! Documentation License Documentation License
+
PyPI - Tag PyPI - Status PyPI - Python Version
+
GitHub Workflow - Build and Test Status Libraries.io status for latest release Codacy - Quality Codacy - Line Coverage Codecov - Branch Coverage
+
+
+
+

The pyEDAA.ProjectModel Documentation

+

An abstract model of HDL design projects and EDA tooling.

+
+

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.

+
+
+

Use Cases

+ +
+
+

News

+
+

Oct. 2021 - Reading *.xpr and *.pro Files

+
+
    +
  • Xilinx Vivado’s *.xpr and OSVVM’s *.pro files can now be read.

  • +
  • Filesets can be nested.

  • +
  • The dataset can be validated.

  • +
+
+

Sep. 2021 - Extracted ProjectModel from pyIPCMI

+
+
    +
  • The project model has been extracted from pyIPCMI.

  • +
  • ProjectModel became first citizen of EDA² and got integrated into the pyEDAA namespace at PyPI.

  • +
+
+
+

Contributors

+ +
+
+

License

+

This Python package (source code) is licensed under Apache License 2.0.
+The accompanying documentation is licensed under Creative Commons - Attribution 4.0 (CC-BY 4.0).

+
+

This document was generated on 24.Aug 2023 - 21:52.

+
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2014-2023, Patrick Lehmann, Unai Martinez-Corral. + Last updated on 24.08.2023. +

+
Built with Sphinx using a + theme + provided by Build the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/objects.inv b/objects.inv new file mode 100644 index 00000000..c702f35c Binary files /dev/null and b/objects.inv differ diff --git a/py-modindex.html b/py-modindex.html new file mode 100644 index 00000000..b388e82e --- /dev/null +++ b/py-modindex.html @@ -0,0 +1,227 @@ + + + + + + Python Module Index — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ + +

Python Module Index

+ +
+ p +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+ p
+ pyEDAA +
    + pyEDAA.ProjectModel +
    + pyEDAA.ProjectModel.Altera +
    + pyEDAA.ProjectModel.Altera.Quartus +
    + pyEDAA.ProjectModel.Attributes +
    + pyEDAA.ProjectModel.GHDL +
    + pyEDAA.ProjectModel.Intel +
    + pyEDAA.ProjectModel.Intel.QuartusPrime +
    + pyEDAA.ProjectModel.MentorGraphics +
    + pyEDAA.ProjectModel.MentorGraphics.ModelSim +
    + pyEDAA.ProjectModel.MentorGraphics.QuestaSim +
    + pyEDAA.ProjectModel.OSVVM +
    + pyEDAA.ProjectModel.Verilog +
    + pyEDAA.ProjectModel.VHDL +
    + pyEDAA.ProjectModel.Xilinx +
    + pyEDAA.ProjectModel.Xilinx.ISE +
    + pyEDAA.ProjectModel.Xilinx.Vivado +
+ + +
+
+
+ +
+ +
+

© Copyright 2014-2023, Patrick Lehmann, Unai Martinez-Corral. + Last updated on 24.08.2023. +

+
Built with Sphinx using a + theme + provided by Build the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/pyEDAA.ProjectModel/index.html b/pyEDAA.ProjectModel/index.html new file mode 100644 index 00000000..6a4afa6c --- /dev/null +++ b/pyEDAA.ProjectModel/index.html @@ -0,0 +1,300 @@ + + + + + + + Python Class Reference — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

Python Class Reference

+

Reference of all packages and modules:

+
+ +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2014-2023, Patrick Lehmann, Unai Martinez-Corral. + Last updated on 24.08.2023. +

+
Built with Sphinx using a + theme + provided by Build the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Altera.Quartus.html b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Altera.Quartus.html new file mode 100644 index 00000000..c1476ef2 --- /dev/null +++ b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Altera.Quartus.html @@ -0,0 +1,184 @@ + + + + + + + pyEDAA.ProjectModel.Altera.Quartus — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

pyEDAA.ProjectModel.Altera.Quartus

+

Classes

+
    +
  • QuartusProjectFile: +A Quartus project file (*.qpf).

  • +
  • SDCConstraintFile: +A Quartus constraint file (Synopsys Design Constraints; *.sdc).

  • +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2014-2023, Patrick Lehmann, Unai Martinez-Corral. + Last updated on 24.08.2023. +

+
Built with Sphinx using a + theme + provided by Build the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Altera.html b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Altera.html new file mode 100644 index 00000000..11bf1a43 --- /dev/null +++ b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Altera.html @@ -0,0 +1,182 @@ + + + + + + + pyEDAA.ProjectModel.Altera — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

pyEDAA.ProjectModel.Altera

+

Submodules

+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2014-2023, Patrick Lehmann, Unai Martinez-Corral. + Last updated on 24.08.2023. +

+
Built with Sphinx using a + theme + provided by Build the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Attributes.html b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Attributes.html new file mode 100644 index 00000000..648cb093 --- /dev/null +++ b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Attributes.html @@ -0,0 +1,194 @@ + + + + + + + pyEDAA.ProjectModel.Attributes — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

pyEDAA.ProjectModel.Attributes

+

Classes

+ +
+
+class pyEDAA.ProjectModel.Attributes.KeyValueAttribute[source]
+

Inheritance

+
+

Inheritance diagram of KeyValueAttribute

+
+
+__init__()[source]
+
+ +
+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2014-2023, Patrick Lehmann, Unai Martinez-Corral. + Last updated on 24.08.2023. +

+
Built with Sphinx using a + theme + provided by Build the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/pyEDAA.ProjectModel/pyEDAA.ProjectModel.GHDL.html b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.GHDL.html new file mode 100644 index 00000000..d275f237 --- /dev/null +++ b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.GHDL.html @@ -0,0 +1,178 @@ + + + + + + + pyEDAA.ProjectModel.GHDL — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

pyEDAA.ProjectModel.GHDL

+

Classes

+
    +
  • GHDLWaveformFile: +GHDL’s waveform file (*.ghw) supporting VHDL and Verilog simulation results.

  • +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2014-2023, Patrick Lehmann, Unai Martinez-Corral. + Last updated on 24.08.2023. +

+
Built with Sphinx using a + theme + provided by Build the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Intel.QuartusPrime.html b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Intel.QuartusPrime.html new file mode 100644 index 00000000..f26a98a9 --- /dev/null +++ b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Intel.QuartusPrime.html @@ -0,0 +1,184 @@ + + + + + + + pyEDAA.ProjectModel.Intel.QuartusPrime — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

pyEDAA.ProjectModel.Intel.QuartusPrime

+

Classes

+
    +
  • QuartusProjectFile: +A Quartus project file (*.qpf).

  • +
  • SDCConstraintFile: +A Quartus constraint file (Synopsys Design Constraints; *.sdc).

  • +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2014-2023, Patrick Lehmann, Unai Martinez-Corral. + Last updated on 24.08.2023. +

+
Built with Sphinx using a + theme + provided by Build the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Intel.html b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Intel.html new file mode 100644 index 00000000..725ce662 --- /dev/null +++ b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Intel.html @@ -0,0 +1,182 @@ + + + + + + + pyEDAA.ProjectModel.Intel — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

pyEDAA.ProjectModel.Intel

+

Submodules

+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2014-2023, Patrick Lehmann, Unai Martinez-Corral. + Last updated on 24.08.2023. +

+
Built with Sphinx using a + theme + provided by Build the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.ModelSim.html b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.ModelSim.html new file mode 100644 index 00000000..26155f51 --- /dev/null +++ b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.ModelSim.html @@ -0,0 +1,187 @@ + + + + + + + pyEDAA.ProjectModel.MentorGraphics.ModelSim — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

pyEDAA.ProjectModel.MentorGraphics.ModelSim

+

Classes

+
    +
  • ModelSimProjectFile: +Base-class of all tool-specific project files.

  • +
  • ModelSimINIFile: +Base-class of all tool-specific setting files.

  • +
  • WaveDoFile: +Base-class of all tool-specific waveform configuration files.

  • +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2014-2023, Patrick Lehmann, Unai Martinez-Corral. + Last updated on 24.08.2023. +

+
Built with Sphinx using a + theme + provided by Build the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.QuestaSim.html b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.QuestaSim.html new file mode 100644 index 00000000..64f8fc2b --- /dev/null +++ b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.QuestaSim.html @@ -0,0 +1,187 @@ + + + + + + + pyEDAA.ProjectModel.MentorGraphics.QuestaSim — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

pyEDAA.ProjectModel.MentorGraphics.QuestaSim

+

Classes

+
    +
  • ModelSimProjectFile: +Base-class of all tool-specific project files.

  • +
  • ModelSimINIFile: +Base-class of all tool-specific setting files.

  • +
  • WaveDoFile: +Base-class of all tool-specific waveform configuration files.

  • +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2014-2023, Patrick Lehmann, Unai Martinez-Corral. + Last updated on 24.08.2023. +

+
Built with Sphinx using a + theme + provided by Build the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.html b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.html new file mode 100644 index 00000000..4f2fd312 --- /dev/null +++ b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.html @@ -0,0 +1,184 @@ + + + + + + + pyEDAA.ProjectModel.MentorGraphics — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

pyEDAA.ProjectModel.MentorGraphics

+

Submodules

+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2014-2023, Patrick Lehmann, Unai Martinez-Corral. + Last updated on 24.08.2023. +

+
Built with Sphinx using a + theme + provided by Build the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/pyEDAA.ProjectModel/pyEDAA.ProjectModel.OSVVM.html b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.OSVVM.html new file mode 100644 index 00000000..b7a40571 --- /dev/null +++ b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.OSVVM.html @@ -0,0 +1,178 @@ + + + + + + + pyEDAA.ProjectModel.OSVVM — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

pyEDAA.ProjectModel.OSVVM

+

Classes

+
    +
  • OSVVMProjectFile: +An OSVVM project file (*.pro).

  • +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2014-2023, Patrick Lehmann, Unai Martinez-Corral. + Last updated on 24.08.2023. +

+
Built with Sphinx using a + theme + provided by Build the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/pyEDAA.ProjectModel/pyEDAA.ProjectModel.VHDL.html b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.VHDL.html new file mode 100644 index 00000000..7e36000f --- /dev/null +++ b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.VHDL.html @@ -0,0 +1,173 @@ + + + + + + + pyEDAA.ProjectModel.VHDL — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

pyEDAA.ProjectModel.VHDL

+
+ + +
+
+
+ +
+ +
+

© Copyright 2014-2023, Patrick Lehmann, Unai Martinez-Corral. + Last updated on 24.08.2023. +

+
Built with Sphinx using a + theme + provided by Build the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Verilog.html b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Verilog.html new file mode 100644 index 00000000..047e0ab9 --- /dev/null +++ b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Verilog.html @@ -0,0 +1,178 @@ + + + + + + + pyEDAA.ProjectModel.Verilog — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

pyEDAA.ProjectModel.Verilog

+

Classes

+
    +
  • ValueChangeDumpFile: +Verilog’s waveform file (*.vcd) for exchanging value changes as defined by IEEE Std. 1364.

  • +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2014-2023, Patrick Lehmann, Unai Martinez-Corral. + Last updated on 24.08.2023. +

+
Built with Sphinx using a + theme + provided by Build the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.ISE.html b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.ISE.html new file mode 100644 index 00000000..bfa31405 --- /dev/null +++ b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.ISE.html @@ -0,0 +1,185 @@ + + + + + + + pyEDAA.ProjectModel.Xilinx.ISE — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

pyEDAA.ProjectModel.Xilinx.ISE

+

Classes

+
    +
  • ISEProjectFile: +Base-class of all tool-specific project files.

  • +
  • UCFConstraintFile: +Base-class of all constraint files.

  • +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2014-2023, Patrick Lehmann, Unai Martinez-Corral. + Last updated on 24.08.2023. +

+
Built with Sphinx using a + theme + provided by Build the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.Vivado.html b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.Vivado.html new file mode 100644 index 00000000..e9923a1b --- /dev/null +++ b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.Vivado.html @@ -0,0 +1,207 @@ + + + + + + + pyEDAA.ProjectModel.Xilinx.Vivado — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

pyEDAA.ProjectModel.Xilinx.Vivado

+

Classes

+
    +
  • UsedInAttribute: +Undocumented.

  • +
  • File: +A File represents a file in a design. This base-class is used

  • +
  • ConstraintFile: +Base-class of all constraint files.

  • +
  • VerilogSourceFile: +A Verilog source file (of any language version).

  • +
  • VHDLSourceFile: +A VHDL source file (of any language version).

  • +
  • VivadoProjectFile: +A Vivado project file (*.xpr).

  • +
  • XDCConstraintFile: +A Vivado constraint file (Xilinx Design Constraints; *.xdc).

  • +
  • IPCoreDescriptionFile: +An XML file (*.xml).

  • +
  • IPCoreInstantiationFile: +A Vivado IP core instantiation file (Xilinx IPCore Instance; *.xci).

  • +
+
+
+class pyEDAA.ProjectModel.Xilinx.Vivado.UsedInAttribute[source]
+

Inheritance

+
+

Inheritance diagram of UsedInAttribute

+
+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2014-2023, Patrick Lehmann, Unai Martinez-Corral. + Last updated on 24.08.2023. +

+
Built with Sphinx using a + theme + provided by Build the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.html b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.html new file mode 100644 index 00000000..a67eb8aa --- /dev/null +++ b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.html @@ -0,0 +1,187 @@ + + + + + + + pyEDAA.ProjectModel.Xilinx — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

pyEDAA.ProjectModel.Xilinx

+

Submodules

+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2014-2023, Patrick Lehmann, Unai Martinez-Corral. + Last updated on 24.08.2023. +

+
Built with Sphinx using a + theme + provided by Build the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/pyEDAA.ProjectModel/pyEDAA.ProjectModel.html b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.html new file mode 100644 index 00000000..62e5409f --- /dev/null +++ b/pyEDAA.ProjectModel/pyEDAA.ProjectModel.html @@ -0,0 +1,1602 @@ + + + + + + + pyEDAA.ProjectModel — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+
+ +
+
+ +
+

pyEDAA.ProjectModel

+

Submodules

+ +

Classes

+
    +
  • Attribute: +Undocumented.

  • +
  • FileType: +A meta-class to construct FileType classes.

  • +
  • File: +A File represents a file in a design. This base-class is used

  • +
  • HumanReadableContent: +A file type representing human-readable contents.

  • +
  • XMLContent: +A file type representing XML contents.

  • +
  • YAMLContent: +A file type representing YAML contents.

  • +
  • JSONContent: +A file type representing JSON contents.

  • +
  • INIContent: +A file type representing INI contents.

  • +
  • TOMLContent: +A file type representing TOML contents.

  • +
  • TCLContent: +A file type representing content in TCL code.

  • +
  • SDCContent: +A file type representing contents as Synopsys Design Constraints (SDC).

  • +
  • PythonContent: +A file type representing contents as Python source code.

  • +
  • TextFile: +A text file (*.txt).

  • +
  • LogFile: +A log file (*.log).

  • +
  • XMLFile: +An XML file (*.xml).

  • +
  • SourceFile: +Base-class of all source files.

  • +
  • HDLSourceFile: +Base-class of all HDL source files.

  • +
  • RDLSourceFile: +Base-class of all RDL source files.

  • +
  • NetlistFile: +Base-class of all netlist source files.

  • +
  • EDIFNetlistFile: +Netlist file in EDIF (Electronic Design Interchange Format).

  • +
  • TCLSourceFile: +A TCL source file.

  • +
  • VHDLSourceFile: +A VHDL source file (of any language version).

  • +
  • VerilogBaseFile: +Base-class of all HDL source files.

  • +
  • VerilogSourceFile: +A Verilog source file (of any language version).

  • +
  • VerilogHeaderFile: +A Verilog header file (of any language version).

  • +
  • SystemVerilogBaseFile: +Base-class of all HDL source files.

  • +
  • SystemVerilogSourceFile: +A SystemVerilog source file (of any language version).

  • +
  • SystemVerilogHeaderFile: +A SystemVerilog header file (of any language version).

  • +
  • SystemRDLSourceFile: +A SystemRDL source file (of any language version).

  • +
  • PythonSourceFile: +A Python source file.

  • +
  • CocotbPythonFile: +A Python source file used by Cocotb.

  • +
  • ConstraintFile: +Base-class of all constraint files.

  • +
  • ProjectFile: +Base-class of all tool-specific project files.

  • +
  • CSourceFile: +Base-class of all ANSI-C source files.

  • +
  • CppSourceFile: +Base-class of all ANSI-C++ source files.

  • +
  • SettingFile: +Base-class of all tool-specific setting files.

  • +
  • SimulationAnalysisFile: +Base-class of all tool-specific analysis files.

  • +
  • SimulationElaborationFile: +Base-class of all tool-specific elaboration files.

  • +
  • SimulationStartFile: +Base-class of all tool-specific simulation start-up files.

  • +
  • SimulationRunFile: +Base-class of all tool-specific simulation run (execution) files.

  • +
  • WaveformConfigFile: +Base-class of all tool-specific waveform configuration files.

  • +
  • WaveformDatabaseFile: +Base-class of all tool-specific waveform database files.

  • +
  • WaveformExchangeFile: +Base-class of all tool-independent waveform exchange files.

  • +
  • FileSet: +A FileSet represents a group of files. Filesets can have sub-filesets.

  • +
  • VHDLLibrary: +A VHDLLibrary represents a group of VHDL source files compiled into the same VHDL library.

  • +
  • Design: +A Design represents a group of filesets and the source files therein.

  • +
  • Project: +A Project represents a group of designs and the source files therein.

  • +
+
+
+class pyEDAA.ProjectModel.Attribute[source]
+

Inheritance

+
+

Inheritance diagram of Attribute

+
+ +
+
+class pyEDAA.ProjectModel.FileType(name, bases, dictionary, **kwargs)[source]
+

A meta-class to construct FileType classes.

+

Modifications done by this meta-class: +* Register all classes of type FileType or derived variants in a class field FileType.FileTypes in this meta-class.

+

Inheritance

+
+

Inheritance diagram of FileType

+
+
Parameters:
+

classMembers (Dict) –

+
+
+
+
+FileTypes: Dict[str, FileType] = {'CSourceFile': <class 'pyEDAA.ProjectModel.CSourceFile'>, 'CocotbPythonFile': <class 'pyEDAA.ProjectModel.CocotbPythonFile'>, 'ConstraintFile': <class 'pyEDAA.ProjectModel.Xilinx.Vivado.ConstraintFile'>, 'CppSourceFile': <class 'pyEDAA.ProjectModel.CppSourceFile'>, 'EDIFNetlistFile': <class 'pyEDAA.ProjectModel.EDIFNetlistFile'>, 'File': <class 'pyEDAA.ProjectModel.Xilinx.Vivado.File'>, 'GHDLWaveformFile': <class 'pyEDAA.ProjectModel.GHDL.GHDLWaveformFile'>, 'HDLSourceFile': <class 'pyEDAA.ProjectModel.HDLSourceFile'>, 'IPCoreDescriptionFile': <class 'pyEDAA.ProjectModel.Xilinx.Vivado.IPCoreDescriptionFile'>, 'IPCoreInstantiationFile': <class 'pyEDAA.ProjectModel.Xilinx.Vivado.IPCoreInstantiationFile'>, 'ISEProjectFile': <class 'pyEDAA.ProjectModel.Xilinx.ISE.ISEProjectFile'>, 'LogFile': <class 'pyEDAA.ProjectModel.LogFile'>, 'ModelSimINIFile': <class 'pyEDAA.ProjectModel.MentorGraphics.QuestaSim.ModelSimINIFile'>, 'ModelSimProjectFile': <class 'pyEDAA.ProjectModel.MentorGraphics.QuestaSim.ModelSimProjectFile'>, 'NetlistFile': <class 'pyEDAA.ProjectModel.NetlistFile'>, 'OSVVMProjectFile': <class 'pyEDAA.ProjectModel.OSVVM.OSVVMProjectFile'>, 'ProjectFile': <class 'pyEDAA.ProjectModel.ProjectFile'>, 'PythonSourceFile': <class 'pyEDAA.ProjectModel.PythonSourceFile'>, 'QuartusProjectFile': <class 'pyEDAA.ProjectModel.Intel.QuartusPrime.QuartusProjectFile'>, 'RDLSourceFile': <class 'pyEDAA.ProjectModel.RDLSourceFile'>, 'SDCConstraintFile': <class 'pyEDAA.ProjectModel.Intel.QuartusPrime.SDCConstraintFile'>, 'SettingFile': <class 'pyEDAA.ProjectModel.SettingFile'>, 'SimulationAnalysisFile': <class 'pyEDAA.ProjectModel.SimulationAnalysisFile'>, 'SimulationElaborationFile': <class 'pyEDAA.ProjectModel.SimulationElaborationFile'>, 'SimulationRunFile': <class 'pyEDAA.ProjectModel.SimulationRunFile'>, 'SimulationStartFile': <class 'pyEDAA.ProjectModel.SimulationStartFile'>, 'SourceFile': <class 'pyEDAA.ProjectModel.SourceFile'>, 'SystemRDLSourceFile': <class 'pyEDAA.ProjectModel.SystemRDLSourceFile'>, 'SystemVerilogBaseFile': <class 'pyEDAA.ProjectModel.SystemVerilogBaseFile'>, 'SystemVerilogHeaderFile': <class 'pyEDAA.ProjectModel.SystemVerilogHeaderFile'>, 'SystemVerilogSourceFile': <class 'pyEDAA.ProjectModel.SystemVerilogSourceFile'>, 'TCLSourceFile': <class 'pyEDAA.ProjectModel.TCLSourceFile'>, 'TextFile': <class 'pyEDAA.ProjectModel.TextFile'>, 'UCFConstraintFile': <class 'pyEDAA.ProjectModel.Xilinx.ISE.UCFConstraintFile'>, 'VHDLSourceFile': <class 'pyEDAA.ProjectModel.Xilinx.Vivado.VHDLSourceFile'>, 'ValueChangeDumpFile': <class 'pyEDAA.ProjectModel.Verilog.ValueChangeDumpFile'>, 'VerilogBaseFile': <class 'pyEDAA.ProjectModel.VerilogBaseFile'>, 'VerilogHeaderFile': <class 'pyEDAA.ProjectModel.VerilogHeaderFile'>, 'VerilogSourceFile': <class 'pyEDAA.ProjectModel.Xilinx.Vivado.VerilogSourceFile'>, 'VivadoProjectFile': <class 'pyEDAA.ProjectModel.Xilinx.Vivado.VivadoProjectFile'>, 'WaveDoFile': <class 'pyEDAA.ProjectModel.MentorGraphics.QuestaSim.WaveDoFile'>, 'WaveformConfigFile': <class 'pyEDAA.ProjectModel.WaveformConfigFile'>, 'WaveformDatabaseFile': <class 'pyEDAA.ProjectModel.WaveformDatabaseFile'>, 'WaveformExchangeFile': <class 'pyEDAA.ProjectModel.WaveformExchangeFile'>, 'XDCConstraintFile': <class 'pyEDAA.ProjectModel.Xilinx.Vivado.XDCConstraintFile'>, 'XMLFile': <class 'pyEDAA.ProjectModel.XMLFile'>}
+

Dictionary of all classes of type FileType or derived variants

+
+ +
+
+__init__(name, bases, dictionary, **kwargs)[source]
+
+
Parameters:
+
+
+
+
+ +
+
+static __new__(cls, className, baseClasses, classMembers, *args, **kwargs)[source]
+

Construct a new class using this meta-class.

+
+
Parameters:
+
    +
  • className – The name of the class to construct.

  • +
  • baseClasses – The tuple of base-classes the class is derived from.

  • +
  • members – The dictionary of members for the constructed class.

  • +
  • slots – If true, store object attributes in __slots__ instead of __dict__.

  • +
  • mixin – If true, make the class a Mixin-Class. +If false, create slots if slots is true. +If none, preserve behavior of primary base-class.

  • +
  • singleton – If true, make the class a Singleton.

  • +
  • classMembers (Dict) –

  • +
+
+
Returns:
+

The new class.

+
+
Raises:
+
+
+
+
+ +
+
+__base__
+

alias of ExtendedType

+
+ +
+
+__call__(*args, **kwargs)
+

Call self as a function.

+
+ +
+
+__delattr__(name, /)
+

Implement delattr(self, name).

+
+ +
+
+__dir__()
+

Specialized __dir__ implementation for types.

+
+ +
+
+__getattribute__(name, /)
+

Return getattr(self, name).

+
+ +
+
+__instancecheck__(instance, /)
+

Check if an object is an instance.

+
+ +
+
+__or__(value, /)
+

Return self|value.

+
+ +
+
+classmethod __prepare__(className, baseClasses, slots=False, mixin=False, singleton=False)
+

used to create the namespace for the class statement

+
+
Parameters:
+
    +
  • slots (bool) –

  • +
  • mixin (bool) –

  • +
  • singleton (bool) –

  • +
+
+
+
+ +
+
+__repr__()
+

Return repr(self).

+
+ +
+
+__ror__(value, /)
+

Return value|self.

+
+ +
+
+__setattr__(name, value, /)
+

Implement setattr(self, name, value).

+
+ +
+
+__sizeof__()
+

Return memory consumption of the type object.

+
+ +
+
+__subclasscheck__(subclass, /)
+

Check if a class is a subclass.

+
+ +
+
+__subclasses__()
+

Return a list of immediate subclasses.

+
+ +
+
+__text_signature__ = None
+
+ +
+
+classmethod _checkForAbstractMethods(baseClasses, members)
+

Check if the current class contains abstract methods and return a tuple of them.

+

These abstract methods might be inherited from any base-class. If there are inherited abstract methods, check if +they are now implemented (overridden) by the current class that’s right now constructed.

+
+
Parameters:
+
    +
  • baseClasses (Tuple[type]) – The tuple of base-classes the class is derived from.

  • +
  • members (Dict[str, Any]) – The dictionary of members for the constructed class.

  • +
+
+
Return type:
+

Tuple[Dict[str, Callable], Dict[str, Any]]

+
+
Returns:
+

A tuple of abstract method’s names.

+
+
+
+ +
+
+classmethod _iterateBaseClassPaths(baseClasses)
+

Return a generator to iterate all possible inheritance paths for a given list of base-classes.

+

An inheritance path is expressed as a tuple of base-classes from current base-class (left-most item) to +object (right-most item).

+
+
Parameters:
+

baseClasses (Tuple[type]) – List (tuple) of base-classes.

+
+
Return type:
+

Generator[Tuple[type, ...], None, None]

+
+
Returns:
+

Generator to iterate all inheritance paths. An inheritance path is a tuple of types (base-classes).

+
+
+
+ +
+
+classmethod _wrapNewMethodIfAbstract(newClass)
+

If the class has abstract methods, replace the _new__ method, so it raises an exception.

+
+
Parameters:
+

newClass – The newly constructed class for further modifications.

+
+
Return type:
+

bool

+
+
Returns:
+

True, if the class is abstract.

+
+
Raises:
+

AbstractClassError – If the class is abstract and can’t be instantiated.

+
+
+
+ +
+
+classmethod _wrapNewMethodIfSingleton(newClass, singleton)
+

If a class is a singleton, wrap the _new__ method, so it returns a cached object, if a first object was created.

+

Only the first object creation initializes the object.

+

This implementation is threadsafe.

+
+
Parameters:
+
    +
  • newClass – The newly constructed class for further modifications.

  • +
  • singleton (bool) – If True, the class allows only a single instance to exist.

  • +
+
+
Return type:
+

bool

+
+
Returns:
+

True, if the class is a singleton.

+
+
+
+ +
+
+mro()
+

Return a type’s method resolution order.

+
+ +
+ +
+
+class pyEDAA.ProjectModel.HumanReadableContent[source]
+

A file type representing human-readable contents.

+

Inheritance

+
+

Inheritance diagram of HumanReadableContent

+
+ +
+
+class pyEDAA.ProjectModel.XMLContent[source]
+

A file type representing XML contents.

+

Inheritance

+
+

Inheritance diagram of XMLContent

+
+ +
+
+class pyEDAA.ProjectModel.YAMLContent[source]
+

A file type representing YAML contents.

+

Inheritance

+
+

Inheritance diagram of YAMLContent

+
+ +
+
+class pyEDAA.ProjectModel.JSONContent[source]
+

A file type representing JSON contents.

+

Inheritance

+
+

Inheritance diagram of JSONContent

+
+ +
+
+class pyEDAA.ProjectModel.INIContent[source]
+

A file type representing INI contents.

+

Inheritance

+
+

Inheritance diagram of INIContent

+
+ +
+
+class pyEDAA.ProjectModel.TOMLContent[source]
+

A file type representing TOML contents.

+

Inheritance

+
+

Inheritance diagram of TOMLContent

+
+ +
+
+class pyEDAA.ProjectModel.TCLContent[source]
+

A file type representing content in TCL code.

+

Inheritance

+
+

Inheritance diagram of TCLContent

+
+ +
+
+class pyEDAA.ProjectModel.SDCContent[source]
+

A file type representing contents as Synopsys Design Constraints (SDC).

+

Inheritance

+
+

Inheritance diagram of SDCContent

+
+ +
+
+class pyEDAA.ProjectModel.PythonContent[source]
+

A file type representing contents as Python source code.

+

Inheritance

+
+

Inheritance diagram of PythonContent

+
+ +
+
+class pyEDAA.ProjectModel.FileSet(name, topLevel=None, directory=PosixPath('.'), project=None, design=None, parent=None, vhdlLibrary=None, vhdlVersion=None, verilogVersion=None, svVersion=None, srdlVersion=None)[source]
+

A FileSet represents a group of files. Filesets can have sub-filesets.

+

The order of insertion is preserved. A fileset can be created standalone and +later associated to another fileset, design and/or project. Or a fileset, +design and/or project can be associated immediately while creating the +fileset.

+
+
Parameters:
+
    +
  • name (str) – Name of this fileset.

  • +
  • topLevel (str) – Name of the fileset’s toplevel.

  • +
  • directory (Path) – Path of this fileset (absolute or relative to a parent fileset or design).

  • +
  • project (Project) – Project the file is associated with.

  • +
  • design (Design) – Design the file is associated with.

  • +
  • parent (Optional[FileSet]) – Parent fileset if this fileset is nested.

  • +
  • vhdlLibrary (Union[str, VHDLLibrary]) – Default VHDL library for files in this fileset, if not specified for the file itself.

  • +
  • vhdlVersion (VHDLVersion) – Default VHDL version for files in this fileset, if not specified for the file itself.

  • +
  • verilogVersion (SystemVerilogVersion) – Default Verilog version for files in this fileset, if not specified for the file itself.

  • +
  • svVersion (SystemVerilogVersion) – Default SystemVerilog version for files in this fileset, if not specified for the file itself.

  • +
  • srdlVersion (SystemRDLVersion) – Default SystemRDL version for files in this fileset, if not specified for the file itself.

  • +
  • name

  • +
  • topLevel

  • +
  • directory

  • +
  • project

  • +
  • design

  • +
  • parent

  • +
  • vhdlLibrary

  • +
  • vhdlVersion

  • +
  • verilogVersion

  • +
  • svVersion

  • +
  • srdlVersion

  • +
+
+
+

Inheritance

+
+

Inheritance diagram of FileSet

+
+
+__init__(name, topLevel=None, directory=PosixPath('.'), project=None, design=None, parent=None, vhdlLibrary=None, vhdlVersion=None, verilogVersion=None, svVersion=None, srdlVersion=None)[source]
+
+
Parameters:
+
    +
  • name (str) –

  • +
  • topLevel (str) –

  • +
  • directory (Path) –

  • +
  • project (Project) –

  • +
  • design (Design) –

  • +
  • parent (FileSet | None) –

  • +
  • vhdlLibrary (str | VHDLLibrary) –

  • +
  • vhdlVersion (VHDLVersion) –

  • +
  • verilogVersion (SystemVerilogVersion) –

  • +
  • svVersion (SystemVerilogVersion) –

  • +
  • srdlVersion (SystemRDLVersion) –

  • +
+
+
+
+ +
+
+property Name: str
+

Property setting or returning the fileset’s name.

+
+ +
+
+property TopLevel: str
+

Property setting or returning the fileset’s toplevel.

+
+ +
+
+property Project: Project | None
+

Property setting or returning the project this fileset is used in.

+
+ +
+
+property Design: Design | None
+

Property setting or returning the design this fileset is used in.

+
+ +
+
+property Directory: Path
+

Property setting or returning the directory this fileset is located in.

+
+ +
+
+property ResolvedPath: Path
+

Read-only property returning the resolved path of this fileset.

+
+ +
+
+property Parent: FileSet | None
+

Property setting or returning the parent fileset this fileset is used in.

+
+ +
+
+property FileSets: Dict[str, FileSet]
+

Read-only property returning the dictionary of sub-filesets.

+
+ +
+
+Files(fileType=<class 'pyEDAA.ProjectModel.File'>, fileSet=None)[source]
+

Method returning the files of this fileset.

+
+
Parameters:
+
    +
  • fileType (FileType) – A filter for file types. Default: Any.

  • +
  • fileSet (Union[bool, str, FileSet]) – Specifies how to handle sub-filesets.

  • +
  • fileType

  • +
  • fileSet

  • +
+
+
Return type:
+

Generator[File, None, None]

+
+
+
+ +
+
+AddFileSet(fileSet)[source]
+

Method to add a single sub-fileset to this fileset.

+
+
Parameters:
+
    +
  • fileSet (FileSet) – A fileset to add to this fileset as sub-fileset.

  • +
  • fileSet

  • +
+
+
Return type:
+

None

+
+
+
+ +
+
+AddFileSets(fileSets)[source]
+

Method to add a multiple sub-filesets to this fileset.

+
+
Parameters:
+
    +
  • fileSets (Iterable[FileSet]) – An iterable of filesets to add each to the fileset.

  • +
  • fileSets

  • +
+
+
Return type:
+

None

+
+
+
+ +
+
+property FileSetCount: int
+

Returns number of file sets excl. sub-filesets.

+
+ +
+
+property TotalFileSetCount: int
+

Returns number of file sets incl. sub-filesets.

+
+ +
+
+AddFile(file)[source]
+

Method to add a single file to this fileset.

+
+
Parameters:
+
    +
  • file (File) – A file to add to this fileset.

  • +
  • file

  • +
+
+
Return type:
+

None

+
+
+
+ +
+
+AddFiles(files)[source]
+

Method to add a multiple files to this fileset.

+
+
Parameters:
+
    +
  • files (Iterable[File]) – An iterable of files to add each to the fileset.

  • +
  • files

  • +
+
+
Return type:
+

None

+
+
+
+ +
+
+property FileCount: int
+

Returns number of files excl. sub-filesets.

+
+ +
+
+property TotalFileCount: int
+

Returns number of files incl. the files in sub-filesets.

+
+ +
+
+Validate()[source]
+

Validate this fileset.

+
+
Return type:
+

None

+
+
+
+ +
+
+property VHDLLibrary: VHDLLibrary
+

Property setting or returning the VHDL library of this fileset.

+
+ +
+
+property VHDLVersion: VHDLVersion
+

Property setting or returning the VHDL version of this fileset.

+
+ +
+
+property VerilogVersion: SystemVerilogVersion
+

Property setting or returning the Verilog version of this fileset.

+
+ +
+
+property SVVersion: SystemVerilogVersion
+

Property setting or returning the SystemVerilog version of this fileset.

+
+ +
+
+__len__()[source]
+

Returns number of attributes set on this fileset.

+
+
Return type:
+

int

+
+
Returns:
+

The number if attributes set on this fileset.

+
+
+
+ +
+
+__getitem__(key)[source]
+

Index access for returning attributes on this fileset.

+
+
Parameters:
+

key (Type[Attribute]) – The attribute type.

+
+
Return type:
+

Any

+
+
Returns:
+

The attribute’s value.

+
+
Raises:
+

TypeError – When parameter ‘key’ is not a subclass of Attribute.

+
+
+
+ +
+
+__setitem__(key, value)[source]
+

Index access for adding or setting attributes on this fileset.

+
+
Parameters:
+
    +
  • key (Type[Attribute]) – The attribute type.

  • +
  • value (Any) – The attributes value.

  • +
+
+
Raises:
+

TypeError – When parameter ‘key’ is not a subclass of Attribute.

+
+
Return type:
+

None

+
+
+
+ +
+
+__delitem__(key)[source]
+

Index access for deleting attributes on this fileset.

+
+
Parameters:
+

key (Type[Attribute]) – The attribute type.

+
+
Return type:
+

None

+
+
+
+ +
+
+__str__()[source]
+

Returns the fileset’s name.

+
+
Return type:
+

str

+
+
+
+ +
+ +
+
+class pyEDAA.ProjectModel.VHDLLibrary(name, project=None, design=None, vhdlVersion=None)[source]
+

A VHDLLibrary represents a group of VHDL source files compiled into the same VHDL library.

+
+
Parameters:
+
    +
  • name (str) – The VHDL libraries’ name.

  • +
  • project (Project) – Project the VHDL library is associated with.

  • +
  • design (Design) – Design the VHDL library is associated with.

  • +
  • vhdlVersion (VHDLVersion) – Default VHDL version for files in this VHDL library, if not specified for the file itself.

  • +
  • name

  • +
  • project

  • +
  • design

  • +
  • vhdlVersion

  • +
+
+
+

Inheritance

+
+

Inheritance diagram of VHDLLibrary

+
+
+__init__(name, project=None, design=None, vhdlVersion=None)[source]
+
+
Parameters:
+
    +
  • name (str) –

  • +
  • project (Project) –

  • +
  • design (Design) –

  • +
  • vhdlVersion (VHDLVersion) –

  • +
+
+
+
+ +
+
+property Project: Project | None
+

Property setting or returning the project this VHDL library is used in.

+
+ +
+
+property Design: Design | None
+

Property setting or returning the design this VHDL library is used in.

+
+ +
+
+property Files: Generator[File, None, None]
+

Read-only property to return all files in this VHDL library.

+
+ +
+
+property VHDLVersion: VHDLVersion
+

Property setting or returning the VHDL version of this VHDL library.

+
+ +
+
+property FileCount: int
+

Returns number of files.

+
+ +
+
+__len__()[source]
+

Returns number of attributes set on this VHDL library.

+
+
Return type:
+

int

+
+
Returns:
+

The number if attributes set on this VHDL library.

+
+
+
+ +
+
+__getitem__(key)[source]
+

Index access for returning attributes on this VHDL library.

+
+
Parameters:
+

key (Type[Attribute]) – The attribute type.

+
+
Return type:
+

Any

+
+
Returns:
+

The attribute’s value.

+
+
Raises:
+

TypeError – When parameter ‘key’ is not a subclass of Attribute.

+
+
+
+ +
+
+__setitem__(key, value)[source]
+

Index access for adding or setting attributes on this VHDL library.

+
+
Parameters:
+
    +
  • key (Type[Attribute]) – The attribute type.

  • +
  • value (Any) – The attributes value.

  • +
+
+
Raises:
+

TypeError – When parameter ‘key’ is not a subclass of Attribute.

+
+
Return type:
+

None

+
+
+
+ +
+
+__delitem__(key)[source]
+

Index access for deleting attributes on this VHDL library.

+
+
Parameters:
+

key (Type[Attribute]) – The attribute type.

+
+
Return type:
+

None

+
+
+
+ +
+
+__str__()[source]
+

Returns the VHDL library’s name.

+
+
Return type:
+

str

+
+
+
+ +
+ +
+
+class pyEDAA.ProjectModel.Design(name, topLevel=None, directory=PosixPath('.'), project=None, vhdlVersion=None, verilogVersion=None, svVersion=None, srdlVersion=None)[source]
+

A Design represents a group of filesets and the source files therein.

+

Each design contains at least one fileset - the default fileset. For +designs with VHDL source files, a independent VHDLLibraries overlay structure +exists.

+
+
Parameters:
+
    +
  • name (str) – The design’s name.

  • +
  • topLevel (str) – Name of the design’s toplevel.

  • +
  • directory (Path) – Path of this design (absolute or relative to the project).

  • +
  • project (Project) – Project the design is associated with.

  • +
  • vhdlVersion (VHDLVersion) – Default VHDL version for files in this design, if not specified for the file itself.

  • +
  • verilogVersion (SystemVerilogVersion) – Default Verilog version for files in this design, if not specified for the file itself.

  • +
  • svVersion (SystemVerilogVersion) – Default SystemVerilog version for files in this design, if not specified for the file itself.

  • +
  • srdlVersion (SystemRDLVersion) – Default SystemRDL version for files in this fileset, if not specified for the file itself.

  • +
  • name

  • +
  • topLevel

  • +
  • directory

  • +
  • project

  • +
  • vhdlVersion

  • +
  • verilogVersion

  • +
  • svVersion

  • +
  • srdlVersion

  • +
+
+
+

Inheritance

+
+

Inheritance diagram of Design

+
+
+__init__(name, topLevel=None, directory=PosixPath('.'), project=None, vhdlVersion=None, verilogVersion=None, svVersion=None, srdlVersion=None)[source]
+
+
Parameters:
+
    +
  • name (str) –

  • +
  • topLevel (str) –

  • +
  • directory (Path) –

  • +
  • project (Project) –

  • +
  • vhdlVersion (VHDLVersion) –

  • +
  • verilogVersion (SystemVerilogVersion) –

  • +
  • svVersion (SystemVerilogVersion) –

  • +
  • srdlVersion (SystemRDLVersion) –

  • +
+
+
+
+ +
+
+property Name: str
+

Property setting or returning the design’s name.

+
+ +
+
+property TopLevel: str
+

Property setting or returning the fileset’s toplevel.

+
+ +
+
+property Project: Project | None
+

Property setting or returning the project this design is used in.

+
+ +
+
+property Directory: Path
+

Property setting or returning the directory this design is located in.

+
+ +
+
+property ResolvedPath: Path
+

Read-only property returning the resolved path of this fileset.

+
+ +
+
+property DefaultFileSet: FileSet
+

Property setting or returning the default fileset of this design.

+
+ +
+
+property FileSets: Dict[str, FileSet]
+

Read-only property returning the dictionary of filesets.

+
+ +
+
+Files(fileType=<class 'pyEDAA.ProjectModel.File'>, fileSet=None)[source]
+

Method returning the files of this design.

+
+
Parameters:
+
    +
  • fileType (FileType) – A filter for file types. Default: Any.

  • +
  • fileSet (Union[str, FileSet]) – Specifies if all files from all filesets (fileSet=None) are files from a single fileset are returned.

  • +
  • fileType

  • +
  • fileSet

  • +
+
+
Return type:
+

Generator[File, None, None]

+
+
+
+ +
+
+Validate()[source]
+

Validate this design.

+
+
Return type:
+

None

+
+
+
+ +
+
+property FileSetCount: int
+

Returns number of file sets excl. sub-filesets.

+
+ +
+
+property TotalFileSetCount: int
+

Returns number of file sets incl. sub-filesets.

+
+ +
+
+__len__()[source]
+

Returns number of attributes set on this design.

+
+
Return type:
+

int

+
+
Returns:
+

The number if attributes set on this design.

+
+
+
+ +
+
+__getitem__(key)[source]
+

Index access for returning attributes on this design.

+
+
Parameters:
+

key (Type[Attribute]) – The attribute type.

+
+
Return type:
+

Any

+
+
Returns:
+

The attribute’s value.

+
+
Raises:
+

TypeError – When parameter ‘key’ is not a subclass of Attribute.

+
+
+
+ +
+
+__setitem__(key, value)[source]
+

Index access for adding or setting attributes on this design.

+
+
Parameters:
+
    +
  • key (Type[Attribute]) – The attribute type.

  • +
  • value (Any) – The attributes value.

  • +
+
+
Raises:
+

TypeError – When parameter ‘key’ is not a subclass of Attribute.

+
+
Return type:
+

None

+
+
+
+ +
+
+__delitem__(key)[source]
+

Index access for deleting attributes on this design.

+
+
Parameters:
+

key (Type[Attribute]) – The attribute type.

+
+
Return type:
+

None

+
+
+
+ +
+
+__str__()[source]
+

Return str(self).

+
+
Return type:
+

str

+
+
+
+ +
+ +
+
+class pyEDAA.ProjectModel.Project(name, rootDirectory=PosixPath('.'), vhdlVersion=None, verilogVersion=None, svVersion=None)[source]
+

A Project represents a group of designs and the source files therein.

+
+
Parameters:
+
    +
  • name (str) – The project’s name.

  • +
  • rootDirectory (Path) – Base-path to the project.

  • +
  • vhdlVersion (VHDLVersion) – Default VHDL version for files in this project, if not specified for the file itself.

  • +
  • verilogVersion (SystemVerilogVersion) – Default Verilog version for files in this project, if not specified for the file itself.

  • +
  • svVersion (SystemVerilogVersion) – Default SystemVerilog version for files in this project, if not specified for the file itself.

  • +
  • name

  • +
  • rootDirectory

  • +
  • vhdlVersion

  • +
  • verilogVersion

  • +
  • svVersion

  • +
+
+
+

Inheritance

+
+

Inheritance diagram of Project

+
+
+__init__(name, rootDirectory=PosixPath('.'), vhdlVersion=None, verilogVersion=None, svVersion=None)[source]
+
+
Parameters:
+
    +
  • name (str) –

  • +
  • rootDirectory (Path) –

  • +
  • vhdlVersion (VHDLVersion) –

  • +
  • verilogVersion (SystemVerilogVersion) –

  • +
  • svVersion (SystemVerilogVersion) –

  • +
+
+
+
+ +
+
+property Name: str
+

Property setting or returning the project’s name.

+
+ +
+
+property RootDirectory: Path
+

Property setting or returning the root directory this project is located in.

+
+ +
+
+property ResolvedPath: Path
+

Read-only property returning the resolved path of this fileset.

+
+ +
+
+Validate()[source]
+

Validate this project.

+
+
Return type:
+

None

+
+
+
+ +
+
+property DesignCount: int
+

Returns number of designs.

+
+ +
+
+__len__()[source]
+

Returns number of attributes set on this project.

+
+
Return type:
+

int

+
+
Returns:
+

The number if attributes set on this project.

+
+
+
+ +
+
+__getitem__(key)[source]
+

Index access for returning attributes on this project.

+
+
Parameters:
+

key (Type[Attribute]) – The attribute type.

+
+
Return type:
+

Any

+
+
Returns:
+

The attribute’s value.

+
+
Raises:
+

TypeError – When parameter ‘key’ is not a subclass of Attribute.

+
+
+
+ +
+
+__setitem__(key, value)[source]
+

Index access for adding or setting attributes on this project.

+
+
Parameters:
+
    +
  • key (Type[Attribute]) – The attribute type.

  • +
  • value (Any) – The attributes value.

  • +
+
+
Raises:
+

TypeError – When parameter ‘key’ is not a subclass of Attribute.

+
+
Return type:
+

None

+
+
+
+ +
+
+__delitem__(key)[source]
+

Index access for deleting attributes on this project.

+
+
Parameters:
+

key (Type[Attribute]) – The attribute type.

+
+
Return type:
+

None

+
+
+
+ +
+
+__str__()[source]
+

Return str(self).

+
+
Return type:
+

str

+
+
+
+ +
+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2014-2023, Patrick Lehmann, Unai Martinez-Corral. + Last updated on 24.08.2023. +

+
Built with Sphinx using a + theme + provided by Build the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/search.html b/search.html new file mode 100644 index 00000000..60a04396 --- /dev/null +++ b/search.html @@ -0,0 +1,146 @@ + + + + + + Search — pyEDAA.ProjectModel 0.5.0 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+
    +
  • »
  • +
  • Search
  • +
  • +
  • +
+
+
+ +
+
+ + + + +
+ +
+ +
+
+
+ +
+ +
+

© Copyright 2014-2023, Patrick Lehmann, Unai Martinez-Corral. + Last updated on 24.08.2023. +

+
Built with Sphinx using a + theme + provided by Build the Docs. + + +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/searchindex.js b/searchindex.js new file mode 100644 index 00000000..5de0ab74 --- /dev/null +++ b/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["ChangeLog/index", "Dependency", "Doc-License", "FileTypes/index", "Glossary", "Installation", "License", "ProjectModel/Design", "ProjectModel/File", "ProjectModel/FileSet", "ProjectModel/Project", "ProjectModel/VHDLLibrary", "ProjectModel/index", "coverage/index", "genindex", "index", "py-modindex", "pyEDAA.ProjectModel/index", "pyEDAA.ProjectModel/pyEDAA.ProjectModel", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.Altera", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.Altera.Quartus", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.Attributes", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.GHDL", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.Intel", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.Intel.QuartusPrime", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.ModelSim", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.QuestaSim", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.OSVVM", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.VHDL", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.Verilog", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.ISE", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.Vivado", "typing/index"], "filenames": ["ChangeLog/index.rst", "Dependency.rst", "Doc-License.rst", "FileTypes/index.rst", "Glossary.rst", "Installation.rst", "License.rst", "ProjectModel/Design.rst", "ProjectModel/File.rst", "ProjectModel/FileSet.rst", "ProjectModel/Project.rst", "ProjectModel/VHDLLibrary.rst", "ProjectModel/index.rst", "coverage/index.rst", "genindex.rst", "index.rst", "py-modindex.rst", "pyEDAA.ProjectModel/index.rst", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.rst", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.Altera.rst", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.Altera.Quartus.rst", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.Attributes.rst", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.GHDL.rst", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.Intel.rst", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.Intel.QuartusPrime.rst", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.rst", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.ModelSim.rst", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.MentorGraphics.QuestaSim.rst", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.OSVVM.rst", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.VHDL.rst", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.Verilog.rst", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.rst", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.ISE.rst", "pyEDAA.ProjectModel/pyEDAA.ProjectModel.Xilinx.Vivado.rst", "typing/index.rst"], "titles": ["ChangeLog", "Dependency", "Creative Commons Attribution 4.0 International", "File Types", "Glossary", "Installation/Updates", "Apache License 2.0", "Design", "File", "FileSet", "Project", "VHDL Library", "Project Model", "Coverage Report", "Index", "The pyEDAA.ProjectModel Documentation", "Module Index", "Python Class Reference", "pyEDAA.ProjectModel", "pyEDAA.ProjectModel.Altera", "pyEDAA.ProjectModel.Altera.Quartus", "pyEDAA.ProjectModel.Attributes", "pyEDAA.ProjectModel.GHDL", "pyEDAA.ProjectModel.Intel", "pyEDAA.ProjectModel.Intel.QuartusPrime", "pyEDAA.ProjectModel.MentorGraphics", "pyEDAA.ProjectModel.MentorGraphics.ModelSim", "pyEDAA.ProjectModel.MentorGraphics.QuestaSim", "pyEDAA.ProjectModel.OSVVM", "pyEDAA.ProjectModel.VHDL", "pyEDAA.ProjectModel.Verilog", "pyEDAA.ProjectModel.Xilinx", "pyEDAA.ProjectModel.Xilinx.ISE", "pyEDAA.ProjectModel.Xilinx.Vivado", "Static Type Checking Report"], "terms": {"\u00bd": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u00bc": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u215b": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u00be": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u215c": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u215d": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u215e": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "_": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u00b5": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u03c9": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u00aa": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u00ba": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u00b9": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u00b2": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u00b3": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u212c": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u2145": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u212d": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u2102": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u2146": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u03dd": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u2130": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u2147": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u2131": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u02c7": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u210f": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u210b": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u2111": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u2148": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u2110": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u2124": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u2112": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u2133": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u2115": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u2134": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u210c": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u2119": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u210d": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u211a": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u211c": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u211b": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u211d": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u03f5": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u03d5": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u03c5": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u03b5": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u03f0": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u03c6": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u03d6": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u03f1": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u03c2": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u03d1": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "\u2128": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "tbd": [0, 3], "pyedaa": [0, 5, 17], "projectmodel": [0, 5, 17], "wa": [0, 6, 15, 18], "split": 0, "from": [0, 2, 6, 18], "pyipcmi": 0, "v1": 0, "1": [0, 1, 4], "6": [0, 1, 5], "an": [0, 2, 4, 6, 7, 9, 10, 12, 15, 18, 28, 33], "independ": [0, 2, 18], "python": [0, 1, 5, 15, 18], "packag": [0, 4, 5, 15, 17], "librari": [1, 12, 18], "io": 1, "requir": [1, 2, 5, 6], "version": [1, 6, 18, 33], "licens": 1, "pytool": [1, 18], "5": 1, "0": [1, 15], "apach": [1, 15], "2": [1, 15], "none": [1, 7, 8, 9, 10, 11, 18], "pyvhdlmodel": 1, "27": 1, "pysvmodel": 1, "3": [1, 5], "pysystemrdlmodel": 1, "addit": [1, 2, 15], "need": [1, 2], "code": [1, 6, 15, 18], "collect": [1, 2], "static": [1, 18], "These": [1, 18], "ar": [1, 2, 6, 18], "develop": 1, "thu": 1, "sub": [1, 18], "evalu": 1, "further": [1, 18], "manual": [1, 4], "instal": 1, "us": [1, 4, 6, 18, 33], "txt": [1, 18], "file": [1, 4, 6, 7, 9, 11, 12, 17, 18, 20, 22, 24, 26, 27, 28, 30, 32, 33], "all": [1, 2, 6, 17, 18, 26, 27, 32, 33], "via": 1, "pip3": [1, 5], "The": [1, 2, 6, 18], "recurs": 1, "mandatori": 1, "too": 1, "u": [1, 5], "r": 1, "list": [1, 6, 7, 9, 11, 18], "pytest": [1, 13], "7": [1, 5], "4": [1, 15], "mit": 1, "Not": [1, 6], "yet": 1, "cov": 1, "mypi": [1, 34], "extens": 1, "psf": 1, "lxml": 1, "9": [1, 2], "bsd": 1, "claus": 1, "gener": [1, 6, 7, 8, 9, 10, 11, 13, 15, 18, 34], "doc": 1, "sphinx_btd_them": 1, "sphinx_fontawesom": 1, "gpl": 1, "sphinx_autodoc_typehint": 1, "19": 1, "build": [1, 15], "wheel": 1, "40": 1, "e": 1, "g": 1, "pypi": [1, 15], "ani": [1, 2, 6, 7, 9, 18, 33], "equival": [1, 2], "servic": [1, 2, 6, 15], "maintain": [1, 15], "dist": 1, "twine": 1, "thi": [2, 5, 6, 15, 18, 33], "i": [2, 4, 5, 6, 15, 18, 33], "local": [2, 6], "copi": [2, 6], "cc": [2, 15], "BY": [2, 15], "appli": [2, 6, 12], "onli": [2, 6, 18], "document": [2, 4, 6, 7, 8, 9, 10, 11], "project": [2, 4, 6, 7, 8, 9, 11, 15, 17, 18, 20, 24, 26, 27, 28, 32, 33], "corpor": 2, "law": [2, 6], "firm": 2, "doe": [2, 6], "provid": [2, 6, 15], "legal": [2, 6], "advic": 2, "distribut": [2, 6], "creat": [2, 15, 18], "lawyer": 2, "client": 2, "relationship": [2, 7, 8, 9, 10, 11], "make": [2, 6, 18], "its": [2, 6], "relat": 2, "inform": [2, 6], "avail": [2, 6], "basi": [2, 6], "give": [2, 6], "regard": [2, 6], "materi": 2, "under": [2, 6, 15], "damag": [2, 6], "result": [2, 6, 22], "fullest": 2, "extent": 2, "possibl": [2, 6, 18], "standard": [2, 4], "set": [2, 9, 12, 18, 26, 27], "creator": 2, "holder": 2, "mai": [2, 6], "share": [2, 6], "origin": [2, 6], "work": [2, 6], "authorship": [2, 6], "subject": [2, 6], "copyright": 2, "certain": 2, "specifi": [2, 4, 18], "below": [2, 6], "follow": [2, 6], "consider": 2, "purpos": [2, 6], "exhaust": 2, "do": [2, 6], "form": [2, 6], "part": [2, 6], "our": 2, "licensor": [2, 6], "intend": 2, "those": [2, 6], "author": [2, 6], "permiss": [2, 6], "wai": 2, "otherwis": [2, 6], "restrict": 2, "irrevoc": [2, 6], "should": [2, 6], "read": [2, 18], "understand": 2, "thei": [2, 18], "choos": [2, 6], "befor": 2, "also": [2, 6], "secur": 2, "necessari": 2, "so": [2, 18], "can": [2, 15, 18], "reus": 2, "expect": 2, "clearli": [2, 12], "mark": [2, 6], "includ": [2, 6], "except": [2, 6, 18], "more": [2, 6, 15], "By": 2, "one": [2, 6, 12, 18], "grant": 2, "If": [2, 4, 6, 18], "": [2, 6, 15, 18, 22, 30], "reason": [2, 6], "exampl": [2, 6], "becaus": 2, "applic": [2, 6], "regul": 2, "ha": [2, 6, 12, 15, 18], "still": 2, "have": [2, 6, 12, 18], "A": [2, 4, 6, 12, 18, 20, 24, 33], "special": [2, 6, 18], "request": 2, "ask": 2, "chang": [2, 6, 30], "describ": [2, 6, 15], "although": 2, "you": [2, 6], "encourag": 2, "respect": 2, "where": [2, 6], "exercis": [2, 6], "defin": [2, 4, 6, 30], "accept": 2, "agre": [2, 6], "bound": 2, "To": [2, 6], "contract": [2, 6], "your": [2, 6], "benefit": 2, "receiv": [2, 6], "adapt": 2, "mean": [2, 6], "similar": 2, "deriv": [2, 4, 6, 15, 18], "base": [2, 4, 6, 18, 26, 27, 32, 33], "upon": 2, "which": [2, 6], "translat": [2, 6], "alter": 2, "arrang": 2, "transform": [2, 6], "modifi": [2, 6], "manner": 2, "held": 2, "For": [2, 6, 18], "music": 2, "perform": [2, 6], "sound": 2, "record": 2, "alwai": 2, "produc": 2, "synch": 2, "time": 2, "move": 2, "imag": 2, "contribut": 2, "accord": 2, "close": 2, "without": [2, 6], "broadcast": 2, "how": [2, 5, 6, 18], "label": 2, "categor": 2, "b": 2, "effect": 2, "technolog": 2, "measur": 2, "absenc": 2, "proper": 2, "circumv": 2, "fulfil": 2, "oblig": [2, 6], "articl": 2, "11": 2, "wipo": 2, "treati": 2, "adopt": 2, "decemb": 2, "20": 2, "1996": 2, "agreement": [2, 6], "fair": 2, "deal": 2, "artist": 2, "literari": 2, "individu": [2, 6], "entiti": [2, 4, 6], "process": 2, "reproduct": [2, 6], "displai": [2, 6], "dissemin": 2, "commun": [2, 6], "import": [2, 6], "member": [2, 18], "access": [2, 18], "place": [2, 6], "chosen": 2, "them": [2, 18], "than": 2, "direct": [2, 6], "96": 2, "ec": 2, "european": 2, "parliament": 2, "council": 2, "march": 2, "protect": 2, "amend": 2, "succeed": 2, "well": 2, "essenti": 2, "anywher": 2, "world": 2, "correspond": 2, "herebi": [2, 6], "worldwid": [2, 6], "royalti": [2, 6], "free": [2, 6], "non": [2, 6], "sublicens": [2, 6], "exclus": [2, 6], "reproduc": [2, 6], "whole": [2, 6], "avoid": 2, "doubt": 2, "compli": [2, 6], "media": [2, 6], "format": [2, 6, 18], "technic": 2, "modif": [2, 6, 18], "allow": [2, 18], "whether": [2, 6], "now": [2, 15, 18], "known": 2, "hereaft": 2, "waiv": 2, "assert": [2, 6], "forbid": 2, "simpli": 2, "never": 2, "downstream": 2, "recipi": [2, 6], "offer": [2, 6], "everi": 2, "automat": 2, "No": 2, "impos": 2, "differ": [2, 6], "endors": 2, "noth": [2, 6], "constitut": [2, 6], "constru": [2, 6], "impli": [2, 6], "connect": 2, "sponsor": 2, "offici": 2, "statu": 2, "design": [2, 3, 4, 6, 8, 9, 10, 11, 12, 15, 17, 18, 20, 24, 33], "moral": 2, "integr": [2, 15], "nor": 2, "privaci": 2, "person": 2, "howev": [2, 6], "patent": 2, "trademark": 2, "directli": 2, "through": [2, 6], "societi": 2, "voluntari": 2, "waivabl": 2, "statutori": 2, "compulsori": 2, "scheme": 2, "In": [2, 6], "case": 2, "expressli": 2, "reserv": 2, "made": [2, 6], "must": [2, 6], "retain": [2, 6], "suppli": 2, "identif": [2, 6], "pseudonym": 2, "notic": [2, 6], "refer": [2, 4, 12], "uri": 2, "hyperlink": 2, "practic": 2, "indic": [2, 6], "previou": 2, "text": [2, 6, 18], "satisfi": 2, "medium": [2, 6], "context": [2, 4], "resourc": 2, "remov": 2, "prevent": 2, "extract": 2, "substanti": 2, "portion": 2, "content": [2, 6, 18], "supplement": 2, "replac": [2, 6, 18], "unless": [2, 6], "separ": [2, 6], "undertaken": 2, "represent": [2, 4], "kind": [2, 6], "concern": 2, "express": [2, 6, 18], "titl": [2, 6], "merchant": [2, 6], "fit": [2, 6], "particular": [2, 6], "infring": [2, 6], "latent": 2, "defect": 2, "accuraci": 2, "presenc": 2, "error": 2, "discover": 2, "full": 2, "event": [2, 6], "liabl": [2, 6], "theori": [2, 6], "neglig": [2, 6], "indirect": [2, 6], "incident": [2, 6], "consequenti": [2, 6], "punit": 2, "exemplari": 2, "loss": [2, 6], "cost": 2, "expens": 2, "aris": [2, 6], "out": [2, 6], "even": [2, 6], "been": [2, 6, 15], "advis": [2, 6], "abov": [2, 5, 6], "shall": [2, 6, 12], "most": [2, 18], "approxim": 2, "absolut": [2, 18], "waiver": 2, "here": 2, "fail": 2, "reinstat": 2, "date": [2, 6], "violat": 2, "cure": 2, "within": [2, 6], "30": 2, "dai": 2, "discoveri": 2, "affect": 2, "seek": 2, "remedi": 2, "stop": 2, "surviv": 2, "state": [2, 6], "herein": [2, 6], "reduc": 2, "could": 2, "lawfulli": 2, "provis": 2, "deem": 2, "unenforc": 2, "reform": 2, "minimum": 2, "enforc": 2, "cannot": [2, 6], "sever": 2, "remain": [2, 6], "failur": [2, 6], "consent": 2, "privileg": 2, "immun": 2, "jurisdict": 2, "parti": [2, 6, 15], "notwithstand": [2, 6], "elect": 2, "publish": 2, "instanc": [2, 18, 33], "consid": 2, "permit": 2, "polici": 2, "creativecommon": 2, "org": [2, 6], "logo": 2, "prior": 2, "written": [2, 6], "unauthor": 2, "paragraph": 2, "contact": 2, "goal": [3, 12], "lrm": 4, "languag": [4, 6, 18, 33], "name": [4, 6, 7, 9, 10, 11, 12, 17, 18], "given": [4, 18], "ieee": [4, 30], "hardwar": 4, "descript": [4, 6, 7, 8, 9, 10, 11], "vhdl": [4, 12, 17, 18, 22, 33], "revis": [4, 6], "1076": 4, "2019": 4, "2008": 4, "aka": 4, "iec": 4, "61691": 4, "2011": 4, "2002": 4, "ed": 4, "2004": [4, 6], "10": 4, "2000": 4, "1993": 4, "1987": 4, "verilog": [4, 15, 17, 18, 22, 33], "tbc": 4, "system": [4, 6], "class": [4, 5, 6, 12, 15, 18, 20, 21, 22, 24, 26, 27, 28, 30, 32, 33], "ancestor": 4, "other": [4, 6], "physic": 4, "fileset": [4, 7, 8, 12, 15, 17, 18], "group": [4, 9, 11, 12, 18], "default": [4, 18], "pre": 4, "exist": [4, 18], "vhdllibrari": [4, 7, 9, 17, 18], "namespac": [4, 15, 18], "organ": 4, "unit": [4, 11], "configur": [4, 6, 18, 26, 27], "due": 5, "problem": 5, "meta": [5, 18], "__getattr__": 5, "see": [5, 6], "section": [5, 6], "sourc": [6, 12, 15, 18, 21, 33], "januari": 6, "term": 6, "AND": 6, "condit": 6, "FOR": 6, "owner": 6, "union": [6, 7, 9, 18], "act": 6, "control": 6, "common": [6, 15], "power": 6, "caus": 6, "manag": [6, 15], "ii": 6, "ownership": 6, "fifti": 6, "percent": 6, "50": 6, "outstand": 6, "iii": 6, "benefici": 6, "prefer": 6, "softwar": 6, "object": [6, 12, 18], "mechan": 6, "compil": [6, 18], "convers": 6, "type": [6, 18], "attach": 6, "appendix": 6, "editori": 6, "annot": 6, "elabor": [6, 18], "repres": [6, 18, 33], "mere": 6, "link": 6, "bind": 6, "interfac": 6, "thereof": 6, "intention": 6, "submit": 6, "inclus": 6, "behalf": 6, "electron": [6, 18], "verbal": 6, "sent": 6, "mail": 6, "issu": 6, "track": 6, "discuss": 6, "improv": 6, "exclud": 6, "conspicu": 6, "write": [6, 7, 8, 9, 10, 11], "contributor": 6, "whom": 6, "subsequ": 6, "incorpor": 6, "each": [6, 18], "perpetu": 6, "charg": 6, "prepar": 6, "publicli": 6, "sell": 6, "transfer": 6, "claim": 6, "necessarili": 6, "alon": 6, "combin": 6, "institut": 6, "litig": 6, "against": 6, "cross": 6, "counterclaim": 6, "lawsuit": 6, "alleg": 6, "contributori": 6, "termin": 6, "meet": 6, "carri": 6, "promin": 6, "attribut": [6, 12, 15, 17, 18, 33], "pertain": 6, "readabl": [6, 18], "contain": [6, 11, 12, 18], "least": [6, 12, 18], "along": 6, "wherev": 6, "third": [6, 15], "normal": 6, "appear": 6, "add": [6, 18], "own": [6, 15], "alongsid": 6, "addendum": 6, "statement": [6, 18], "explicitli": 6, "supersed": 6, "execut": [6, 18], "trade": 6, "product": 6, "customari": 6, "AS": 6, "OR": 6, "OF": 6, "either": 6, "sole": 6, "respons": 6, "determin": 6, "appropri": 6, "assum": 6, "risk": 6, "associ": [6, 18], "tort": 6, "deliber": 6, "grossli": 6, "charact": 6, "inabl": 6, "goodwil": 6, "stoppag": 6, "comput": 6, "malfunct": 6, "commerci": 6, "while": [6, 15, 18], "fee": 6, "support": [6, 15, 22], "indemn": 6, "right": [6, 18], "consist": 6, "indemnifi": 6, "defend": 6, "hold": 6, "harmless": 6, "incur": 6, "boilerpl": 6, "field": [6, 18], "enclos": 6, "bracket": 6, "identifi": 6, "don": 6, "t": [6, 18], "comment": 6, "syntax": 6, "we": 6, "recommend": 6, "same": [6, 18], "print": 6, "page": 6, "easier": 6, "archiv": 6, "yyyi": 6, "complianc": 6, "obtain": 6, "http": 6, "www": 6, "specif": [6, 18, 26, 27, 32], "govern": 6, "eda": [7, 8, 9, 10, 12, 15], "export": [7, 8, 9, 10, 11], "_name": [7, 9, 10, 11], "str": [7, 9, 10, 11, 18], "_project": [7, 8, 9, 11], "nullabl": [7, 8, 9, 10, 11], "_directori": [7, 9], "path": [7, 8, 9, 10, 18], "_fileset": [7, 8, 9], "dict": [7, 9, 10, 18], "_defaultfileset": 7, "_vhdllibrari": [7, 9], "_vhdlversion": [7, 9, 10, 11], "vhdlversion": [7, 9, 10, 11, 17, 18], "_verilogvers": [7, 9, 10], "verilogvers": [7, 9, 10, 17, 18], "_svversion": [7, 9, 10], "systemverilogvers": [7, 9, 10, 18], "_externalvhdllibrari": 7, "def": [7, 8, 9, 10, 11], "__init__": [7, 8, 9, 10, 11, 17, 18, 21], "self": [7, 8, 9, 10, 11, 18], "directori": [7, 9, 17, 18], "svversion": [7, 9, 10, 17, 18], "properti": [7, 8, 9, 10, 11, 18], "setter": [7, 8, 9, 10, 11], "valu": [7, 8, 9, 10, 11, 18, 30], "resolvedpath": [7, 8, 9, 10, 17, 18], "defaultfileset": [7, 17, 18], "filetyp": [7, 8, 9, 17, 18], "externalvhdllibrari": 7, "addfileset": [7, 17, 18], "iter": [7, 9, 18], "addfil": [7, 9, 17, 18], "metaclass": [8, 18], "_path": 8, "_design": [8, 9, 10, 11], "_parent": 9, "_file": [9, 11], "parent": [9, 12, 17, 18], "_rootdirectori": 10, "rootdirectori": [10, 17, 18], "primari": [11, 18], "semant": 12, "child": 12, "overal": 12, "hierarchi": 12, "multipl": [12, 15, 18], "variant": [12, 18], "usual": 12, "element": 12, "placehold": [13, 34], "abstract": [15, 18], "model": 15, "hdl": [15, 18], "tool": [15, 18, 26, 27, 32], "unifi": 15, "framework": 15, "implement": [15, 18], "logic": 15, "concret": 15, "consum": 15, "higher": 15, "level": 15, "featur": 15, "top": 15, "input": 15, "open": 15, "simul": [15, 18, 22], "synthesi": 15, "ghdl": [15, 17, 18], "icaru": 15, "veril": 15, "yosi": 15, "rout": 15, "vtr": 15, "nextpnr": 15, "etc": 15, "ip": [15, 33], "core": [15, 33], "xilinx": [15, 17, 18], "vivado": [15, 17, 18, 31], "osvvm": [15, 17, 18], "nest": [15, 18], "dataset": 15, "valid": [15, 17, 18], "becam": 15, "first": [15, 18], "citizen": 15, "eda\u00b2": 15, "got": 15, "patrick": 15, "lehmann": 15, "unai": 15, "martinez": 15, "corral": 15, "accompani": 15, "creativ": 15, "24": 15, "aug": 15, "2023": 15, "21": 15, "52": 15, "modul": 17, "altera": [17, 18], "quartu": [17, 18, 19, 24], "keyvalueattribut": [17, 18, 21], "intel": [17, 18], "quartusprim": [17, 18, 23], "mentorgraph": [17, 18], "modelsim": [17, 18, 25], "questasim": [17, 18, 25], "ISE": [17, 18, 31], "usedinattribut": [17, 18, 31, 33], "__new__": [17, 18], "__base__": [17, 18], "__call__": [17, 18], "__delattr__": [17, 18], "__dir__": [17, 18], "__getattribute__": [17, 18], "__instancecheck__": [17, 18], "__or__": [17, 18], "__prepare__": [17, 18], "__repr__": [17, 18], "__ror__": [17, 18], "__setattr__": [17, 18], "__sizeof__": [17, 18], "__subclasscheck__": [17, 18], "__subclasses__": [17, 18], "__text_signature__": [17, 18], "_checkforabstractmethod": [17, 18], "_iteratebaseclasspath": [17, 18], "_wrapnewmethodifabstract": [17, 18], "_wrapnewmethodifsingleton": [17, 18], "mro": [17, 18], "humanreadablecont": [17, 18], "xmlcontent": [17, 18], "yamlcont": [17, 18], "jsoncont": [17, 18], "inicont": [17, 18], "tomlcont": [17, 18], "tclcontent": [17, 18], "sdccontent": [17, 18], "pythoncont": [17, 18], "toplevel": [17, 18], "filesetcount": [17, 18], "totalfilesetcount": [17, 18], "filecount": [17, 18], "totalfilecount": [17, 18], "__len__": [17, 18], "__getitem__": [17, 18], "__setitem__": [17, 18], "__delitem__": [17, 18], "__str__": [17, 18], "designcount": [17, 18], "submodul": [18, 19, 23, 25, 31], "undocu": [18, 21, 33], "construct": 18, "human": 18, "xml": [18, 33], "yaml": 18, "json": 18, "ini": 18, "toml": 18, "tcl": 18, "synopsi": [18, 20, 24], "constraint": [18, 20, 24, 32, 33], "sdc": [18, 20, 24], "textfil": 18, "logfil": 18, "log": 18, "xmlfile": 18, "sourcefil": 18, "hdlsourcefil": 18, "rdlsourcefil": 18, "rdl": 18, "netlistfil": 18, "netlist": 18, "edifnetlistfil": 18, "edif": 18, "interchang": 18, "tclsourcefil": 18, "vhdlsourcefil": [18, 33], "verilogbasefil": 18, "verilogsourcefil": [18, 33], "verilogheaderfil": 18, "header": 18, "systemverilogbasefil": 18, "systemverilogsourcefil": 18, "systemverilog": 18, "systemverilogheaderfil": 18, "systemrdlsourcefil": 18, "systemrdl": 18, "pythonsourcefil": 18, "cocotbpythonfil": 18, "cocotb": 18, "constraintfil": [18, 33], "projectfil": 18, "csourcefil": 18, "ansi": 18, "c": 18, "cppsourcefil": 18, "settingfil": 18, "simulationanalysisfil": 18, "analysi": 18, "simulationelaborationfil": 18, "simulationstartfil": 18, "start": 18, "up": 18, "simulationrunfil": 18, "run": 18, "waveformconfigfil": 18, "waveform": [18, 22, 26, 27, 30], "waveformdatabasefil": 18, "databas": 18, "waveformexchangefil": 18, "exchang": [18, 30], "therein": 18, "inherit": [18, 21, 33], "dictionari": 18, "kwarg": 18, "done": 18, "regist": 18, "extendedtyp": 18, "paramet": 18, "classmemb": 18, "ghdlwaveformfil": [18, 22], "ipcoredescriptionfil": [18, 33], "ipcoreinstantiationfil": [18, 33], "iseprojectfil": [18, 32], "modelsiminifil": [18, 26, 27], "modelsimprojectfil": [18, 26, 27], "osvvmprojectfil": [18, 28], "quartusprojectfil": [18, 20, 24], "sdcconstraintfil": [18, 20, 24], "ucfconstraintfil": [18, 32], "valuechangedumpfil": [18, 30], "vivadoprojectfil": [18, 33], "wavedofil": [18, 26, 27], "xdcconstraintfil": [18, 33], "tupl": 18, "cl": 18, "classnam": 18, "baseclass": 18, "arg": 18, "new": 18, "slot": 18, "true": 18, "store": 18, "__slots__": 18, "instead": 18, "__dict__": 18, "mixin": 18, "fals": 18, "preserv": 18, "behavior": 18, "singleton": 18, "return": 18, "rais": 18, "attributeerror": 18, "alreadi": 18, "alia": 18, "call": 18, "function": 18, "delattr": 18, "getattr": 18, "check": 18, "classmethod": 18, "bool": 18, "repr": 18, "setattr": 18, "memori": 18, "consumpt": 18, "subclass": 18, "immedi": 18, "current": 18, "method": 18, "might": 18, "overridden": 18, "callabl": 18, "left": 18, "item": 18, "newclass": 18, "_new__": 18, "newli": 18, "abstractclasserror": 18, "instanti": [18, 33], "wrap": 18, "cach": 18, "creation": 18, "initi": 18, "threadsaf": 18, "singl": 18, "resolut": 18, "order": 18, "posixpath": 18, "srdlversion": 18, "insert": 18, "standalon": 18, "later": 18, "anoth": 18, "Or": 18, "rel": 18, "option": 18, "itself": 18, "systemrdlvers": 18, "locat": 18, "resolv": 18, "filter": 18, "handl": 18, "int": 18, "number": 18, "excl": 18, "incl": 18, "kei": 18, "index": 18, "typeerror": 18, "when": 18, "ad": 18, "delet": 18, "overlai": 18, "structur": 18, "root": 18, "qpf": [20, 24], "ghw": 22, "pro": 28, "vcd": 30, "std": 30, "1364": 30, "xpr": 33, "xdc": 33, "ipcor": 33, "xci": 33}, "objects": {"pyEDAA": [[18, 0, 0, "-", "ProjectModel"]], "pyEDAA.ProjectModel": [[19, 0, 0, "-", "Altera"], [18, 1, 1, "", "Attribute"], [21, 0, 0, "-", "Attributes"], [18, 1, 1, "", "Design"], [18, 1, 1, "", "FileSet"], [18, 1, 1, "", "FileType"], [22, 0, 0, "-", "GHDL"], [18, 1, 1, "", "HumanReadableContent"], [18, 1, 1, "", "INIContent"], [23, 0, 0, "-", "Intel"], [18, 1, 1, "", "JSONContent"], [25, 0, 0, "-", "MentorGraphics"], [28, 0, 0, "-", "OSVVM"], [18, 1, 1, "", "Project"], [18, 1, 1, "", "PythonContent"], [18, 1, 1, "", "SDCContent"], [18, 1, 1, "", "TCLContent"], [18, 1, 1, "", "TOMLContent"], [29, 0, 0, "-", "VHDL"], [18, 1, 1, "", "VHDLLibrary"], [30, 0, 0, "-", "Verilog"], [18, 1, 1, "", "XMLContent"], [31, 0, 0, "-", "Xilinx"], [18, 1, 1, "", "YAMLContent"]], "pyEDAA.ProjectModel.Altera": [[20, 0, 0, "-", "Quartus"]], "pyEDAA.ProjectModel.Attributes": [[21, 1, 1, "", "KeyValueAttribute"]], "pyEDAA.ProjectModel.Attributes.KeyValueAttribute": [[21, 2, 1, "", "__init__"]], "pyEDAA.ProjectModel.Design": [[18, 3, 1, "", "DefaultFileSet"], [18, 3, 1, "", "Directory"], [18, 3, 1, "", "FileSetCount"], [18, 3, 1, "", "FileSets"], [18, 2, 1, "", "Files"], [18, 3, 1, "", "Name"], [18, 3, 1, "", "Project"], [18, 3, 1, "", "ResolvedPath"], [18, 3, 1, "", "TopLevel"], [18, 3, 1, "", "TotalFileSetCount"], [18, 2, 1, "", "Validate"], [18, 2, 1, "", "__delitem__"], [18, 2, 1, "", "__getitem__"], [18, 2, 1, "", "__init__"], [18, 2, 1, "", "__len__"], [18, 2, 1, "", "__setitem__"], [18, 2, 1, "", "__str__"]], "pyEDAA.ProjectModel.FileSet": [[18, 2, 1, "", "AddFile"], [18, 2, 1, "", "AddFileSet"], [18, 2, 1, "", "AddFileSets"], [18, 2, 1, "", "AddFiles"], [18, 3, 1, "", "Design"], [18, 3, 1, "", "Directory"], [18, 3, 1, "", "FileCount"], [18, 3, 1, "", "FileSetCount"], [18, 3, 1, "", "FileSets"], [18, 2, 1, "", "Files"], [18, 3, 1, "", "Name"], [18, 3, 1, "", "Parent"], [18, 3, 1, "", "Project"], [18, 3, 1, "", "ResolvedPath"], [18, 3, 1, "", "SVVersion"], [18, 3, 1, "", "TopLevel"], [18, 3, 1, "", "TotalFileCount"], [18, 3, 1, "", "TotalFileSetCount"], [18, 3, 1, "", "VHDLLibrary"], [18, 3, 1, "", "VHDLVersion"], [18, 2, 1, "", "Validate"], [18, 3, 1, "", "VerilogVersion"], [18, 2, 1, "", "__delitem__"], [18, 2, 1, "", "__getitem__"], [18, 2, 1, "", "__init__"], [18, 2, 1, "", "__len__"], [18, 2, 1, "", "__setitem__"], [18, 2, 1, "", "__str__"]], "pyEDAA.ProjectModel.FileType": [[18, 4, 1, "", "FileTypes"], [18, 4, 1, "", "__base__"], [18, 2, 1, "", "__call__"], [18, 2, 1, "", "__delattr__"], [18, 2, 1, "", "__dir__"], [18, 2, 1, "", "__getattribute__"], [18, 2, 1, "", "__init__"], [18, 2, 1, "", "__instancecheck__"], [18, 2, 1, "", "__new__"], [18, 2, 1, "", "__or__"], [18, 2, 1, "", "__prepare__"], [18, 2, 1, "", "__repr__"], [18, 2, 1, "", "__ror__"], [18, 2, 1, "", "__setattr__"], [18, 2, 1, "", "__sizeof__"], [18, 2, 1, "", "__subclasscheck__"], [18, 2, 1, "", "__subclasses__"], [18, 4, 1, "", "__text_signature__"], [18, 2, 1, "", "_checkForAbstractMethods"], [18, 2, 1, "", "_iterateBaseClassPaths"], [18, 2, 1, "", "_wrapNewMethodIfAbstract"], [18, 2, 1, "", "_wrapNewMethodIfSingleton"], [18, 2, 1, "", "mro"]], "pyEDAA.ProjectModel.Intel": [[24, 0, 0, "-", "QuartusPrime"]], "pyEDAA.ProjectModel.MentorGraphics": [[26, 0, 0, "-", "ModelSim"], [27, 0, 0, "-", "QuestaSim"]], "pyEDAA.ProjectModel.Project": [[18, 3, 1, "", "DesignCount"], [18, 3, 1, "", "Name"], [18, 3, 1, "", "ResolvedPath"], [18, 3, 1, "", "RootDirectory"], [18, 2, 1, "", "Validate"], [18, 2, 1, "", "__delitem__"], [18, 2, 1, "", "__getitem__"], [18, 2, 1, "", "__init__"], [18, 2, 1, "", "__len__"], [18, 2, 1, "", "__setitem__"], [18, 2, 1, "", "__str__"]], "pyEDAA.ProjectModel.VHDLLibrary": [[18, 3, 1, "", "Design"], [18, 3, 1, "", "FileCount"], [18, 3, 1, "", "Files"], [18, 3, 1, "", "Project"], [18, 3, 1, "", "VHDLVersion"], [18, 2, 1, "", "__delitem__"], [18, 2, 1, "", "__getitem__"], [18, 2, 1, "", "__init__"], [18, 2, 1, "", "__len__"], [18, 2, 1, "", "__setitem__"], [18, 2, 1, "", "__str__"]], "pyEDAA.ProjectModel.Xilinx": [[32, 0, 0, "-", "ISE"], [33, 0, 0, "-", "Vivado"]], "pyEDAA.ProjectModel.Xilinx.Vivado": [[33, 1, 1, "", "UsedInAttribute"]]}, "objtypes": {"0": "py:module", "1": "py:class", "2": "py:method", "3": "py:property", "4": "py:attribute"}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "class", "Python class"], "2": ["py", "method", "Python method"], "3": ["py", "property", "Python property"], "4": ["py", "attribute", "Python attribute"]}, "titleterms": {"changelog": 0, "upcom": 0, "releas": 0, "01": 0, "09": 0, "2021": [0, 15], "depend": 1, "pyedaa": [1, 15, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33], "projectmodel": [1, 15, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33], "packag": 1, "unit": 1, "test": 1, "coverag": [1, 13], "type": [1, 3, 34], "check": [1, 34], "option": 1, "sphinx": 1, "document": [1, 15], "publish": 1, "ci": 1, "server": 1, "onli": 1, "creativ": 2, "common": 2, "attribut": [2, 21], "4": [2, 6], "0": [2, 6], "intern": 2, "us": [2, 5, 15], "public": 2, "licens": [2, 6, 15], "section": 2, "1": [2, 6], "definit": [2, 6, 7, 8, 9, 10, 11], "2": [2, 6], "scope": 2, "3": [2, 6], "condit": 2, "sui": 2, "generi": 2, "databas": 2, "right": 2, "5": [2, 6], "disclaim": [2, 6], "warranti": [2, 6], "limit": [2, 6], "liabil": [2, 6], "6": [2, 6], "term": 2, "termin": 2, "7": [2, 6], "other": 2, "8": [2, 6], "interpret": 2, "file": [3, 8, 15], "content": 3, "overal": 3, "hierarchi": 3, "glossari": 4, "instal": 5, "updat": 5, "pip": 5, "from": [5, 15], "pypi": 5, "uninstal": 5, "local": 5, "directori": 5, "setup": 5, "py": 5, "legaci": 5, "apach": 6, "grant": 6, "copyright": 6, "patent": 6, "redistribut": 6, "submiss": 6, "contribut": 6, "trademark": 6, "9": 6, "accept": 6, "addit": 6, "design": 7, "todo": [7, 8, 9, 10, 11], "condens": [7, 8, 9, 10, 11], "class": [7, 8, 9, 10, 11, 17], "fileset": 9, "project": [10, 12], "vhdl": [11, 29], "librari": 11, "vhdllibrari": 11, "model": 12, "report": [13, 34], "index": [14, 16], "The": 15, "main": 15, "goal": 15, "case": 15, "new": 15, "oct": 15, "read": 15, "xpr": 15, "pro": 15, "sep": 15, "extract": 15, "pyipcmi": 15, "contributor": 15, "modul": 16, "python": 17, "refer": 17, "altera": [19, 20], "quartu": 20, "ghdl": 22, "intel": [23, 24], "quartusprim": 24, "mentorgraph": [25, 26, 27], "modelsim": 26, "questasim": 27, "osvvm": 28, "verilog": 30, "xilinx": [31, 32, 33], "ISE": 32, "vivado": 33, "static": 34}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.intersphinx": 1, "sphinx.ext.todo": 2, "sphinx.ext.viewcode": 1, "sphinx": 60}, "alltitles": {"ChangeLog": [[0, "changelog"]], "Upcoming Release": [[0, "upcoming-release"]], "01.09.2021": [[0, "id1"]], "Dependency": [[1, "dependency"]], "pyEDAA.ProjectModel Package": [[1, "pyedaa-projectmodel-package"]], "Unit Testing / Coverage / Type Checking (Optional)": [[1, "unit-testing-coverage-type-checking-optional"]], "Sphinx Documentation (Optional)": [[1, "sphinx-documentation-optional"]], "Packaging (Optional)": [[1, "packaging-optional"]], "Publishing (CI-Server only)": [[1, "publishing-ci-server-only"]], "Creative Commons Attribution 4.0 International": [[2, "creative-commons-attribution-4-0-international"]], "Using Creative Commons Public Licenses": [[2, null]], "Section 1 \u2013 Definitions.": [[2, "section-1-definitions"]], "Section 2 \u2013 Scope.": [[2, "section-2-scope"]], "Section 3 \u2013 License Conditions.": [[2, "section-3-license-conditions"]], "Section 4 \u2013 Sui Generis Database Rights.": [[2, "section-4-sui-generis-database-rights"]], "Section 5 \u2013 Disclaimer of Warranties and Limitation of Liability.": [[2, "section-5-disclaimer-of-warranties-and-limitation-of-liability"]], "Section 6 \u2013 Term and Termination.": [[2, "section-6-term-and-termination"]], "Section 7 \u2013 Other Terms and Conditions.": [[2, "section-7-other-terms-and-conditions"]], "Section 8 \u2013 Interpretation.": [[2, "section-8-interpretation"]], "File Types": [[3, "file-types"]], "Content Types": [[3, "content-types"]], "Overall Hierarchy": [[3, "overall-hierarchy"]], "Glossary": [[4, "glossary"]], "Installation/Updates": [[5, "installation-updates"]], "Using PIP": [[5, "using-pip"]], "Installation from PyPI using PIP": [[5, "installation-from-pypi-using-pip"]], "Updating from PyPI using PIP": [[5, "updating-from-pypi-using-pip"]], "Uninstallation using PIP": [[5, "uninstallation-using-pip"]], "Installation from local directory using PIP": [[5, "installation-from-local-directory-using-pip"]], "Using setup.py (legacy)": [[5, "using-setup-py-legacy"]], "Installation using setup.py": [[5, "installation-using-setup-py"]], "Apache License 2.0": [[6, "apache-license-2-0"]], "1. Definitions.": [[6, "definitions"]], "2. Grant of Copyright License.": [[6, "grant-of-copyright-license"]], "3. Grant of Patent License.": [[6, "grant-of-patent-license"]], "4. Redistribution.": [[6, "redistribution"]], "5. Submission of Contributions.": [[6, "submission-of-contributions"]], "6. Trademarks.": [[6, "trademarks"]], "7. Disclaimer of Warranty.": [[6, "disclaimer-of-warranty"]], "8. Limitation of Liability.": [[6, "limitation-of-liability"]], "9. Accepting Warranty or Additional Liability.": [[6, "accepting-warranty-or-additional-liability"]], "Design": [[7, "design"]], "Todo": [[7, "id1"], [8, "id1"], [9, "id1"], [10, "id1"], [11, "id1"]], "Condensed definition of class Design": [[7, "condensed-definition-of-class-design"]], "File": [[8, "file"]], "Condensed definition of class File": [[8, "condensed-definition-of-class-file"]], "FileSet": [[9, "fileset"]], "Condensed definition of class FileSet": [[9, "condensed-definition-of-class-fileset"]], "Project": [[10, "project"]], "Condensed definition of class Project": [[10, "condensed-definition-of-class-project"]], "VHDL Library": [[11, "vhdl-library"]], "Condensed definition of class VHDLLibrary": [[11, "condensed-definition-of-class-vhdllibrary"]], "Project Model": [[12, "project-model"]], "Coverage Report": [[13, "coverage-report"]], "Index": [[14, "index"]], "The pyEDAA.ProjectModel Documentation": [[15, "the-pyedaa-projectmodel-documentation"]], "Main Goals": [[15, "main-goals"]], "Use Cases": [[15, "use-cases"]], "News": [[15, "news"]], "Oct. 2021 - Reading *.xpr and *.pro Files": [[15, "oct-2021-reading-xpr-and-pro-files"]], "Sep. 2021 - Extracted ProjectModel from pyIPCMI": [[15, "sep-2021-extracted-projectmodel-from-pyipcmi"]], "Contributors": [[15, "contributors"]], "License": [[15, "license"]], "Module Index": [[16, "module-index"]], "Python Class Reference": [[17, "python-class-reference"]], "pyEDAA.ProjectModel": [[18, "pyedaa-projectmodel"]], "pyEDAA.ProjectModel.Altera": [[19, "pyedaa-projectmodel-altera"]], "pyEDAA.ProjectModel.Altera.Quartus": [[20, "pyedaa-projectmodel-altera-quartus"]], "pyEDAA.ProjectModel.Attributes": [[21, "pyedaa-projectmodel-attributes"]], "pyEDAA.ProjectModel.GHDL": [[22, "pyedaa-projectmodel-ghdl"]], "pyEDAA.ProjectModel.Intel": [[23, "pyedaa-projectmodel-intel"]], "pyEDAA.ProjectModel.Intel.QuartusPrime": [[24, "pyedaa-projectmodel-intel-quartusprime"]], "pyEDAA.ProjectModel.MentorGraphics": [[25, "pyedaa-projectmodel-mentorgraphics"]], "pyEDAA.ProjectModel.MentorGraphics.ModelSim": [[26, "pyedaa-projectmodel-mentorgraphics-modelsim"]], "pyEDAA.ProjectModel.MentorGraphics.QuestaSim": [[27, "pyedaa-projectmodel-mentorgraphics-questasim"]], "pyEDAA.ProjectModel.OSVVM": [[28, "pyedaa-projectmodel-osvvm"]], "pyEDAA.ProjectModel.VHDL": [[29, "pyedaa-projectmodel-vhdl"]], "pyEDAA.ProjectModel.Verilog": [[30, "pyedaa-projectmodel-verilog"]], "pyEDAA.ProjectModel.Xilinx": [[31, "pyedaa-projectmodel-xilinx"]], "pyEDAA.ProjectModel.Xilinx.ISE": [[32, "pyedaa-projectmodel-xilinx-ise"]], "pyEDAA.ProjectModel.Xilinx.Vivado": [[33, "pyedaa-projectmodel-xilinx-vivado"]], "Static Type Checking Report": [[34, "static-type-checking-report"]]}, "indexentries": {"default fileset": [[4, "term-Default-fileset"]], "design": [[4, "term-Design"]], "file": [[4, "term-File"]], "fileset": [[4, "term-FileSet"]], "lrm": [[4, "term-LRM"]], "project": [[4, "term-Project"]], "vhdllibrary": [[4, "term-VHDLLibrary"]], "base-class": [[4, "term-base-class"]], "addfile() (pyedaa.projectmodel.fileset method)": [[18, "pyEDAA.ProjectModel.FileSet.AddFile"]], "addfileset() (pyedaa.projectmodel.fileset method)": [[18, "pyEDAA.ProjectModel.FileSet.AddFileSet"]], "addfilesets() (pyedaa.projectmodel.fileset method)": [[18, "pyEDAA.ProjectModel.FileSet.AddFileSets"]], "addfiles() (pyedaa.projectmodel.fileset method)": [[18, "pyEDAA.ProjectModel.FileSet.AddFiles"]], "attribute (class in pyedaa.projectmodel)": [[18, "pyEDAA.ProjectModel.Attribute"]], "defaultfileset (pyedaa.projectmodel.design property)": [[18, "pyEDAA.ProjectModel.Design.DefaultFileSet"]], "design (class in pyedaa.projectmodel)": [[18, "pyEDAA.ProjectModel.Design"]], "design (pyedaa.projectmodel.fileset property)": [[18, "pyEDAA.ProjectModel.FileSet.Design"]], "design (pyedaa.projectmodel.vhdllibrary property)": [[18, "pyEDAA.ProjectModel.VHDLLibrary.Design"]], "designcount (pyedaa.projectmodel.project property)": [[18, "pyEDAA.ProjectModel.Project.DesignCount"]], "directory (pyedaa.projectmodel.design property)": [[18, "pyEDAA.ProjectModel.Design.Directory"]], "directory (pyedaa.projectmodel.fileset property)": [[18, "pyEDAA.ProjectModel.FileSet.Directory"]], "filecount (pyedaa.projectmodel.fileset property)": [[18, "pyEDAA.ProjectModel.FileSet.FileCount"]], "filecount (pyedaa.projectmodel.vhdllibrary property)": [[18, "pyEDAA.ProjectModel.VHDLLibrary.FileCount"]], "fileset (class in pyedaa.projectmodel)": [[18, "pyEDAA.ProjectModel.FileSet"]], "filesetcount (pyedaa.projectmodel.design property)": [[18, "pyEDAA.ProjectModel.Design.FileSetCount"]], "filesetcount (pyedaa.projectmodel.fileset property)": [[18, "pyEDAA.ProjectModel.FileSet.FileSetCount"]], "filesets (pyedaa.projectmodel.design property)": [[18, "pyEDAA.ProjectModel.Design.FileSets"]], "filesets (pyedaa.projectmodel.fileset property)": [[18, "pyEDAA.ProjectModel.FileSet.FileSets"]], "filetype (class in pyedaa.projectmodel)": [[18, "pyEDAA.ProjectModel.FileType"]], "filetypes (pyedaa.projectmodel.filetype attribute)": [[18, "pyEDAA.ProjectModel.FileType.FileTypes"]], "files (pyedaa.projectmodel.vhdllibrary property)": [[18, "pyEDAA.ProjectModel.VHDLLibrary.Files"]], "files() (pyedaa.projectmodel.design method)": [[18, "pyEDAA.ProjectModel.Design.Files"]], "files() (pyedaa.projectmodel.fileset method)": [[18, "pyEDAA.ProjectModel.FileSet.Files"]], "humanreadablecontent (class in pyedaa.projectmodel)": [[18, "pyEDAA.ProjectModel.HumanReadableContent"]], "inicontent (class in pyedaa.projectmodel)": [[18, "pyEDAA.ProjectModel.INIContent"]], "jsoncontent (class in pyedaa.projectmodel)": [[18, "pyEDAA.ProjectModel.JSONContent"]], "name (pyedaa.projectmodel.design property)": [[18, "pyEDAA.ProjectModel.Design.Name"]], "name (pyedaa.projectmodel.fileset property)": [[18, "pyEDAA.ProjectModel.FileSet.Name"]], "name (pyedaa.projectmodel.project property)": [[18, "pyEDAA.ProjectModel.Project.Name"]], "parent (pyedaa.projectmodel.fileset property)": [[18, "pyEDAA.ProjectModel.FileSet.Parent"]], "project (class in pyedaa.projectmodel)": [[18, "pyEDAA.ProjectModel.Project"]], "project (pyedaa.projectmodel.design property)": [[18, "pyEDAA.ProjectModel.Design.Project"]], "project (pyedaa.projectmodel.fileset property)": [[18, "pyEDAA.ProjectModel.FileSet.Project"]], "project (pyedaa.projectmodel.vhdllibrary property)": [[18, "pyEDAA.ProjectModel.VHDLLibrary.Project"]], "pythoncontent (class in pyedaa.projectmodel)": [[18, "pyEDAA.ProjectModel.PythonContent"]], "resolvedpath (pyedaa.projectmodel.design property)": [[18, "pyEDAA.ProjectModel.Design.ResolvedPath"]], "resolvedpath (pyedaa.projectmodel.fileset property)": [[18, "pyEDAA.ProjectModel.FileSet.ResolvedPath"]], "resolvedpath (pyedaa.projectmodel.project property)": [[18, "pyEDAA.ProjectModel.Project.ResolvedPath"]], "rootdirectory (pyedaa.projectmodel.project property)": [[18, "pyEDAA.ProjectModel.Project.RootDirectory"]], "sdccontent (class in pyedaa.projectmodel)": [[18, "pyEDAA.ProjectModel.SDCContent"]], "svversion (pyedaa.projectmodel.fileset property)": [[18, "pyEDAA.ProjectModel.FileSet.SVVersion"]], "tclcontent (class in pyedaa.projectmodel)": [[18, "pyEDAA.ProjectModel.TCLContent"]], "tomlcontent (class in pyedaa.projectmodel)": [[18, "pyEDAA.ProjectModel.TOMLContent"]], "toplevel (pyedaa.projectmodel.design property)": [[18, "pyEDAA.ProjectModel.Design.TopLevel"]], "toplevel (pyedaa.projectmodel.fileset property)": [[18, "pyEDAA.ProjectModel.FileSet.TopLevel"]], "totalfilecount (pyedaa.projectmodel.fileset property)": [[18, "pyEDAA.ProjectModel.FileSet.TotalFileCount"]], "totalfilesetcount (pyedaa.projectmodel.design property)": [[18, "pyEDAA.ProjectModel.Design.TotalFileSetCount"]], "totalfilesetcount (pyedaa.projectmodel.fileset property)": [[18, "pyEDAA.ProjectModel.FileSet.TotalFileSetCount"]], "vhdllibrary (class in pyedaa.projectmodel)": [[18, "pyEDAA.ProjectModel.VHDLLibrary"]], "vhdllibrary (pyedaa.projectmodel.fileset property)": [[18, "pyEDAA.ProjectModel.FileSet.VHDLLibrary"]], "vhdlversion (pyedaa.projectmodel.fileset property)": [[18, "pyEDAA.ProjectModel.FileSet.VHDLVersion"]], "vhdlversion (pyedaa.projectmodel.vhdllibrary property)": [[18, "pyEDAA.ProjectModel.VHDLLibrary.VHDLVersion"]], "validate() (pyedaa.projectmodel.design method)": [[18, "pyEDAA.ProjectModel.Design.Validate"]], "validate() (pyedaa.projectmodel.fileset method)": [[18, "pyEDAA.ProjectModel.FileSet.Validate"]], "validate() (pyedaa.projectmodel.project method)": [[18, "pyEDAA.ProjectModel.Project.Validate"]], "verilogversion (pyedaa.projectmodel.fileset property)": [[18, "pyEDAA.ProjectModel.FileSet.VerilogVersion"]], "xmlcontent (class in pyedaa.projectmodel)": [[18, "pyEDAA.ProjectModel.XMLContent"]], "yamlcontent (class in pyedaa.projectmodel)": [[18, "pyEDAA.ProjectModel.YAMLContent"]], "__base__ (pyedaa.projectmodel.filetype attribute)": [[18, "pyEDAA.ProjectModel.FileType.__base__"]], "__call__() (pyedaa.projectmodel.filetype method)": [[18, "pyEDAA.ProjectModel.FileType.__call__"]], "__delattr__() (pyedaa.projectmodel.filetype method)": [[18, "pyEDAA.ProjectModel.FileType.__delattr__"]], "__delitem__() (pyedaa.projectmodel.design method)": [[18, "pyEDAA.ProjectModel.Design.__delitem__"]], "__delitem__() (pyedaa.projectmodel.fileset method)": [[18, "pyEDAA.ProjectModel.FileSet.__delitem__"]], "__delitem__() (pyedaa.projectmodel.project method)": [[18, "pyEDAA.ProjectModel.Project.__delitem__"]], "__delitem__() (pyedaa.projectmodel.vhdllibrary method)": [[18, "pyEDAA.ProjectModel.VHDLLibrary.__delitem__"]], "__dir__() (pyedaa.projectmodel.filetype method)": [[18, "pyEDAA.ProjectModel.FileType.__dir__"]], "__getattribute__() (pyedaa.projectmodel.filetype method)": [[18, "pyEDAA.ProjectModel.FileType.__getattribute__"]], "__getitem__() (pyedaa.projectmodel.design method)": [[18, "pyEDAA.ProjectModel.Design.__getitem__"]], "__getitem__() (pyedaa.projectmodel.fileset method)": [[18, "pyEDAA.ProjectModel.FileSet.__getitem__"]], "__getitem__() (pyedaa.projectmodel.project method)": [[18, "pyEDAA.ProjectModel.Project.__getitem__"]], "__getitem__() (pyedaa.projectmodel.vhdllibrary method)": [[18, "pyEDAA.ProjectModel.VHDLLibrary.__getitem__"]], "__init__() (pyedaa.projectmodel.design method)": [[18, "pyEDAA.ProjectModel.Design.__init__"]], "__init__() (pyedaa.projectmodel.fileset method)": [[18, "pyEDAA.ProjectModel.FileSet.__init__"]], "__init__() (pyedaa.projectmodel.filetype method)": [[18, "pyEDAA.ProjectModel.FileType.__init__"]], "__init__() (pyedaa.projectmodel.project method)": [[18, "pyEDAA.ProjectModel.Project.__init__"]], "__init__() (pyedaa.projectmodel.vhdllibrary method)": [[18, "pyEDAA.ProjectModel.VHDLLibrary.__init__"]], "__instancecheck__() (pyedaa.projectmodel.filetype method)": [[18, "pyEDAA.ProjectModel.FileType.__instancecheck__"]], "__len__() (pyedaa.projectmodel.design method)": [[18, "pyEDAA.ProjectModel.Design.__len__"]], "__len__() (pyedaa.projectmodel.fileset method)": [[18, "pyEDAA.ProjectModel.FileSet.__len__"]], "__len__() (pyedaa.projectmodel.project method)": [[18, "pyEDAA.ProjectModel.Project.__len__"]], "__len__() (pyedaa.projectmodel.vhdllibrary method)": [[18, "pyEDAA.ProjectModel.VHDLLibrary.__len__"]], "__new__() (pyedaa.projectmodel.filetype static method)": [[18, "pyEDAA.ProjectModel.FileType.__new__"]], "__or__() (pyedaa.projectmodel.filetype method)": [[18, "pyEDAA.ProjectModel.FileType.__or__"]], "__prepare__() (pyedaa.projectmodel.filetype class method)": [[18, "pyEDAA.ProjectModel.FileType.__prepare__"]], "__repr__() (pyedaa.projectmodel.filetype method)": [[18, "pyEDAA.ProjectModel.FileType.__repr__"]], "__ror__() (pyedaa.projectmodel.filetype method)": [[18, "pyEDAA.ProjectModel.FileType.__ror__"]], "__setattr__() (pyedaa.projectmodel.filetype method)": [[18, "pyEDAA.ProjectModel.FileType.__setattr__"]], "__setitem__() (pyedaa.projectmodel.design method)": [[18, "pyEDAA.ProjectModel.Design.__setitem__"]], "__setitem__() (pyedaa.projectmodel.fileset method)": [[18, "pyEDAA.ProjectModel.FileSet.__setitem__"]], "__setitem__() (pyedaa.projectmodel.project method)": [[18, "pyEDAA.ProjectModel.Project.__setitem__"]], "__setitem__() (pyedaa.projectmodel.vhdllibrary method)": [[18, "pyEDAA.ProjectModel.VHDLLibrary.__setitem__"]], "__sizeof__() (pyedaa.projectmodel.filetype method)": [[18, "pyEDAA.ProjectModel.FileType.__sizeof__"]], "__str__() (pyedaa.projectmodel.design method)": [[18, "pyEDAA.ProjectModel.Design.__str__"]], "__str__() (pyedaa.projectmodel.fileset method)": [[18, "pyEDAA.ProjectModel.FileSet.__str__"]], "__str__() (pyedaa.projectmodel.project method)": [[18, "pyEDAA.ProjectModel.Project.__str__"]], "__str__() (pyedaa.projectmodel.vhdllibrary method)": [[18, "pyEDAA.ProjectModel.VHDLLibrary.__str__"]], "__subclasscheck__() (pyedaa.projectmodel.filetype method)": [[18, "pyEDAA.ProjectModel.FileType.__subclasscheck__"]], "__subclasses__() (pyedaa.projectmodel.filetype method)": [[18, "pyEDAA.ProjectModel.FileType.__subclasses__"]], "__text_signature__ (pyedaa.projectmodel.filetype attribute)": [[18, "pyEDAA.ProjectModel.FileType.__text_signature__"]], "_checkforabstractmethods() (pyedaa.projectmodel.filetype class method)": [[18, "pyEDAA.ProjectModel.FileType._checkForAbstractMethods"]], "_iteratebaseclasspaths() (pyedaa.projectmodel.filetype class method)": [[18, "pyEDAA.ProjectModel.FileType._iterateBaseClassPaths"]], "_wrapnewmethodifabstract() (pyedaa.projectmodel.filetype class method)": [[18, "pyEDAA.ProjectModel.FileType._wrapNewMethodIfAbstract"]], "_wrapnewmethodifsingleton() (pyedaa.projectmodel.filetype class method)": [[18, "pyEDAA.ProjectModel.FileType._wrapNewMethodIfSingleton"]], "module": [[18, "module-pyEDAA.ProjectModel"], [19, "module-pyEDAA.ProjectModel.Altera"], [20, "module-pyEDAA.ProjectModel.Altera.Quartus"], [21, "module-pyEDAA.ProjectModel.Attributes"], [22, "module-pyEDAA.ProjectModel.GHDL"], [23, "module-pyEDAA.ProjectModel.Intel"], [24, "module-pyEDAA.ProjectModel.Intel.QuartusPrime"], [25, "module-pyEDAA.ProjectModel.MentorGraphics"], [26, "module-pyEDAA.ProjectModel.MentorGraphics.ModelSim"], [27, "module-pyEDAA.ProjectModel.MentorGraphics.QuestaSim"], [28, "module-pyEDAA.ProjectModel.OSVVM"], [29, "module-pyEDAA.ProjectModel.VHDL"], [30, "module-pyEDAA.ProjectModel.Verilog"], [31, "module-pyEDAA.ProjectModel.Xilinx"], [32, "module-pyEDAA.ProjectModel.Xilinx.ISE"], [33, "module-pyEDAA.ProjectModel.Xilinx.Vivado"]], "mro() (pyedaa.projectmodel.filetype method)": [[18, "pyEDAA.ProjectModel.FileType.mro"]], "pyedaa.projectmodel": [[18, "module-pyEDAA.ProjectModel"]], "pyedaa.projectmodel.altera": [[19, "module-pyEDAA.ProjectModel.Altera"]], "pyedaa.projectmodel.altera.quartus": [[20, "module-pyEDAA.ProjectModel.Altera.Quartus"]], "keyvalueattribute (class in pyedaa.projectmodel.attributes)": [[21, "pyEDAA.ProjectModel.Attributes.KeyValueAttribute"]], "__init__() (pyedaa.projectmodel.attributes.keyvalueattribute method)": [[21, "pyEDAA.ProjectModel.Attributes.KeyValueAttribute.__init__"]], "pyedaa.projectmodel.attributes": [[21, "module-pyEDAA.ProjectModel.Attributes"]], "pyedaa.projectmodel.ghdl": [[22, "module-pyEDAA.ProjectModel.GHDL"]], "pyedaa.projectmodel.intel": [[23, "module-pyEDAA.ProjectModel.Intel"]], "pyedaa.projectmodel.intel.quartusprime": [[24, "module-pyEDAA.ProjectModel.Intel.QuartusPrime"]], "pyedaa.projectmodel.mentorgraphics": [[25, "module-pyEDAA.ProjectModel.MentorGraphics"]], "pyedaa.projectmodel.mentorgraphics.modelsim": [[26, "module-pyEDAA.ProjectModel.MentorGraphics.ModelSim"]], "pyedaa.projectmodel.mentorgraphics.questasim": [[27, "module-pyEDAA.ProjectModel.MentorGraphics.QuestaSim"]], "pyedaa.projectmodel.osvvm": [[28, "module-pyEDAA.ProjectModel.OSVVM"]], "pyedaa.projectmodel.vhdl": [[29, "module-pyEDAA.ProjectModel.VHDL"]], "pyedaa.projectmodel.verilog": [[30, "module-pyEDAA.ProjectModel.Verilog"]], "pyedaa.projectmodel.xilinx": [[31, "module-pyEDAA.ProjectModel.Xilinx"]], "pyedaa.projectmodel.xilinx.ise": [[32, "module-pyEDAA.ProjectModel.Xilinx.ISE"]], "usedinattribute (class in pyedaa.projectmodel.xilinx.vivado)": [[33, "pyEDAA.ProjectModel.Xilinx.Vivado.UsedInAttribute"]], "pyedaa.projectmodel.xilinx.vivado": [[33, "module-pyEDAA.ProjectModel.Xilinx.Vivado"]]}}) \ No newline at end of file diff --git a/typing/html/ProjectModel/Altera/Quartus.py.html b/typing/html/ProjectModel/Altera/Quartus.py.html new file mode 100644 index 00000000..f1b492ae --- /dev/null +++ b/typing/html/ProjectModel/Altera/Quartus.py.html @@ -0,0 +1,106 @@ + + + + + + +

ProjectModel.Altera.Quartus

+ + + + + + +
ProjectModel/Altera/Quartus.py
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+
# ==================================================================================================================== #
+#               _____ ____    _        _      ____            _           _   __  __           _      _                #
+#   _ __  _   _| ____|  _ \  / \      / \    |  _ \ _ __ ___ (_) ___  ___| |_|  \/  | ___   __| | ___| |               #
+#  | '_ \| | | |  _| | | | |/ _ \    / _ \   | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ |               #
+#  | |_) | |_| | |___| |_| / ___ \  / ___ \ _|  __/| | | (_) | |  __/ (__| |_| |  | | (_) | (_| |  __/ |               #
+#  | .__/ \__, |_____|____/_/   \_\/_/   \_(_)_|   |_|  \___// |\___|\___|\__|_|  |_|\___/ \__,_|\___|_|               #
+#  |_|    |___/                                            |__/                                                        #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany                                                            #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""Specific file types and attributes for Altera Quartus."""
+from pyTooling.Decorators import export
+
+from pyEDAA.ProjectModel import ConstraintFile, ProjectFile, SDCContent, TCLContent
+
+
+@export
+class QuartusProjectFile(ProjectFile, TCLContent):
+	"""A Quartus project file (``*.qpf``)."""
+
+
+@export
+class SDCConstraintFile(ConstraintFile, SDCContent):
+	"""A Quartus constraint file (Synopsys Design Constraints; ``*.sdc``)."""
+
+ + diff --git a/typing/html/ProjectModel/Altera/__init__.py.html b/typing/html/ProjectModel/Altera/__init__.py.html new file mode 100644 index 00000000..59fb7972 --- /dev/null +++ b/typing/html/ProjectModel/Altera/__init__.py.html @@ -0,0 +1,78 @@ + + + + + + +

ProjectModel.Altera

+ + + + + + +
ProjectModel/Altera/__init__.py
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+
# ==================================================================================================================== #
+#               _____ ____    _        _      ____            _           _   __  __           _      _                #
+#   _ __  _   _| ____|  _ \  / \      / \    |  _ \ _ __ ___ (_) ___  ___| |_|  \/  | ___   __| | ___| |               #
+#  | '_ \| | | |  _| | | | |/ _ \    / _ \   | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ |               #
+#  | |_) | |_| | |___| |_| / ___ \  / ___ \ _|  __/| | | (_) | |  __/ (__| |_| |  | | (_) | (_| |  __/ |               #
+#  | .__/ \__, |_____|____/_/   \_\/_/   \_(_)_|   |_|  \___// |\___|\___|\__|_|  |_|\___/ \__,_|\___|_|               #
+#  |_|    |___/                                            |__/                                                        #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany                                                            #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""A vendor specific package for Altera (now Intel FPGA)."""
+
+ + diff --git a/typing/html/ProjectModel/Attributes.py.html b/typing/html/ProjectModel/Attributes.py.html new file mode 100644 index 00000000..663c9e3f --- /dev/null +++ b/typing/html/ProjectModel/Attributes.py.html @@ -0,0 +1,125 @@ + + + + + + +

ProjectModel.Attributes

+ + + + + + +
ProjectModel/Attributes.py
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+
# ==================================================================================================================== #
+#               _____ ____    _        _      ____            _           _   __  __           _      _                #
+#   _ __  _   _| ____|  _ \  / \      / \    |  _ \ _ __ ___ (_) ___  ___| |_|  \/  | ___   __| | ___| |               #
+#  | '_ \| | | |  _| | | | |/ _ \    / _ \   | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ |               #
+#  | |_) | |_| | |___| |_| / ___ \  / ___ \ _|  __/| | | (_) | |  __/ (__| |_| |  | | (_) | (_| |  __/ |               #
+#  | .__/ \__, |_____|____/_/   \_\/_/   \_(_)_|   |_|  \___// |\___|\___|\__|_|  |_|\___/ \__,_|\___|_|               #
+#  |_|    |___/                                            |__/                                                        #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany                                                            #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""A set of common attributes to store meta information on ProjectModel entities (project, design, fileset, file, ...)."""
+from typing               import Dict
+from pyTooling.Decorators import export
+
+from pyEDAA.ProjectModel  import Attribute
+
+
+@export
+class KeyValueAttribute(Attribute):
+	KEY = "ID"
+
+	_keyValuePairs: Dict[str, str]
+
+	def __init__(self):
+		super().__init__()
+
+		self._keyValuePairs = {}
+
+	def __getitem__(self, item: str) -> str:
+		return self._keyValuePairs[item]
+
+	def __setitem__(self, key: str, value: str) -> None:
+		self._keyValuePairs[key] = value
+
+ + diff --git a/typing/html/ProjectModel/GHDL.py.html b/typing/html/ProjectModel/GHDL.py.html new file mode 100644 index 00000000..745543a7 --- /dev/null +++ b/typing/html/ProjectModel/GHDL.py.html @@ -0,0 +1,95 @@ + + + + + + +

ProjectModel.GHDL

+ + + + + + +
ProjectModel/GHDL.py
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+
# ==================================================================================================================== #
+#               _____ ____    _        _      ____            _           _   __  __           _      _                #
+#   _ __  _   _| ____|  _ \  / \      / \    |  _ \ _ __ ___ (_) ___  ___| |_|  \/  | ___   __| | ___| |               #
+#  | '_ \| | | |  _| | | | |/ _ \    / _ \   | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ |               #
+#  | |_) | |_| | |___| |_| / ___ \  / ___ \ _|  __/| | | (_) | |  __/ (__| |_| |  | | (_) | (_| |  __/ |               #
+#  | .__/ \__, |_____|____/_/   \_\/_/   \_(_)_|   |_|  \___// |\___|\___|\__|_|  |_|\___/ \__,_|\___|_|               #
+#  |_|    |___/                                            |__/                                                        #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany                                                            #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""Specific file types and attributes for `GHDL <https://github.com/ghdl>`__."""
+from pyTooling.Decorators import export
+
+from pyEDAA.ProjectModel import WaveformExchangeFile
+
+
+@export
+class GHDLWaveformFile(WaveformExchangeFile):
+	"""GHDL's waveform file (``*.ghw``) supporting VHDL and Verilog simulation results."""
+
+ + diff --git a/typing/html/ProjectModel/Intel/QuartusPrime.py.html b/typing/html/ProjectModel/Intel/QuartusPrime.py.html new file mode 100644 index 00000000..5ad7d97c --- /dev/null +++ b/typing/html/ProjectModel/Intel/QuartusPrime.py.html @@ -0,0 +1,106 @@ + + + + + + +

ProjectModel.Intel.QuartusPrime

+ + + + + + +
ProjectModel/Intel/QuartusPrime.py
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+
# ==================================================================================================================== #
+#               _____ ____    _        _      ____            _           _   __  __           _      _                #
+#   _ __  _   _| ____|  _ \  / \      / \    |  _ \ _ __ ___ (_) ___  ___| |_|  \/  | ___   __| | ___| |               #
+#  | '_ \| | | |  _| | | | |/ _ \    / _ \   | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ |               #
+#  | |_) | |_| | |___| |_| / ___ \  / ___ \ _|  __/| | | (_) | |  __/ (__| |_| |  | | (_) | (_| |  __/ |               #
+#  | .__/ \__, |_____|____/_/   \_\/_/   \_(_)_|   |_|  \___// |\___|\___|\__|_|  |_|\___/ \__,_|\___|_|               #
+#  |_|    |___/                                            |__/                                                        #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany                                                            #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""Specific file types and attributes for Intel FPGA Quartus Prime."""
+from pyTooling.Decorators import export
+
+from pyEDAA.ProjectModel import ConstraintFile, ProjectFile, SDCContent, TCLContent
+
+
+@export
+class QuartusProjectFile(ProjectFile, TCLContent):
+	"""A Quartus project file (``*.qpf``)."""
+
+
+@export
+class SDCConstraintFile(ConstraintFile, SDCContent):
+	"""A Quartus constraint file (Synopsys Design Constraints; ``*.sdc``)."""
+
+ + diff --git a/typing/html/ProjectModel/Intel/__init__.py.html b/typing/html/ProjectModel/Intel/__init__.py.html new file mode 100644 index 00000000..96b47437 --- /dev/null +++ b/typing/html/ProjectModel/Intel/__init__.py.html @@ -0,0 +1,78 @@ + + + + + + +

ProjectModel.Intel

+ + + + + + +
ProjectModel/Intel/__init__.py
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+
# ==================================================================================================================== #
+#               _____ ____    _        _      ____            _           _   __  __           _      _                #
+#   _ __  _   _| ____|  _ \  / \      / \    |  _ \ _ __ ___ (_) ___  ___| |_|  \/  | ___   __| | ___| |               #
+#  | '_ \| | | |  _| | | | |/ _ \    / _ \   | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ |               #
+#  | |_) | |_| | |___| |_| / ___ \  / ___ \ _|  __/| | | (_) | |  __/ (__| |_| |  | | (_) | (_| |  __/ |               #
+#  | .__/ \__, |_____|____/_/   \_\/_/   \_(_)_|   |_|  \___// |\___|\___|\__|_|  |_|\___/ \__,_|\___|_|               #
+#  |_|    |___/                                            |__/                                                        #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany                                                            #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""A vendor specific package for Intel FPGA (formerly Altera)."""
+
+ + diff --git a/typing/html/ProjectModel/MentorGraphics/ModelSim.py.html b/typing/html/ProjectModel/MentorGraphics/ModelSim.py.html new file mode 100644 index 00000000..a554726b --- /dev/null +++ b/typing/html/ProjectModel/MentorGraphics/ModelSim.py.html @@ -0,0 +1,117 @@ + + + + + + +

ProjectModel.MentorGraphics.ModelSim

+ + + + + + +
ProjectModel/MentorGraphics/ModelSim.py
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+
# ==================================================================================================================== #
+#               _____ ____    _        _      ____            _           _   __  __           _      _                #
+#   _ __  _   _| ____|  _ \  / \      / \    |  _ \ _ __ ___ (_) ___  ___| |_|  \/  | ___   __| | ___| |               #
+#  | '_ \| | | |  _| | | | |/ _ \    / _ \   | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ |               #
+#  | |_) | |_| | |___| |_| / ___ \  / ___ \ _|  __/| | | (_) | |  __/ (__| |_| |  | | (_) | (_| |  __/ |               #
+#  | .__/ \__, |_____|____/_/   \_\/_/   \_(_)_|   |_|  \___// |\___|\___|\__|_|  |_|\___/ \__,_|\___|_|               #
+#  |_|    |___/                                            |__/                                                        #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany                                                            #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""Specific file types and attributes for Mentor Graphics ModelSim."""
+from pyTooling.Decorators import export
+
+from pyEDAA.ProjectModel import ProjectFile, SettingFile, INIContent, WaveformConfigFile, TCLContent
+
+
+@export
+class ModelSimProjectFile(ProjectFile):
+	pass
+
+
+@export
+class ModelSimINIFile(SettingFile, INIContent):
+	pass
+
+
+@export
+class WaveDoFile(WaveformConfigFile, TCLContent):
+	pass
+
+ + diff --git a/typing/html/ProjectModel/MentorGraphics/QuestaSim.py.html b/typing/html/ProjectModel/MentorGraphics/QuestaSim.py.html new file mode 100644 index 00000000..b0921474 --- /dev/null +++ b/typing/html/ProjectModel/MentorGraphics/QuestaSim.py.html @@ -0,0 +1,117 @@ + + + + + + +

ProjectModel.MentorGraphics.QuestaSim

+ + + + + + +
ProjectModel/MentorGraphics/QuestaSim.py
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+
# ==================================================================================================================== #
+#               _____ ____    _        _      ____            _           _   __  __           _      _                #
+#   _ __  _   _| ____|  _ \  / \      / \    |  _ \ _ __ ___ (_) ___  ___| |_|  \/  | ___   __| | ___| |               #
+#  | '_ \| | | |  _| | | | |/ _ \    / _ \   | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ |               #
+#  | |_) | |_| | |___| |_| / ___ \  / ___ \ _|  __/| | | (_) | |  __/ (__| |_| |  | | (_) | (_| |  __/ |               #
+#  | .__/ \__, |_____|____/_/   \_\/_/   \_(_)_|   |_|  \___// |\___|\___|\__|_|  |_|\___/ \__,_|\___|_|               #
+#  |_|    |___/                                            |__/                                                        #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany                                                            #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""Specific file types and attributes for Mentor Graphics QuestaSim."""
+from pyTooling.Decorators import export
+
+from pyEDAA.ProjectModel import ProjectFile, SettingFile, INIContent, WaveformConfigFile, TCLContent
+
+
+@export
+class ModelSimProjectFile(ProjectFile):
+	pass
+
+
+@export
+class ModelSimINIFile(SettingFile, INIContent):
+	pass
+
+
+@export
+class WaveDoFile(WaveformConfigFile, TCLContent):
+	pass
+
+ + diff --git a/typing/html/ProjectModel/MentorGraphics/__init__.py.html b/typing/html/ProjectModel/MentorGraphics/__init__.py.html new file mode 100644 index 00000000..f22a8021 --- /dev/null +++ b/typing/html/ProjectModel/MentorGraphics/__init__.py.html @@ -0,0 +1,78 @@ + + + + + + +

ProjectModel.MentorGraphics

+ + + + + + +
ProjectModel/MentorGraphics/__init__.py
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+
# ==================================================================================================================== #
+#               _____ ____    _        _      ____            _           _   __  __           _      _                #
+#   _ __  _   _| ____|  _ \  / \      / \    |  _ \ _ __ ___ (_) ___  ___| |_|  \/  | ___   __| | ___| |               #
+#  | '_ \| | | |  _| | | | |/ _ \    / _ \   | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ |               #
+#  | |_) | |_| | |___| |_| / ___ \  / ___ \ _|  __/| | | (_) | |  __/ (__| |_| |  | | (_) | (_| |  __/ |               #
+#  | .__/ \__, |_____|____/_/   \_\/_/   \_(_)_|   |_|  \___// |\___|\___|\__|_|  |_|\___/ \__,_|\___|_|               #
+#  |_|    |___/                                            |__/                                                        #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany                                                            #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""A vendor specific package for Mentor Graphics (now Siemens EDA)."""
+
+ + diff --git a/typing/html/ProjectModel/OSVVM.py.html b/typing/html/ProjectModel/OSVVM.py.html new file mode 100644 index 00000000..3475c334 --- /dev/null +++ b/typing/html/ProjectModel/OSVVM.py.html @@ -0,0 +1,482 @@ + + + + + + +

ProjectModel.OSVVM

+ + + + + + +
ProjectModel/OSVVM.py
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+
# ==================================================================================================================== #
+#               _____ ____    _        _      ____            _           _   __  __           _      _                #
+#   _ __  _   _| ____|  _ \  / \      / \    |  _ \ _ __ ___ (_) ___  ___| |_|  \/  | ___   __| | ___| |               #
+#  | '_ \| | | |  _| | | | |/ _ \    / _ \   | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ |               #
+#  | |_) | |_| | |___| |_| / ___ \  / ___ \ _|  __/| | | (_) | |  __/ (__| |_| |  | | (_) | (_| |  __/ |               #
+#  | .__/ \__, |_____|____/_/   \_\/_/   \_(_)_|   |_|  \___// |\___|\___|\__|_|  |_|\___/ \__,_|\___|_|               #
+#  |_|    |___/                                            |__/                                                        #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany                                                            #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""Specific file types and attributes for `OSVVM <https://github.com/OSVVM>`__."""
+from pathlib import Path
+
+from pyTooling.Decorators import export
+from typing import Optional as Nullable, List
+
+from pyEDAA.ProjectModel import ProjectFile, TCLContent, Project, Design, FileSet, VHDLLibrary, VHDLSourceFile
+
+
+@export
+class OSVVMProjectFile(ProjectFile, TCLContent):
+	"""An OSVVM project file (``*.pro``)."""
+
+	_osvvmProject: Nullable[Project]
+
+	def __init__(
+		self,
+		path: Path,
+		project: Project = None,
+		design: Design = None,
+		fileSet: FileSet = None
+	):
+		super().__init__(path, project, design, fileSet)
+
+		self._osvvmProject = None
+
+	@property
+	def ProjectModel(self) -> Project:
+		return self._osvvmProject
+
+	class Instruction:
+		_line: int
+
+		def __init__(self, line: int):
+			self._line = line
+
+	class Empty(Instruction):
+		def __init__(self, line: int):
+			super().__init__(line)
+
+	class Comment(Instruction):
+		_commentText: str
+
+		def __init__(self, line: int, commentText: str):
+			super().__init__(line)
+			self._commentText = commentText.rstrip()
+
+		@property
+		def CommentText(self) -> str:
+			return self._commentText
+
+	class Analyze(Instruction):
+		_vhdlSourceFile: VHDLSourceFile
+
+		def __init__(self, line: int, parameterText: str):
+			super().__init__(line)
+			self._vhdlSourceFile = VHDLSourceFile(Path(parameterText.strip()))
+
+		@property
+		def VHDLSourceFile(self) -> VHDLSourceFile:
+			return self._vhdlSourceFile
+
+	class Library(Instruction):
+		_vhdlLibrary: VHDLLibrary
+
+		def __init__(self, line: int, parameterText: str):
+			super().__init__(line)
+			self._vhdlLibrary = VHDLLibrary(parameterText.strip())
+
+		@property
+		def VHDLLibrary(self) -> VHDLLibrary:
+			return self._vhdlLibrary
+
+	class Include(Instruction):
+		_osvvmProjectFile: 'OSVVMProjectFile'
+		_fileSet:          FileSet
+
+		def __init__(self, line: int, workingDirectory: Path, parameterText: str):
+			super().__init__(line)
+
+			includeFile = Path(parameterText.strip())
+			includePath = (workingDirectory / includeFile).resolve()
+
+			self._fileSet = FileSet(includeFile.name, directory=includeFile.parent)
+			self._osvvmProjectFile = OSVVMProjectFile(includePath)
+
+		@property
+		def OSVVMProjectFile(self) -> 'OSVVMProjectFile':
+			return self._osvvmProjectFile
+
+		def Parse(self, fileSet: FileSet):
+			self._fileSet.Parent = fileSet
+
+			for instruction in self._osvvmProjectFile._Parse():
+				if isinstance(instruction, OSVVMProjectFile.Include):
+					instruction.Parse(self._fileSet)
+				elif isinstance(instruction, OSVVMProjectFile.Analyze):
+					self._fileSet.AddFile(instruction.VHDLSourceFile)
+				elif isinstance(instruction, OSVVMProjectFile.Library):
+					self._fileSet.Design.AddVHDLLibrary(instruction.VHDLLibrary)
+#				elif isinstance(instruction, OSVVMProjectFile.Build):
+
+				elif not isinstance(instruction, (OSVVMProjectFile.Empty, OSVVMProjectFile.Comment)):
+					raise Exception(f"Unknown instruction '{instruction.__class__.__name__}' in OSVVM project file '{self._osvvmProjectFile.ResolvedPath}'")
+
+	def Parse(self):
+		projectName = self._path.name
+		self._osvvmProject = Project(projectName, rootDirectory=self._path.parent)
+
+		fileSet = self._osvvmProject.DefaultDesign.DefaultFileSet
+
+		for instruction in self._Parse():
+			if isinstance(instruction, OSVVMProjectFile.Include):
+				instruction.Parse(fileSet)
+			elif isinstance(instruction, OSVVMProjectFile.Analyze):
+				fileSet.AddFile(instruction.VHDLSourceFile)
+			elif not isinstance(instruction, (OSVVMProjectFile.Empty, OSVVMProjectFile.Comment)):
+				raise Exception(f"Unknown instruction '{instruction.__class__.__name__}' in OSVVM project file '{self.ResolvedPath}'")
+
+	def _Parse(self):
+		path = self.ResolvedPath
+		if not path.exists():
+			raise Exception(f"OSVVM project file '{path}' not found.") from FileNotFoundError(f"File '{path}' not found.")
+
+		instructions: List = []
+		print()
+		with path.open("r") as file:
+			i = 1
+			for line in file:
+				line = line.lstrip()
+
+				if line.startswith("#"):
+					comment = OSVVMProjectFile.Comment(i, line[1:])
+					instructions.append(comment)
+
+				elif line.startswith("analyze"):
+					vhdlFile = OSVVMProjectFile.Analyze(i, line[8:])
+					instructions.append(vhdlFile)
+
+				elif line.startswith("library"):
+					vhdlLibrary = OSVVMProjectFile.Library(i, line[8:])
+					instructions.append(vhdlLibrary)
+
+				elif line.startswith("include"):
+					include = OSVVMProjectFile.Include(i, path.parent, line[8:])
+					instructions.append(include)
+
+				elif line.startswith("build"):
+					parameter = line[6:]
+					print(f"BUILD: {parameter}")
+				elif line.startswith("if"):
+					print(f"IF (line={i}): {line[3:].rstrip()}")
+				elif line.startswith("}"):
+					print(f"}} (line={i}): {line[2:].rstrip()}")
+				elif len(line) == 0:
+					instructions.append(OSVVMProjectFile.Empty(i))
+				else:
+					print(f"UNKNOWN (line={i}): '{line.rstrip()}'")
+
+				i += 1
+
+		return instructions
+
+ + diff --git a/typing/html/ProjectModel/VHDL.py.html b/typing/html/ProjectModel/VHDL.py.html new file mode 100644 index 00000000..4cb8715d --- /dev/null +++ b/typing/html/ProjectModel/VHDL.py.html @@ -0,0 +1,16 @@ + + + + + + +

ProjectModel.VHDL

+ + + + + + +
ProjectModel/VHDL.py
+ + diff --git a/typing/html/ProjectModel/Verilog.py.html b/typing/html/ProjectModel/Verilog.py.html new file mode 100644 index 00000000..6685f71d --- /dev/null +++ b/typing/html/ProjectModel/Verilog.py.html @@ -0,0 +1,95 @@ + + + + + + +

ProjectModel.Verilog

+ + + + + + +
ProjectModel/Verilog.py
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+
# ==================================================================================================================== #
+#               _____ ____    _        _      ____            _           _   __  __           _      _                #
+#   _ __  _   _| ____|  _ \  / \      / \    |  _ \ _ __ ___ (_) ___  ___| |_|  \/  | ___   __| | ___| |               #
+#  | '_ \| | | |  _| | | | |/ _ \    / _ \   | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ |               #
+#  | |_) | |_| | |___| |_| / ___ \  / ___ \ _|  __/| | | (_) | |  __/ (__| |_| |  | | (_) | (_| |  __/ |               #
+#  | .__/ \__, |_____|____/_/   \_\/_/   \_(_)_|   |_|  \___// |\___|\___|\__|_|  |_|\___/ \__,_|\___|_|               #
+#  |_|    |___/                                            |__/                                                        #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany                                                            #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""Specific file types and attributes for Verilog."""
+from pyTooling.Decorators import export
+
+from pyEDAA.ProjectModel import WaveformExchangeFile
+
+
+@export
+class ValueChangeDumpFile(WaveformExchangeFile):
+	"""Verilog's waveform file (``*.vcd``) for exchanging value changes as defined by IEEE Std. 1364."""
+
+ + diff --git a/typing/html/ProjectModel/Xilinx/ISE.py.html b/typing/html/ProjectModel/Xilinx/ISE.py.html new file mode 100644 index 00000000..90382f24 --- /dev/null +++ b/typing/html/ProjectModel/Xilinx/ISE.py.html @@ -0,0 +1,106 @@ + + + + + + +

ProjectModel.Xilinx.ISE

+ + + + + + +
ProjectModel/Xilinx/ISE.py
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+
# ==================================================================================================================== #
+#               _____ ____    _        _      ____            _           _   __  __           _      _                #
+#   _ __  _   _| ____|  _ \  / \      / \    |  _ \ _ __ ___ (_) ___  ___| |_|  \/  | ___   __| | ___| |               #
+#  | '_ \| | | |  _| | | | |/ _ \    / _ \   | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ |               #
+#  | |_) | |_| | |___| |_| / ___ \  / ___ \ _|  __/| | | (_) | |  __/ (__| |_| |  | | (_) | (_| |  __/ |               #
+#  | .__/ \__, |_____|____/_/   \_\/_/   \_(_)_|   |_|  \___// |\___|\___|\__|_|  |_|\___/ \__,_|\___|_|               #
+#  |_|    |___/                                            |__/                                                        #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany                                                            #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""Specific file types and attributes for Xilinx ISE."""
+from pyTooling.Decorators import export
+
+from pyEDAA.ProjectModel import ConstraintFile, ProjectFile, HumanReadableContent
+
+
+@export
+class ISEProjectFile(ProjectFile):
+	pass
+
+
+@export
+class UCFConstraintFile(ConstraintFile, HumanReadableContent):
+	pass
+
+ + diff --git a/typing/html/ProjectModel/Xilinx/Vivado.py.html b/typing/html/ProjectModel/Xilinx/Vivado.py.html new file mode 100644 index 00000000..96906608 --- /dev/null +++ b/typing/html/ProjectModel/Xilinx/Vivado.py.html @@ -0,0 +1,506 @@ + + + + + + +

ProjectModel.Xilinx.Vivado

+ + + + + + +
ProjectModel/Xilinx/Vivado.py
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+
# ==================================================================================================================== #
+#               _____ ____    _        _      ____            _           _   __  __           _      _                #
+#   _ __  _   _| ____|  _ \  / \      / \    |  _ \ _ __ ___ (_) ___  ___| |_|  \/  | ___   __| | ___| |               #
+#  | '_ \| | | |  _| | | | |/ _ \    / _ \   | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ |               #
+#  | |_) | |_| | |___| |_| / ___ \  / ___ \ _|  __/| | | (_) | |  __/ (__| |_| |  | | (_) | (_| |  __/ |               #
+#  | .__/ \__, |_____|____/_/   \_\/_/   \_(_)_|   |_|  \___// |\___|\___|\__|_|  |_|\___/ \__,_|\___|_|               #
+#  |_|    |___/                                            |__/                                                        #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany                                                            #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""Specific file types and attributes for Xilinx Vivado."""
+from pathlib import Path
+from typing import Iterable
+
+from xml.dom import minidom, Node
+
+from pyTooling.MetaClasses import ExtendedType
+from pyVHDLModel import VHDLVersion
+from pyTooling.Decorators import export
+
+from pyEDAA.ProjectModel import ProjectFile, XMLFile, XMLContent, SDCContent, Project, FileSet, Attribute, Design
+from pyEDAA.ProjectModel import File as Model_File
+from pyEDAA.ProjectModel import ConstraintFile as Model_ConstraintFile
+from pyEDAA.ProjectModel import VerilogSourceFile as Model_VerilogSourceFile
+from pyEDAA.ProjectModel import VHDLSourceFile as Model_VHDLSourceFile
+
+
+@export
+class UsedInAttribute(Attribute):
+	KEY = "UsedIn"
+	VALUE_TYPE = Iterable[str]
+
+
+@export
+class File(Model_File):
+	pass
+
+
+class VivadoFileMixIn(metaclass=ExtendedType, mixin=True):
+	def _registerAttributes(self):
+		self._attributes[UsedInAttribute] = []
+
+
+@export
+class ConstraintFile(Model_ConstraintFile, VivadoFileMixIn):
+	def _registerAttributes(self):
+		super()._registerAttributes()
+		VivadoFileMixIn._registerAttributes(self)
+
+
+@export
+class VerilogSourceFile(Model_VerilogSourceFile):
+	def _registerAttributes(self):
+		super()._registerAttributes()
+		VivadoFileMixIn._registerAttributes(self)
+
+
+@export
+class VHDLSourceFile(Model_VHDLSourceFile):
+	def _registerAttributes(self):
+		super()._registerAttributes()
+		VivadoFileMixIn._registerAttributes(self)
+
+
+@export
+class VivadoProjectFile(ProjectFile, XMLContent):
+	"""A Vivado project file (``*.xpr``)."""
+
+	_xprProject: Project
+
+	def __init__(
+		self,
+		path: Path,
+		project: Project = None,
+		design: Design = None,
+		fileSet: FileSet = None
+	):
+		super().__init__(path, project, design, fileSet)
+
+		self._xprProject = None
+
+	@property
+	def ProjectModel(self) -> Project:
+		return self._xprProject
+
+	def Parse(self):
+		if not self._path.exists():
+			raise Exception(f"Vivado project file '{self._path!s}' not found.") from FileNotFoundError(f"File '{self._path!s}' not found.")
+
+		try:
+			root = minidom.parse(str(self._path)).documentElement
+		except Exception as ex:
+			raise Exception(f"Couldn't open '{self._path!s}'.") from ex
+
+		self._xprProject = Project(self._path.stem, rootDirectory=self._path.parent)
+		self._ParseRootElement(root)
+
+	def _ParseRootElement(self, root):
+		for rootNode in root.childNodes:
+			if rootNode.nodeName == "FileSets":
+				self._ParseFileSets(rootNode)
+				break
+
+	def _ParseFileSets(self, filesetsNode):
+		for fileSetsNode in filesetsNode.childNodes:
+			if fileSetsNode.nodeType == Node.ELEMENT_NODE and fileSetsNode.tagName == "FileSet":
+				self._ParseFileSet(fileSetsNode)
+
+	def _ParseFileSet(self, filesetNode):
+		filesetName = filesetNode.getAttribute("Name")
+		fileset = FileSet(filesetName, design=self._xprProject.DefaultDesign)
+
+		for fileNode in filesetNode.childNodes:
+			if fileNode.nodeType == Node.ELEMENT_NODE:
+				if fileNode.tagName == "File":
+					self._ParseFile(fileNode, fileset)
+				elif fileNode.nodeType == Node.ELEMENT_NODE and fileNode.tagName == "Config":
+					self._ParseFileSetConfig(fileNode, fileset)
+
+	def _ParseFile(self, fileNode, fileset):
+		croppedPath = fileNode.getAttribute("Path").replace("$PPRDIR/", "")
+		filePath = Path(croppedPath)
+		if filePath.suffix in (".vhd", ".vhdl"):
+			self._ParseVHDLFile(fileNode, filePath, fileset)
+		elif filePath.suffix == ".xdc":
+			self._ParseXDCFile(fileNode, filePath, fileset)
+		elif filePath.suffix == ".v":
+			self._ParseVerilogFile(fileNode, filePath, fileset)
+		elif filePath.suffix == ".xci":
+			self._ParseXCIFile(fileNode, filePath, fileset)
+		else:
+			self._ParseDefaultFile(fileNode, filePath, fileset)
+
+	def _ParseVHDLFile(self, fileNode, path, fileset):
+		vhdlFile = VHDLSourceFile(path)
+		fileset.AddFile(vhdlFile)
+		usedInAttr = vhdlFile[UsedInAttribute]
+
+		for childNode in fileNode.childNodes:
+			if childNode.nodeType == Node.ELEMENT_NODE and childNode.tagName == "FileInfo":
+				if childNode.getAttribute("SFType") == "VHDL2008":
+					vhdlFile.VHDLVersion = VHDLVersion.VHDL2008
+				else:
+					vhdlFile.VHDLVersion = VHDLVersion.VHDL93
+
+				for fileAttribute in childNode.childNodes:
+					if fileAttribute.nodeType == Node.ELEMENT_NODE and fileAttribute.tagName == "Attr":
+						if fileAttribute.getAttribute("Name") == "Library":
+							libraryName = fileAttribute.getAttribute("Val")
+							vhdlFile.VHDLLibrary = fileset.GetOrCreateVHDLLibrary(libraryName)
+						elif fileAttribute.getAttribute("Val") == "UsedIn":
+							usedInAttr.append(fileAttribute.getAttribute("Val"))
+
+	def _ParseDefaultFile(self, _, path, fileset):
+		File(path, fileSet=fileset)
+
+	def _ParseXDCFile(self, _, path, fileset):
+		XDCConstraintFile(path, fileSet=fileset)
+
+	def _ParseVerilogFile(self, _, path, fileset):
+		VerilogSourceFile(path, fileSet=fileset)
+
+	def _ParseXCIFile(self, _, path, fileset):
+		IPCoreInstantiationFile(path, fileSet=fileset)
+
+	def _ParseFileSetConfig(self, fileNode, fileset):
+		for option in fileNode.childNodes:
+			if option.nodeType == Node.ELEMENT_NODE and option.tagName == "Option":
+				if option.getAttribute("Name") == "TopModule":
+					fileset.TopLevel = option.getAttribute("Val")
+
+
+@export
+class XDCConstraintFile(ConstraintFile, SDCContent):
+	"""A Vivado constraint file (Xilinx Design Constraints; ``*.xdc``)."""
+
+
+@export
+class IPCoreDescriptionFile(XMLFile):
+	pass
+
+
+@export
+class IPCoreInstantiationFile(XMLFile):
+	"""A Vivado IP core instantiation file (Xilinx IPCore Instance; ``*.xci``)."""
+
+ + diff --git a/typing/html/ProjectModel/Xilinx/__init__.py.html b/typing/html/ProjectModel/Xilinx/__init__.py.html new file mode 100644 index 00000000..8cb7b4a8 --- /dev/null +++ b/typing/html/ProjectModel/Xilinx/__init__.py.html @@ -0,0 +1,78 @@ + + + + + + +

ProjectModel.Xilinx

+ + + + + + +
ProjectModel/Xilinx/__init__.py
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+
# ==================================================================================================================== #
+#               _____ ____    _        _      ____            _           _   __  __           _      _                #
+#   _ __  _   _| ____|  _ \  / \      / \    |  _ \ _ __ ___ (_) ___  ___| |_|  \/  | ___   __| | ___| |               #
+#  | '_ \| | | |  _| | | | |/ _ \    / _ \   | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ |               #
+#  | |_) | |_| | |___| |_| / ___ \  / ___ \ _|  __/| | | (_) | |  __/ (__| |_| |  | | (_) | (_| |  __/ |               #
+#  | .__/ \__, |_____|____/_/   \_\/_/   \_(_)_|   |_|  \___// |\___|\___|\__|_|  |_|\___/ \__,_|\___|_|               #
+#  |_|    |___/                                            |__/                                                        #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany                                                            #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""A vendor specific package for Xilinx."""
+
+ + diff --git a/typing/html/ProjectModel/__init__.py.html b/typing/html/ProjectModel/__init__.py.html new file mode 100644 index 00000000..68b5bc53 --- /dev/null +++ b/typing/html/ProjectModel/__init__.py.html @@ -0,0 +1,4012 @@ + + + + + + +

ProjectModel

+ + + + + + +
ProjectModel/__init__.py
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+
# ==================================================================================================================== #
+#               _____ ____    _        _      ____            _           _   __  __           _      _                #
+#   _ __  _   _| ____|  _ \  / \      / \    |  _ \ _ __ ___ (_) ___  ___| |_|  \/  | ___   __| | ___| |               #
+#  | '_ \| | | |  _| | | | |/ _ \    / _ \   | |_) | '__/ _ \| |/ _ \/ __| __| |\/| |/ _ \ / _` |/ _ \ |               #
+#  | |_) | |_| | |___| |_| / ___ \  / ___ \ _|  __/| | | (_) | |  __/ (__| |_| |  | | (_) | (_| |  __/ |               #
+#  | .__/ \__, |_____|____/_/   \_\/_/   \_(_)_|   |_|  \___// |\___|\___|\__|_|  |_|\___/ \__,_|\___|_|               #
+#  |_|    |___/                                            |__/                                                        #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany                                                            #
+# Copyright 2014-2016 Technische Universität Dresden - Germany, Chair of VLSI-Design, Diagnostics and Architecture     #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""An abstract model of EDA tool projects."""
+__author__ =    "Patrick Lehmann"
+__email__ =     "Paebbels@gmail.com"
+__copyright__ = "2014-2023, Patrick Lehmann, Unai Martinez-Corral"
+__license__ =   "Apache License, Version 2.0"
+__version__ =   "0.5.0"
+__keywords__ =  ["eda project", "model", "abstract", "xilinx", "vivado", "osvvm", "file set", "file group", "test bench", "test harness"]
+
+from os.path import relpath as path_relpath
+from pathlib import Path as pathlib_Path
+from typing  import Dict, Union, Optional as Nullable, List, Iterable, Generator, Tuple, Any as typing_Any, Type, Set, Any
+
+from pyTooling.Decorators  import export
+from pyTooling.MetaClasses import ExtendedType
+from pyTooling.Graph       import Graph, Vertex
+from pySVModel             import SystemVerilogVersion
+from pyVHDLModel           import VHDLVersion
+from pySystemRDLModel      import SystemRDLVersion
+
+
+@export
+class Attribute(metaclass=ExtendedType):
+	KEY: str
+	VALUE_TYPE: typing_Any
+
+	@staticmethod
+	def resolve(obj: typing_Any, key: Type['Attribute']):
+		if isinstance(obj, File):
+			return obj._fileSet[key]
+		elif isinstance(obj, FileSet):
+			return obj._design[key]
+		elif isinstance(obj, Design):
+			return obj._project[key]
+		else:
+			raise Exception("Resolution error")
+
+
+@export
+class FileType(ExtendedType):
+	"""
+	A :term:`meta-class` to construct *FileType* classes.
+
+	Modifications done by this meta-class:
+	* Register all classes of type :class:`FileType` or derived variants in a class field :attr:`FileType.FileTypes` in this meta-class.
+	"""
+
+	FileTypes: Dict[str, 'FileType'] = {}     #: Dictionary of all classes of type :class:`FileType` or derived variants
+	Any: 'FileType'
+
+	def __init__(cls, name: str, bases: Tuple[type, ...], dictionary: Dict[str, typing_Any], **kwargs):
+		super().__init__(name, bases, dictionary, **kwargs)
+		cls.Any = cls
+
+	def __new__(cls, className, baseClasses, classMembers: Dict, *args, **kwargs):
+		fileType = super().__new__(cls, className, baseClasses, classMembers, *args, **kwargs)
+		cls.FileTypes[className] = fileType
+		return fileType
+
+	def __getattr__(cls, item) -> 'FileType':
+		if item[:2] != "__" and item[-2:] != "__":
+			return cls.FileTypes[item]
+		else:
+			return super().__getattribute__(item)
+
+	def __contains__(cls, item) -> bool:
+		return issubclass(item, cls)
+
+
+@export
+class File(metaclass=FileType, slots=True):
+	"""
+	A :term:`File` represents a file in a design. This :term:`base-class` is used
+	for all derived file classes.
+
+	A file can be created standalone and later associated to a fileset, design and
+	project. Or a fileset, design and/or project can be associated immediately
+	while creating a file.
+
+	:arg path:    Relative or absolute path to the file.
+	:arg project: Project the file is associated with.
+	:arg design:  Design the file is associated with.
+	:arg fileSet: Fileset the file is associated with.
+	"""
+
+	_path:       pathlib_Path
+	_fileType:   'FileType'
+	_project:    Nullable['Project']
+	_design:     Nullable['Design']
+	_fileSet:    Nullable['FileSet']
+	_attributes: Dict[Type[Attribute], typing_Any]
+
+	def __init__(
+		self,
+		path: pathlib_Path,
+		project: 'Project' = None,
+		design: 'Design' = None,
+		fileSet: 'FileSet' = None
+	):
+		self._fileType =  getattr(FileTypes, self.__class__.__name__)
+		self._path =      path
+		if project is not None:
+			self._project = project
+			self._design =  design
+			if fileSet is not None:
+				self.FileSet =  fileSet
+		elif design is not None:
+			self._project = design._project
+			self._design =  design
+			self.FileSet =  design.DefaultFileSet if fileSet is None else fileSet
+		elif fileSet is not None:
+			design = fileSet._design
+			if design is not None:
+				self._project = design._project
+			else:
+				self._project = None
+			self._design =    design
+			self.FileSet =    fileSet
+		else:
+			self._project = None
+			self._design =  None
+			self._fileSet = None
+
+		self._attributes = {}
+		self._registerAttributes()
+
+	def _registerAttributes(self):
+		pass
+
+	@property
+	def FileType(self) -> 'FileType':
+		"""Read-only property to return the file type of this file."""
+		return self._fileType
+
+	@property
+	def Path(self) -> pathlib_Path:
+		"""Read-only property returning the path of this file."""
+		return self._path
+
+	# TODO: setter?
+
+	@property
+	def ResolvedPath(self) -> pathlib_Path:
+		"""Read-only property returning the resolved path of this file."""
+		if self._path.is_absolute():
+			return self._path.resolve()
+		elif self._fileSet is not None:
+			path = (self._fileSet.ResolvedPath / self._path).resolve()
+
+			if path.is_absolute():
+				return path
+			else:
+				# WORKAROUND: https://stackoverflow.com/questions/67452690/pathlib-path-relative-to-vs-os-path-relpath
+				return pathlib_Path(path_relpath(path, pathlib_Path.cwd()))
+		else:
+			# TODO: message and exception type
+			raise Exception("")
+
+	@property
+	def Project(self) -> Nullable['Project']:
+		"""Property setting or returning the project this file is used in."""
+		return self._project
+
+	@Project.setter
+	def Project(self, value: 'Project') -> None:
+		self._project = value
+
+		if self._fileSet is None:
+			self._project.DefaultDesign.DefaultFileSet.AddFile(self)
+
+	@property
+	def Design(self) -> Nullable['Design']:
+		"""Property setting or returning the design this file is used in."""
+		return self._design
+
+	@Design.setter
+	def Design(self, value: 'Design') -> None:
+		self._design = value
+
+		if self._fileSet is None:
+			self._design.DefaultFileSet.AddFile(self)
+
+		if self._project is None:
+			self._project = value._project
+		elif self._project is not value._project:
+			raise Exception("The design's project is not identical to the already assigned project.")
+
+	@property
+	def FileSet(self) -> Nullable['FileSet']:
+		"""Property setting or returning the fileset this file is used in."""
+		return self._fileSet
+
+	@FileSet.setter
+	def FileSet(self, value: 'FileSet') -> None:
+		self._fileSet = value
+		value._files.append(self)
+
+	def Validate(self):
+		"""Validate this file."""
+		if self._path is None:
+			raise Exception("Validation: File has no path.")
+		try:
+			path = self.ResolvedPath
+		except Exception as ex:
+			raise Exception(f"Validation: File '{self._path}' could not compute resolved path.") from ex
+		if not path.exists():
+			raise Exception(f"Validation: File '{self._path}' (={path}) does not exist.")
+		if not path.is_file():
+			raise Exception(f"Validation: File '{self._path}' (={path}) is not a file.")
+
+		if self._fileSet is None:
+			raise Exception(f"Validation: File '{self._path}' has no fileset.")
+		if self._design is None:
+			raise Exception(f"Validation: File '{self._path}' has no design.")
+		if self._project is None:
+			raise Exception(f"Validation: File '{self._path}' has no project.")
+
+	def __len__(self) -> int:
+		"""
+		Returns number of attributes set on this file.
+
+		:returns: The number if attributes set on this file.
+		"""
+		return len(self._attributes)
+
+	def __getitem__(self, key: Type[Attribute]) -> Any:
+		"""Index access for returning attributes on this file.
+
+		:param key:        The attribute type.
+		:returns:          The attribute's value.
+		:raises TypeError: When parameter 'key' is not a subclass of Attribute.
+		"""
+		if not issubclass(key, Attribute):
+			raise TypeError("Parameter 'key' is not an 'Attribute'.")
+
+		try:
+			return self._attributes[key]
+		except KeyError:
+			return key.resolve(self, key)
+
+	def __setitem__(self, key: Type[Attribute], value: typing_Any) -> None:
+		"""
+		Index access for adding or setting attributes on this file.
+
+		:param key:        The attribute type.
+		:param value:      The attributes value.
+		:raises TypeError: When parameter 'key' is not a subclass of Attribute.
+		"""
+		if not issubclass(key, Attribute):
+			raise TypeError("Parameter 'key' is not an 'Attribute'.")
+
+		self._attributes[key] = value
+
+	def __delitem__(self, key: Type[Attribute]) -> None:
+		"""
+		Index access for deleting attributes on this file.
+
+		:param key: The attribute type.
+		"""
+		if not issubclass(key, Attribute):
+			raise TypeError("Parameter 'key' is not an 'Attribute'.")
+
+		del self._attributes[key]
+
+	def __str__(self) -> str:
+		return f"{self._path}"
+
+
+FileTypes = File
+
+
+@export
+class HumanReadableContent(metaclass=ExtendedType, mixin=True):
+	"""A file type representing human-readable contents."""
+
+
+@export
+class XMLContent(HumanReadableContent, mixin=True):
+	"""A file type representing XML contents."""
+
+
+@export
+class YAMLContent(HumanReadableContent, mixin=True):
+	"""A file type representing YAML contents."""
+
+
+@export
+class JSONContent(HumanReadableContent, mixin=True):
+	"""A file type representing JSON contents."""
+
+
+@export
+class INIContent(HumanReadableContent, mixin=True):
+	"""A file type representing INI contents."""
+
+
+@export
+class TOMLContent(HumanReadableContent, mixin=True):
+	"""A file type representing TOML contents."""
+
+
+@export
+class TCLContent(HumanReadableContent, mixin=True):
+	"""A file type representing content in TCL code."""
+
+
+@export
+class SDCContent(TCLContent, mixin=True):
+	"""A file type representing contents as Synopsys Design Constraints (SDC)."""
+
+
+@export
+class PythonContent(HumanReadableContent, mixin=True):
+	"""A file type representing contents as Python source code."""
+
+
+@export
+class TextFile(File, HumanReadableContent):
+	"""A text file (``*.txt``)."""
+
+
+@export
+class LogFile(File, HumanReadableContent):
+	"""A log file (``*.log``)."""
+
+
+@export
+class XMLFile(File, XMLContent):
+	"""An XML file (``*.xml``)."""
+
+
+@export
+class SourceFile(File):
+	"""Base-class of all source files."""
+
+
+@export
+class HDLSourceFile(SourceFile):
+	"""Base-class of all HDL source files."""
+
+
+@export
+class RDLSourceFile(SourceFile):
+	"""Base-class of all RDL source files."""
+
+
+@export
+class NetlistFile(SourceFile):
+	"""Base-class of all netlist source files."""
+
+
+@export
+class EDIFNetlistFile(NetlistFile):
+	"""Netlist file in EDIF (Electronic Design Interchange Format)."""
+
+
+@export
+class TCLSourceFile(SourceFile, TCLContent):
+	"""A TCL source file."""
+
+
+@export
+class VHDLSourceFile(HDLSourceFile, HumanReadableContent):
+	"""
+	A VHDL source file (of any language version).
+
+	:arg path:        Relative or absolute path to the file.
+	:arg vhdlLibrary: VHDLLibrary this VHDL source file is associated wih.
+	:arg vhdlVersion: VHDLVersion this VHDL source file is associated wih.
+	:arg project:     Project the file is associated with.
+	:arg design:      Design the file is associated with.
+	:arg fileSet:     Fileset the file is associated with.
+	"""
+
+	_vhdlLibrary: Nullable['VHDLLibrary']
+	_vhdlVersion: VHDLVersion
+
+	def __init__(self, path: pathlib_Path, vhdlLibrary: Union[str, 'VHDLLibrary'] = None, vhdlVersion: VHDLVersion = None, project: 'Project' = None, design: 'Design' = None, fileSet: 'FileSet' = None):
+		super().__init__(path, project, design, fileSet)
+
+		if isinstance(vhdlLibrary, str):
+			if design is not None:
+				try:
+					vhdlLibrary = design.VHDLLibraries[vhdlLibrary]
+				except KeyError as ex:
+					raise Exception(f"VHDL library '{vhdlLibrary}' not found in design '{design.Name}'.") from ex
+			elif project is not None:
+				try:
+					vhdlLibrary = project.DefaultDesign.VHDLLibraries[vhdlLibrary]
+				except KeyError as ex:
+					raise Exception(f"VHDL library '{vhdlLibrary}' not found in default design '{project.DefaultDesign.Name}'.") from ex
+			else:
+				raise Exception(f"Can't lookup VHDL library because neither 'project' nor 'design' is given as a parameter.")
+		elif isinstance(vhdlLibrary, VHDLLibrary):
+			self._vhdlLibrary = vhdlLibrary
+			vhdlLibrary.AddFile(self)
+		elif vhdlLibrary is None:
+			self._vhdlLibrary = None
+		else:
+			raise TypeError(f"Parameter 'vhdlLibrary' is neither a 'str' nor 'VHDLibrary'.")
+
+		self._vhdlVersion = vhdlVersion
+
+	def Validate(self) -> None:
+		"""Validate this VHDL source file."""
+		super().Validate()
+
+		try:
+			_ = self.VHDLLibrary
+		except Exception as ex:
+			raise Exception(f"Validation: VHDLSourceFile '{self._path}' (={self.ResolvedPath}) has no VHDLLibrary assigned.") from ex
+		try:
+			_ = self.VHDLVersion
+		except Exception as ex:
+			raise Exception(f"Validation: VHDLSourceFile '{self._path}' (={self.ResolvedPath}) has no VHDLVersion assigned.") from ex
+
+	@property
+	def VHDLLibrary(self) -> 'VHDLLibrary':
+		"""Property setting or returning the VHDL library this VHDL source file is used in."""
+		if self._vhdlLibrary is not None:
+			return self._vhdlLibrary
+		elif self._fileSet is not None:
+			return self._fileSet.VHDLLibrary
+		else:
+			raise Exception("VHDLLibrary was neither set locally nor globally.")
+
+	@VHDLLibrary.setter
+	def VHDLLibrary(self, value: 'VHDLLibrary') -> None:
+		self._vhdlLibrary = value
+		value._files.append(self)
+
+	@property
+	def VHDLVersion(self) -> VHDLVersion:
+		"""Property setting or returning the VHDL version this VHDL source file is used in."""
+		if self._vhdlVersion is not None:
+			return self._vhdlVersion
+		elif self._fileSet is not None:
+			return self._fileSet.VHDLVersion
+		else:
+			raise Exception("VHDLVersion was neither set locally nor globally.")
+
+	@VHDLVersion.setter
+	def VHDLVersion(self, value: VHDLVersion) -> None:
+		self._vhdlVersion = value
+
+	def __repr__(self) -> str:
+		return f"<VHDL file: '{self.ResolvedPath}'; lib: '{self.VHDLLibrary}'; version: {self.VHDLVersion}>"
+
+
+class VerilogMixIn(metaclass=ExtendedType, mixin=True):
+	@property
+	def VerilogVersion(self) -> SystemVerilogVersion:
+		"""Property setting or returning the Verilog version this Verilog source file is used in."""
+		if self._version is not None:
+			return self._version
+		elif self._fileSet is not None:
+			return self._fileSet.VerilogVersion
+		else:
+			raise Exception("VerilogVersion was neither set locally nor globally.")
+
+	@VerilogVersion.setter
+	def VerilogVersion(self, value: SystemVerilogVersion) -> None:
+		self._version = value
+
+
+class SystemVerilogMixIn(metaclass=ExtendedType, mixin=True):
+	@property
+	def SVVersion(self) -> SystemVerilogVersion:
+		"""Property setting or returning the SystemVerilog version this SystemVerilog source file is used in."""
+		if self._version is not None:
+			return self._version
+		elif self._fileSet is not None:
+			return self._fileSet.SVVersion
+		else:
+			raise Exception("SVVersion was neither set locally nor globally.")
+
+	@SVVersion.setter
+	def SVVersion(self, value: SystemVerilogVersion) -> None:
+		self._version = value
+
+
+@export
+class VerilogBaseFile(HDLSourceFile, HumanReadableContent):
+	_version: SystemVerilogVersion
+
+	def __init__(self, path: pathlib_Path, version: SystemVerilogVersion = None, project: 'Project' = None, design: 'Design' = None, fileSet: 'FileSet' = None):
+		super().__init__(path, project, design, fileSet)
+
+		self._version = version
+
+
+@export
+class VerilogSourceFile(VerilogBaseFile, VerilogMixIn):
+	"""A Verilog source file (of any language version)."""
+
+
+@export
+class VerilogHeaderFile(VerilogBaseFile, VerilogMixIn):
+	"""A Verilog header file (of any language version)."""
+
+
+@export
+class SystemVerilogBaseFile(VerilogBaseFile):
+	...
+
+
+@export
+class SystemVerilogSourceFile(SystemVerilogBaseFile, SystemVerilogMixIn):
+	"""A SystemVerilog source file (of any language version)."""
+
+
+@export
+class SystemVerilogHeaderFile(SystemVerilogBaseFile, SystemVerilogMixIn):
+	"""A SystemVerilog header file (of any language version)."""
+
+
+@export
+class SystemRDLSourceFile(RDLSourceFile, HumanReadableContent):
+	"""A SystemRDL source file (of any language version)."""
+
+	_srdlVersion: SystemRDLVersion
+
+	def __init__(self, path: pathlib_Path, srdlVersion: SystemRDLVersion = None, project: 'Project' = None, design: 'Design' = None, fileSet: 'FileSet' = None):
+		super().__init__(path, project, design, fileSet)
+
+		self._srdlVersion = srdlVersion
+
+	@property
+	def SystemRDLVersion(self) -> SystemRDLVersion:
+		"""Property setting or returning the SystemRDL version this SystemRDL source file is used in."""
+		if self._srdlVersion is not None:
+			return self._srdlVersion
+		elif self._fileSet is not None:
+			return self._fileSet.SRDLVersion
+		else:
+			raise Exception("SRDLVersion was neither set locally nor globally.")
+
+	@SystemRDLVersion.setter
+	def SystemRDLVersion(self, value: SystemRDLVersion) -> None:
+		self._srdlVersion = value
+
+
+@export
+class PythonSourceFile(SourceFile, PythonContent):
+	"""A Python source file."""
+
+
+# TODO: move to a Cocotb module
+@export
+class CocotbPythonFile(PythonSourceFile):
+	"""A Python source file used by Cocotb."""
+
+
+@export
+class ConstraintFile(File, HumanReadableContent):
+	"""Base-class of all constraint files."""
+
+
+@export
+class ProjectFile(File):
+	"""Base-class of all tool-specific project files."""
+
+
+@export
+class CSourceFile(SourceFile):
+	"""Base-class of all ANSI-C source files."""
+
+
+@export
+class CppSourceFile(SourceFile):
+	"""Base-class of all ANSI-C++ source files."""
+
+
+@export
+class SettingFile(File):
+	"""Base-class of all tool-specific setting files."""
+
+
+@export
+class SimulationAnalysisFile(File):
+	"""Base-class of all tool-specific analysis files."""
+
+
+@export
+class SimulationElaborationFile(File):
+	"""Base-class of all tool-specific elaboration files."""
+
+
+@export
+class SimulationStartFile(File):
+	"""Base-class of all tool-specific simulation start-up files."""
+
+
+@export
+class SimulationRunFile(File):
+	"""Base-class of all tool-specific simulation run (execution) files."""
+
+
+@export
+class WaveformConfigFile(File):
+	"""Base-class of all tool-specific waveform configuration files."""
+
+
+@export
+class WaveformDatabaseFile(File):
+	"""Base-class of all tool-specific waveform database files."""
+
+
+@export
+class WaveformExchangeFile(File):
+	"""Base-class of all tool-independent waveform exchange files."""
+
+
+@export
+class FileSet(metaclass=ExtendedType, slots=True):
+	"""
+	A :term:`FileSet` represents a group of files. Filesets can have sub-filesets.
+
+	The order of insertion is preserved. A fileset can be created standalone and
+	later associated to another fileset, design and/or project. Or a fileset,
+	design and/or project can be associated immediately while creating the
+	fileset.
+
+	:arg name:            Name of this fileset.
+	:arg topLevel:        Name of the fileset's toplevel.
+	:arg directory:       Path of this fileset (absolute or relative to a parent fileset or design).
+	:arg project:         Project the file is associated with.
+	:arg design:          Design the file is associated with.
+	:arg parent:          Parent fileset if this fileset is nested.
+	:arg vhdlLibrary:     Default VHDL library for files in this fileset, if not specified for the file itself.
+	:arg vhdlVersion:     Default VHDL version for files in this fileset, if not specified for the file itself.
+	:arg verilogVersion:  Default Verilog version for files in this fileset, if not specified for the file itself.
+	:arg svVersion:       Default SystemVerilog version for files in this fileset, if not specified for the file itself.
+	:arg srdlVersion:     Default SystemRDL version for files in this fileset, if not specified for the file itself.
+	"""
+
+	_name:            str
+	_topLevel:        Nullable[str]
+	_project:         Nullable['Project']
+	_design:          Nullable['Design']
+	_directory:       pathlib_Path
+	_parent:          Nullable['FileSet']
+	_fileSets:        Dict[str, 'FileSet']
+	_files:           List[File]
+	_set:             Set
+	_attributes:      Dict[Type[Attribute], typing_Any]
+	_vhdlLibraries:   Dict[str, 'VHDLLibrary']
+	_vhdlLibrary:     'VHDLLibrary'
+	_vhdlVersion:     VHDLVersion
+	_verilogVersion:  SystemVerilogVersion
+	_svVersion:       SystemVerilogVersion
+	_srdlVersion:     SystemRDLVersion
+
+	def __init__(
+		self,
+		name: str,
+		topLevel: str = None,
+		directory: pathlib_Path = pathlib_Path("."),
+		project: 'Project' = None,
+		design: 'Design' = None,
+		parent: Nullable['FileSet'] = None,
+		vhdlLibrary: Union[str, 'VHDLLibrary'] = None,
+		vhdlVersion: VHDLVersion = None,
+		verilogVersion: SystemVerilogVersion = None,
+		svVersion: SystemVerilogVersion = None,
+		srdlVersion: SystemRDLVersion = None
+	):
+		self._name =      name
+		self._topLevel =  topLevel
+		if project is not None:
+			self._project = project
+			self._design =  design if design is not None else project.DefaultDesign
+
+		elif design is not None:
+			self._project = design._project
+			self._design =  design
+		else:
+			self._project = None
+			self._design =  None
+		self._directory = directory
+		self._parent =    parent
+		self._fileSets =  {}
+		self._files =     []
+		self._set =     set()
+
+		if design is not None:
+			design._fileSets[name] = self
+
+		self._attributes =      {}
+		self._vhdlLibraries =   {}
+
+		# TODO: handle if vhdlLibrary is a string
+		self._vhdlLibrary =     vhdlLibrary
+		self._vhdlVersion =     vhdlVersion
+		self._verilogVersion =  verilogVersion
+		self._svVersion =       svVersion
+		self._srdlVersion =     srdlVersion
+
+	@property
+	def Name(self) -> str:
+		"""Property setting or returning the fileset's name."""
+		return self._name
+
+	@Name.setter
+	def Name(self, value: str) -> None:
+		self._name = value
+
+	@property
+	def TopLevel(self) -> str:
+		"""Property setting or returning the fileset's toplevel."""
+		return self._topLevel
+
+	@TopLevel.setter
+	def TopLevel(self, value: str) -> None:
+		self._topLevel = value
+
+	@property
+	def Project(self) -> Nullable['Project']:
+		"""Property setting or returning the project this fileset is used in."""
+		return self._project
+
+	@Project.setter
+	def Project(self, value: 'Project') -> None:
+		self._project = value
+
+	@property
+	def Design(self) -> Nullable['Design']:
+		"""Property setting or returning the design this fileset is used in."""
+		if self._design is not None:
+			return self._design
+		elif self._parent is not None:
+			return self._parent.Design
+		else:
+			return None
+			# TODO: raise exception instead
+			# QUESTION: how to handle if design and parent is set?
+
+	@Design.setter
+	def Design(self, value: 'Design') -> None:
+		self._design = value
+		if self._project is None:
+			self._project = value._project
+		elif self._project is not value._project:
+			raise Exception("The design's project is not identical to the already assigned project.")
+
+	@property
+	def Directory(self) -> pathlib_Path:
+		"""Property setting or returning the directory this fileset is located in."""
+		return self._directory
+
+	@Directory.setter
+	def Directory(self, value: pathlib_Path) -> None:
+		self._directory = value
+
+	@property
+	def ResolvedPath(self) -> pathlib_Path:
+		"""Read-only property returning the resolved path of this fileset."""
+		if self._directory.is_absolute():
+			return self._directory.resolve()
+		else:
+			if self._parent is not None:
+				directory = self._parent.ResolvedPath
+			elif self._design is not None:
+				directory = self._design.ResolvedPath
+			elif self._project is not None:
+				directory = self._project.ResolvedPath
+			else:
+				# TODO: message and exception type
+				raise Exception("")
+
+			directory = (directory / self._directory).resolve()
+			if directory.is_absolute():
+				return directory
+			else:
+				# WORKAROUND: https://stackoverflow.com/questions/67452690/pathlib-path-relative-to-vs-os-path-relpath
+				return pathlib_Path(path_relpath(directory, pathlib_Path.cwd()))
+
+	@property
+	def Parent(self) -> Nullable['FileSet']:
+		"""Property setting or returning the parent fileset this fileset is used in."""
+		return self._parent
+
+	@Parent.setter
+	def Parent(self, value: 'FileSet') -> None:
+		self._parent = value
+		value._fileSets[self._name] = self
+		# TODO: check it it already exists
+		# QUESTION: make an Add fileset method?
+
+	@property
+	def FileSets(self) -> Dict[str, 'FileSet']:
+		"""Read-only property returning the dictionary of sub-filesets."""
+		return self._fileSets
+
+	def Files(self, fileType: FileType = FileTypes.Any, fileSet: Union[bool, str, 'FileSet'] = None) -> Generator[File, None, None]:
+		"""
+		Method returning the files of this fileset.
+
+		:arg fileType: A filter for file types. Default: ``Any``.
+		:arg fileSet:  Specifies how to handle sub-filesets.
+		"""
+		if fileSet is False:
+			for file in self._files:
+				if file.FileType in fileType:
+					yield file
+		elif fileSet is None:
+			for fileSet in self._fileSets.values():
+				for file in fileSet.Files(fileType):
+					yield file
+			for file in self._files:
+				if file.FileType in fileType:
+					yield file
+		else:
+			if isinstance(fileSet, str):
+				fileSetName = fileSet
+				try:
+					fileSet = self._fileSets[fileSetName]
+				except KeyError as ex:
+					raise Exception(f"Fileset {fileSetName} not bound to fileset {self.Name}.") from ex
+			elif not isinstance(fileSet, FileSet):
+				raise TypeError("Parameter 'fileSet' is not of type 'str' or 'FileSet' nor value 'None'.")
+
+			for file in fileSet.Files(fileType):
+				yield file
+
+	def AddFileSet(self, fileSet: "FileSet") -> None:
+		"""
+		Method to add a single sub-fileset to this fileset.
+
+		:arg fileSet: A fileset to add to this fileset as sub-fileset.
+		"""
+		if not isinstance(fileSet, FileSet):
+			raise ValueError("Parameter 'fileSet' is not of type ProjectModel.FileSet.")
+		elif fileSet in self._fileSets:
+			raise Exception("Sub-fileset already contains this fileset.")
+		elif fileSet.Name in self._fileSets.keys():
+			raise Exception(f"Fileset already contains a sub-fileset named '{fileSet.Name}'.")
+
+		self._fileSets[fileSet.Name] = fileSet
+		fileSet._parent = self
+
+	def AddFileSets(self, fileSets: Iterable["FileSet"]) -> None:
+		"""
+		Method to add a multiple sub-filesets to this fileset.
+
+		:arg fileSets: An iterable of filesets to add each to the fileset.
+		"""
+		for fileSet in fileSets:
+			self.AddFileSet(fileSet)
+
+	@property
+	def FileSetCount(self) -> int:
+		"""Returns number of file sets excl. sub-filesets."""
+		return len(self._fileSets)
+
+	@property
+	def TotalFileSetCount(self) -> int:
+		"""Returns number of file sets incl. sub-filesets."""
+		fileSetCount = len(self._fileSets)
+		for fileSet in self._fileSets.values():
+			fileSetCount += fileSet.TotalFileSetCount
+
+		return fileSetCount
+
+	def AddFile(self, file: File) -> None:
+		"""
+		Method to add a single file to this fileset.
+
+		:arg file: A file to add to this fileset.
+		"""
+		if not isinstance(file, File):
+			raise TypeError("Parameter 'file' is not of type ProjectModel.File.")
+		elif file._fileSet is not None:
+			ex = ValueError(f"File '{file.Path!s}' is already part of fileset '{file.FileSet.Name}'.")
+			ex.add_note(f"A file can't be assigned to another fileset.")
+			raise ex
+		elif file in self._set:
+			ex = ValueError(f"File '{file.Path!s}' is already part of this fileset.")
+			ex.add_note(f"A file can't be added twice to a fileset.")
+			raise ex
+
+		self._files.append(file)
+		self._set.add(file)
+		file._fileSet = self
+
+	def AddFiles(self, files: Iterable[File]) -> None:
+		"""
+		Method to add a multiple files to this fileset.
+
+		:arg files: An iterable of files to add each to the fileset.
+		"""
+		for file in files:
+			self.AddFile(file)
+
+	@property
+	def FileCount(self) -> int:
+		"""Returns number of files excl. sub-filesets."""
+		return len(self._files)
+
+	@property
+	def TotalFileCount(self) -> int:
+		"""Returns number of files incl. the files in sub-filesets."""
+		fileCount = len(self._files)
+		for fileSet in self._fileSets.values():
+			fileCount += fileSet.FileCount
+
+		return fileCount
+
+	def Validate(self) -> None:
+		"""Validate this fileset."""
+		if self._name is None or self._name == "":
+			raise Exception("Validation: FileSet has no name.")
+
+		if self._directory is None:
+			raise Exception(f"Validation: FileSet '{self._name}' has no directory.")
+		try:
+			path = self.ResolvedPath
+		except Exception as ex:
+			raise Exception(f"Validation: FileSet '{self._name}' could not compute resolved path.") from ex
+		if not path.exists():
+			raise Exception(f"Validation: FileSet '{self._name}'s directory '{path}' does not exist.")
+		if not path.is_dir():
+			raise Exception(f"Validation: FileSet '{self._name}'s directory '{path}' is not a directory.")
+
+		if self._design is None:
+			raise Exception(f"Validation: FileSet '{self._directory}' has no design.")
+		if self._project is None:
+			raise Exception(f"Validation: FileSet '{self._directory}' has no project.")
+
+		for fileSet in self._fileSets.values():
+			fileSet.Validate()
+		for file in self._files:
+			file.Validate()
+
+	def GetOrCreateVHDLLibrary(self, name) -> 'VHDLLibrary':
+		if name in self._vhdlLibraries:
+			return self._vhdlLibraries[name]
+		elif name in self._design._vhdlLibraries:
+			library = self._design._vhdlLibraries[name]
+			self._vhdlLibraries[name] = library
+			return library
+		else:
+			library = VHDLLibrary(name, design=self._design, vhdlVersion=self._vhdlVersion)
+			self._vhdlLibraries[name] = library
+			return library
+
+	@property
+	def VHDLLibrary(self) -> 'VHDLLibrary':
+		"""Property setting or returning the VHDL library of this fileset."""
+		if self._vhdlLibrary is not None:
+			return self._vhdlLibrary
+		elif self._parent is not None:
+			return self._parent.VHDLLibrary
+		elif self._design is not None:
+			return self._design.VHDLLibrary
+		else:
+			raise Exception("VHDLLibrary was neither set locally nor globally.")
+
+	@VHDLLibrary.setter
+	def VHDLLibrary(self, value: 'VHDLLibrary') -> None:
+		self._vhdlLibrary = value
+
+	@property
+	def VHDLVersion(self) -> VHDLVersion:
+		"""Property setting or returning the VHDL version of this fileset."""
+		if self._vhdlVersion is not None:
+			return self._vhdlVersion
+		elif self._parent is not None:
+			return self._parent.VHDLVersion
+		elif self._design is not None:
+			return self._design.VHDLVersion
+		else:
+			raise Exception("VHDLVersion was neither set locally nor globally.")
+
+	@VHDLVersion.setter
+	def VHDLVersion(self, value: VHDLVersion) -> None:
+		self._vhdlVersion = value
+
+	@property
+	def VerilogVersion(self) -> SystemVerilogVersion:
+		"""Property setting or returning the Verilog version of this fileset."""
+		if self._verilogVersion is not None:
+			return self._verilogVersion
+		elif self._parent is not None:
+			return self._parent.VerilogVersion
+		elif self._design is not None:
+			return self._design.VerilogVersion
+		else:
+			raise Exception("VerilogVersion was neither set locally nor globally.")
+
+	@VerilogVersion.setter
+	def VerilogVersion(self, value: SystemVerilogVersion) -> None:
+		self._verilogVersion = value
+
+	@property
+	def SVVersion(self) -> SystemVerilogVersion:
+		"""Property setting or returning the SystemVerilog version of this fileset."""
+		if self._svVersion is not None:
+			return self._svVersion
+		elif self._parent is not None:
+			return self._parent.SVVersion
+		elif self._design is not None:
+			return self._design.SVVersion
+		else:
+			raise Exception("SVVersion was neither set locally nor globally.")
+
+	@SVVersion.setter
+	def SVVersion(self, value: SystemVerilogVersion) -> None:
+		self._svVersion = value
+
+	@property
+	def SRDLVersion(self) -> SystemRDLVersion:
+		if self._srdlVersion is not None:
+			return self._srdlVersion
+		elif self._parent is not None:
+			return self._parent.SRDLVersion
+		elif self._design is not None:
+			return self._design.SRDLVersion
+		else:
+			raise Exception("SRDLVersion was neither set locally nor globally.")
+
+	@SRDLVersion.setter
+	def SRDLVersion(self, value: SystemRDLVersion) -> None:
+		self._srdlVersion = value
+
+	def __len__(self) -> int:
+		"""
+		Returns number of attributes set on this fileset.
+
+		:returns: The number if attributes set on this fileset.
+		"""
+		return len(self._attributes)
+
+	def __getitem__(self, key: Type[Attribute]) -> Any:
+		"""Index access for returning attributes on this fileset.
+
+		:param key:        The attribute type.
+		:returns:          The attribute's value.
+		:raises TypeError: When parameter 'key' is not a subclass of Attribute.
+		"""
+		if not issubclass(key, Attribute):
+			raise TypeError("Parameter 'key' is not an 'Attribute'.")
+
+		try:
+			return self._attributes[key]
+		except KeyError:
+			return key.resolve(self, key)
+
+	def __setitem__(self, key: Type[Attribute], value: typing_Any) -> None:
+		"""
+		Index access for adding or setting attributes on this fileset.
+
+		:param key:        The attribute type.
+		:param value:      The attributes value.
+		:raises TypeError: When parameter 'key' is not a subclass of Attribute.
+		"""
+		if not issubclass(key, Attribute):
+			raise TypeError("Parameter 'key' is not an 'Attribute'.")
+
+		self._attributes[key] = value
+
+	def __delitem__(self, key: Type[Attribute]) -> None:
+		"""
+		Index access for deleting attributes on this fileset.
+
+		:param key: The attribute type.
+		"""
+		if not issubclass(key, Attribute):
+			raise TypeError("Parameter 'key' is not an 'Attribute'.")
+
+		del self._attributes[key]
+
+	def __str__(self) -> str:
+		"""Returns the fileset's name."""
+		return self._name
+
+
+@export
+class VHDLLibrary(metaclass=ExtendedType, slots=True):
+	"""
+	A :term:`VHDLLibrary` represents a group of VHDL source files compiled into the same VHDL library.
+
+	:arg name:        The VHDL libraries' name.
+	:arg project:     Project the VHDL library is associated with.
+	:arg design:      Design the VHDL library is associated with.
+	:arg vhdlVersion: Default VHDL version for files in this VHDL library, if not specified for the file itself.
+	"""
+
+	_name:        str
+	_project:     Nullable['Project']
+	_design:      Nullable['Design']
+	_files:       List[File]
+	_vhdlVersion: VHDLVersion
+
+	_dependencyNode: Vertex
+
+	def __init__(
+		self,
+		name: str,
+		project: 'Project' = None,
+		design: 'Design' = None,
+		vhdlVersion: VHDLVersion = None
+	):
+		self._name =    name
+		if project is not None:
+			self._project = project
+			self._design = project._defaultDesign if design is None else design
+			self._dependencyNode = Vertex(value=self, graph=self._design._vhdlLibraryDependencyGraph)
+
+			if name in self._design._vhdlLibraries:
+				raise Exception(f"Library '{name}' already in design '{self._design.Name}'.")
+			else:
+				self._design._vhdlLibraries[name] = self
+
+		elif design is not None:
+			self._project = design._project
+			self._design = design
+			self._dependencyNode = Vertex(value=self, graph=design._vhdlLibraryDependencyGraph)
+
+			if name in design._vhdlLibraries:
+				raise Exception(f"Library '{name}' already in design '{design.Name}'.")
+			else:
+				design._vhdlLibraries[name] = self
+
+		else:
+			self._project = None
+			self._design =  None
+			self._dependencyNode = None
+
+		self._files =     []
+		self._vhdlVersion = vhdlVersion
+
+	@property
+	def Name(self) -> str:
+		return self._name
+
+	@property
+	def Project(self) -> Nullable['Project']:
+		"""Property setting or returning the project this VHDL library is used in."""
+		return self._project
+
+	@Project.setter
+	def Project(self, value: 'Project') -> None:
+		if not isinstance(value, Project):
+			raise TypeError("Parameter 'value' is not of type 'Project'.")
+
+		if value is None:
+			# TODO: unlink VHDLLibrary from project
+			self._project = None
+		else:
+			self._project = value
+			if self._design is None:
+				self._design = value._defaultDesign
+
+	@property
+	def Design(self) -> Nullable['Design']:
+		"""Property setting or returning the design this VHDL library is used in."""
+		return self._design
+
+	@Design.setter
+	def Design(self, value: 'Design') -> None:
+		if not isinstance(value, Design):
+			raise TypeError("Parameter 'value' is not of type 'Design'.")
+
+		if value is None:
+			# TODO: unlink VHDLLibrary from design
+			self._design = None
+		else:
+			if self._design is None:
+				self._design = value
+				self._dependencyNode = Vertex(value=self, graph=self._design._vhdlLibraryDependencyGraph)
+			elif self._design is not value:
+				# TODO: move VHDLLibrary to other design
+				# TODO: create new vertex in dependency graph and remove vertex from old graph
+				self._design = value
+			else:
+				pass
+
+			if self._project is None:
+				self._project = value._project
+			elif self._project is not value._project:
+				raise Exception("The design's project is not identical to the already assigned project.")
+
+	@property
+	def Files(self) -> Generator[File, None, None]:
+		"""Read-only property to return all files in this VHDL library."""
+		for file in self._files:
+			yield file
+
+	@property
+	def VHDLVersion(self) -> VHDLVersion:
+		"""Property setting or returning the VHDL version of this VHDL library."""
+		if self._vhdlVersion is not None:
+			return self._vhdlVersion
+		elif self._design is not None:
+			return self._design.VHDLVersion
+		else:
+			raise Exception("VHDLVersion is not set on VHDLLibrary nor parent object.")
+
+	@VHDLVersion.setter
+	def VHDLVersion(self, value: VHDLVersion) -> None:
+		self._vhdlVersion = value
+
+	def AddDependency(self, library: 'VHDLLibrary') -> None:
+		library.parent = self
+
+	def AddFile(self, vhdlFile: VHDLSourceFile) -> None:
+		if not isinstance(vhdlFile, VHDLSourceFile):
+			raise TypeError(f"Parameter 'vhdlFile' is not a 'VHDLSourceFile'.")
+
+		self._files.append(vhdlFile)
+
+	def AddFiles(self, vhdlFiles: Iterable[VHDLSourceFile]) -> None:
+		for vhdlFile in vhdlFiles:
+			if not isinstance(vhdlFile, VHDLSourceFile):
+				raise TypeError(f"Item '{vhdlFile}' in parameter 'vhdlFiles' is not a 'VHDLSourceFile'.")
+
+			self._files.append(vhdlFile)
+
+	@property
+	def FileCount(self) -> int:
+		"""Returns number of files."""
+		return len(self._files)
+
+	def __len__(self) -> int:
+		"""
+		Returns number of attributes set on this VHDL library.
+
+		:returns: The number if attributes set on this VHDL library.
+		"""
+		return len(self._attributes)
+
+	def __getitem__(self, key: Type[Attribute]) -> Any:
+		"""Index access for returning attributes on this VHDL library.
+
+		:param key:        The attribute type.
+		:returns:          The attribute's value.
+		:raises TypeError: When parameter 'key' is not a subclass of Attribute.
+		"""
+		if not issubclass(key, Attribute):
+			raise TypeError("Parameter 'key' is not an 'Attribute'.")
+
+		try:
+			return self._attributes[key]
+		except KeyError:
+			return key.resolve(self, key)
+
+	def __setitem__(self, key: Type[Attribute], value: typing_Any) -> None:
+		"""
+		Index access for adding or setting attributes on this VHDL library.
+
+		:param key:        The attribute type.
+		:param value:      The attributes value.
+		:raises TypeError: When parameter 'key' is not a subclass of Attribute.
+		"""
+		if not issubclass(key, Attribute):
+			raise TypeError("Parameter 'key' is not an 'Attribute'.")
+
+		self._attributes[key] = value
+
+	def __delitem__(self, key: Type[Attribute]) -> None:
+		"""
+		Index access for deleting attributes on this VHDL library.
+
+		:param key: The attribute type.
+		"""
+		if not issubclass(key, Attribute):
+			raise TypeError("Parameter 'key' is not an 'Attribute'.")
+
+		del self._attributes[key]
+
+	def __str__(self) -> str:
+		"""Returns the VHDL library's name."""
+		return self._name
+
+
+@export
+class Design(metaclass=ExtendedType, slots=True):
+	"""
+	A :term:`Design` represents a group of filesets and the source files therein.
+
+	Each design contains at least one fileset - the :term:`default fileset`. For
+	designs with VHDL source files, a independent `VHDLLibraries` overlay structure
+	exists.
+
+	:arg name:            The design's name.
+	:arg topLevel:        Name of the design's toplevel.
+	:arg directory:       Path of this design (absolute or relative to the project).
+	:arg project:         Project the design is associated with.
+	:arg vhdlVersion:     Default VHDL version for files in this design, if not specified for the file itself.
+	:arg verilogVersion:  Default Verilog version for files in this design, if not specified for the file itself.
+	:arg svVersion:       Default SystemVerilog version for files in this design, if not specified for the file itself.
+	:arg srdlVersion:     Default SystemRDL version for files in this fileset, if not specified for the file itself.
+	"""
+
+	_name:                  str
+	_topLevel:              Nullable[str]
+	_project:               Nullable['Project']
+	_directory:             pathlib_Path
+	_fileSets:              Dict[str, FileSet]
+	_defaultFileSet:        Nullable[FileSet]
+	_attributes:            Dict[Type[Attribute], typing_Any]
+
+	_vhdlLibraries:         Dict[str, VHDLLibrary]
+	_vhdlVersion:           VHDLVersion
+	_verilogVersion:        SystemVerilogVersion
+	_svVersion:             SystemVerilogVersion
+	_srdlVersion:           SystemRDLVersion
+	_externalVHDLLibraries: List
+
+	_vhdlLibraryDependencyGraph: Graph
+	_fileDependencyGraph:        Graph
+
+	def __init__(
+		self,
+		name: str,
+		topLevel: str = None,
+		directory: pathlib_Path = pathlib_Path("."),
+		project: 'Project' = None,
+		vhdlVersion: VHDLVersion = None,
+		verilogVersion: SystemVerilogVersion = None,
+		svVersion: SystemVerilogVersion = None,
+		srdlVersion: SystemRDLVersion = None
+	):
+		self._name =                  name
+		self._topLevel =              topLevel
+		self._project =               project
+		if project is not None:
+			project._designs[name] = self
+		self._directory =             directory
+		self._fileSets =              {}
+		self._defaultFileSet =        FileSet("default", project=project, design=self)
+		self._attributes =            {}
+		self._vhdlLibraries =         {}
+		self._vhdlVersion =           vhdlVersion
+		self._verilogVersion =        verilogVersion
+		self._svVersion =             svVersion
+		self._srdlVersion =           srdlVersion
+		self._externalVHDLLibraries = []
+
+		self._vhdlLibraryDependencyGraph = Graph()
+		self._fileDependencyGraph = Graph()
+
+	@property
+	def Name(self) -> str:
+		"""Property setting or returning the design's name."""
+		return self._name
+
+	@Name.setter
+	def Name(self, value: str) -> None:
+		self._name = value
+
+	@property
+	def TopLevel(self) -> str:
+		"""Property setting or returning the fileset's toplevel."""
+		return self._topLevel
+
+	@TopLevel.setter
+	def TopLevel(self, value: str) -> None:
+		self._topLevel = value
+
+	@property
+	def Project(self) -> Nullable['Project']:
+		"""Property setting or returning the project this design is used in."""
+		return self._project
+
+	@Project.setter
+	def Project(self, value: 'Project') -> None:
+		self._project = value
+
+	@property
+	def Directory(self) -> pathlib_Path:
+		"""Property setting or returning the directory this design is located in."""
+		return self._directory
+
+	@Directory.setter
+	def Directory(self, value: pathlib_Path) -> None:
+		self._directory = value
+
+	@property
+	def ResolvedPath(self) -> pathlib_Path:
+		"""Read-only property returning the resolved path of this fileset."""
+		if self._directory.is_absolute():
+			return self._directory.resolve()
+		elif self._project is not None:
+			path = (self._project.ResolvedPath / self._directory).resolve()
+
+			if path.is_absolute():
+				return path
+			else:
+				# WORKAROUND: https://stackoverflow.com/questions/67452690/pathlib-path-relative-to-vs-os-path-relpath
+				return pathlib_Path(path_relpath(path, pathlib_Path.cwd()))
+		else:
+			# TODO: message and exception type
+			raise Exception("")
+
+	@property
+	def DefaultFileSet(self) -> FileSet:
+		"""Property setting or returning the default fileset of this design."""
+		return self._defaultFileSet
+
+	@DefaultFileSet.setter
+	def DefaultFileSet(self, value: Union[str, FileSet]) -> None:
+		if isinstance(value, str):
+			if value not in self._fileSets.keys():
+				raise Exception(f"Fileset '{value}' is not in this design.")
+
+			self._defaultFileSet = self._fileSets[value]
+		elif isinstance(value, FileSet):
+			if value not in self.FileSets:
+				raise Exception(f"Fileset '{value}' is not associated to this design.")
+
+			self._defaultFileSet = value
+		else:
+			raise ValueError("Unsupported parameter type for 'value'.")
+
+	# TODO: return generator with another method
+	@property
+	def FileSets(self) -> Dict[str, FileSet]:
+		"""Read-only property returning the dictionary of filesets."""
+		return self._fileSets
+
+	def Files(self, fileType: FileType = FileTypes.Any, fileSet: Union[str, FileSet] = None) -> Generator[File, None, None]:
+		"""
+		Method returning the files of this design.
+
+		:arg fileType: A filter for file types. Default: ``Any``.
+		:arg fileSet:  Specifies if all files from all filesets (``fileSet=None``) are files from a single fileset are returned.
+		"""
+		if fileSet is None:
+			for fileSet in self._fileSets.values():
+				for file in fileSet.Files(fileType):
+					yield file
+		else:
+			if isinstance(fileSet, str):
+				try:
+					fileSet = self._fileSets[fileSet]
+				except KeyError as ex:
+					raise Exception(f"Fileset {fileSet.Name} not bound to design {self.Name}.") from ex
+			elif not isinstance(fileSet, FileSet):
+				raise TypeError("Parameter 'fileSet' is not of type 'str' or 'FileSet' nor value 'None'.")
+
+			for file in fileSet.Files(fileType):
+				yield file
+
+	def Validate(self) -> None:
+		"""Validate this design."""
+		if self._name is None or self._name == "":
+			raise Exception("Validation: Design has no name.")
+
+		if self._directory is None:
+			raise Exception(f"Validation: Design '{self._name}' has no directory.")
+		try:
+			path = self.ResolvedPath
+		except Exception as ex:
+			raise Exception(f"Validation: Design '{self._name}' could not compute resolved path.") from ex
+		if not path.exists():
+			raise Exception(f"Validation: Design '{self._name}'s directory '{path}' does not exist.")
+		if not path.is_dir():
+			raise Exception(f"Validation: Design '{self._name}'s directory '{path}' is not a directory.")
+
+		if len(self._fileSets) == 0:
+			raise Exception(f"Validation: Design '{self._name}' has no fileset.")
+		try:
+			if self._defaultFileSet is not self._fileSets[self._defaultFileSet.Name]:
+				raise Exception(f"Validation: Design '{self._name}'s default fileset is the same as listed in filesets.")
+		except KeyError as ex:
+			raise Exception(f"Validation: Design '{self._name}'s default fileset is not in list of filesets.") from ex
+		if self._project is None:
+			raise Exception(f"Validation: Design '{self._path}' has no project.")
+
+		for fileSet in self._fileSets.values():
+			fileSet.Validate()
+
+	@property
+	def VHDLLibraries(self) -> Dict[str, VHDLLibrary]:
+		return self._vhdlLibraries
+
+	@property
+	def VHDLVersion(self) -> VHDLVersion:
+		if self._vhdlVersion is not None:
+			return self._vhdlVersion
+		elif self._project is not None:
+			return self._project.VHDLVersion
+		else:
+			raise Exception("VHDLVersion was neither set locally nor globally.")
+
+	@VHDLVersion.setter
+	def VHDLVersion(self, value: VHDLVersion) -> None:
+		self._vhdlVersion = value
+
+	@property
+	def VerilogVersion(self) -> SystemVerilogVersion:
+		if self._verilogVersion is not None:
+			return self._verilogVersion
+		elif self._project is not None:
+			return self._project.VerilogVersion
+		else:
+			raise Exception("VerilogVersion was neither set locally nor globally.")
+
+	@VerilogVersion.setter
+	def VerilogVersion(self, value: SystemVerilogVersion) -> None:
+		self._verilogVersion = value
+
+	@property
+	def SVVersion(self) -> SystemVerilogVersion:
+		if self._svVersion is not None:
+			return self._svVersion
+		elif self._project is not None:
+			return self._project.SVVersion
+		else:
+			raise Exception("SVVersion was neither set locally nor globally.")
+
+	@SVVersion.setter
+	def SVVersion(self, value: SystemVerilogVersion) -> None:
+		self._svVersion = value
+
+	@property
+	def SRDLVersion(self) -> SystemRDLVersion:
+		if self._srdlVersion is not None:
+			return self._srdlVersion
+		elif self._project is not None:
+			return self._project.SRDLVersion
+		else:
+			raise Exception("SRDLVersion was neither set locally nor globally.")
+
+	@SRDLVersion.setter
+	def SRDLVersion(self, value: SystemRDLVersion) -> None:
+		self._srdlVersion = value
+
+	@property
+	def ExternalVHDLLibraries(self) -> List:
+		return self._externalVHDLLibraries
+
+	def AddFileSet(self, fileSet: FileSet) -> None:
+		if not isinstance(fileSet, FileSet):
+			raise ValueError("Parameter 'fileSet' is not of type ProjectModel.FileSet.")
+		elif fileSet in self._fileSets:
+			raise Exception("Design already contains this fileset.")
+		elif fileSet.Name in self._fileSets.keys():
+			raise Exception(f"Design already contains a fileset named '{fileSet.Name}'.")
+
+		self._fileSets[fileSet.Name] = fileSet
+		fileSet.Design = self
+		fileSet._parent = self
+
+	def AddFileSets(self, fileSets: Iterable[FileSet]) -> None:
+		for fileSet in fileSets:
+			self.AddFileSet(fileSet)
+
+	@property
+	def FileSetCount(self) -> int:
+		"""Returns number of file sets excl. sub-filesets."""
+		return len(self._fileSets)
+
+	@property
+	def TotalFileSetCount(self) -> int:
+		"""Returns number of file sets incl. sub-filesets."""
+		fileSetCount = len(self._fileSets)
+		for fileSet in self._fileSets.values():
+			fileSetCount += fileSet.TotalFileSetCount
+
+		return fileSetCount
+
+	def AddFile(self, file: File) -> None:
+		if file.FileSet is None:
+			self._defaultFileSet.AddFile(file)
+		else:
+			raise ValueError(f"File '{file.Path!s}' is already part of fileset '{file.FileSet.Name}' and can't be assigned via Design to a default fileset.")
+
+	def AddFiles(self, files: Iterable[File]) -> None:
+		for file in files:
+			self.AddFile(file)
+
+	def AddVHDLLibrary(self, vhdlLibrary: VHDLLibrary) -> None:
+		if vhdlLibrary.Name in self._vhdlLibraries:
+			if self._vhdlLibraries[vhdlLibrary.Name] is vhdlLibrary:
+				raise Exception(f"The VHDLLibrary '{vhdlLibrary.Name}' was already added to the design.")
+			else:
+				raise Exception(f"A VHDLLibrary with same name ('{vhdlLibrary.Name}') already exists for this design.")
+
+
+	def __len__(self) -> int:
+		"""
+		Returns number of attributes set on this design.
+
+		:returns: The number if attributes set on this design.
+		"""
+		return len(self._attributes)
+
+	def __getitem__(self, key: Type[Attribute]) -> Any:
+		"""Index access for returning attributes on this design.
+
+		:param key:        The attribute type.
+		:returns:          The attribute's value.
+		:raises TypeError: When parameter 'key' is not a subclass of Attribute.
+		"""
+		if not issubclass(key, Attribute):
+			raise TypeError("Parameter 'key' is not an 'Attribute'.")
+
+		try:
+			return self._attributes[key]
+		except KeyError:
+			return key.resolve(self, key)
+
+	def __setitem__(self, key: Type[Attribute], value: typing_Any) -> None:
+		"""
+		Index access for adding or setting attributes on this design.
+
+		:param key:        The attribute type.
+		:param value:      The attributes value.
+		:raises TypeError: When parameter 'key' is not a subclass of Attribute.
+		"""
+		if not issubclass(key, Attribute):
+			raise TypeError("Parameter 'key' is not an 'Attribute'.")
+
+		self._attributes[key] = value
+
+	def __delitem__(self, key: Type[Attribute]) -> None:
+		"""
+		Index access for deleting attributes on this design.
+
+		:param key: The attribute type.
+		"""
+		if not issubclass(key, Attribute):
+			raise TypeError("Parameter 'key' is not an 'Attribute'.")
+
+		del self._attributes[key]
+
+	def __str__(self) -> str:
+		return self._name
+
+
+@export
+class Project(metaclass=ExtendedType, slots=True):
+	"""
+	A :term:`Project` represents a group of designs and the source files therein.
+
+	:arg name:            The project's name.
+	:arg rootDirectory:   Base-path to the project.
+	:arg vhdlVersion:     Default VHDL version for files in this project, if not specified for the file itself.
+	:arg verilogVersion:  Default Verilog version for files in this project, if not specified for the file itself.
+	:arg svVersion:       Default SystemVerilog version for files in this project, if not specified for the file itself.
+	"""
+
+	_name:            str
+	_rootDirectory:   pathlib_Path
+	_designs:         Dict[str, Design]
+	_defaultDesign:   Design
+	_attributes:      Dict[Type[Attribute], typing_Any]
+
+	_vhdlVersion:     VHDLVersion
+	_verilogVersion:  SystemVerilogVersion
+	_svVersion:       SystemVerilogVersion
+	_srdlVersion:     SystemRDLVersion
+
+	def __init__(
+		self,
+		name: str,
+		rootDirectory: pathlib_Path = pathlib_Path("."),
+		vhdlVersion: VHDLVersion = None,
+		verilogVersion: SystemVerilogVersion = None,
+		svVersion: SystemVerilogVersion = None
+	):
+		self._name =            name
+		self._rootDirectory =   rootDirectory
+		self._designs =         {}
+		self._defaultDesign =   Design("default", project=self)
+		self._attributes =      {}
+		self._vhdlVersion =     vhdlVersion
+		self._verilogVersion =  verilogVersion
+		self._svVersion =       svVersion
+
+	@property
+	def Name(self) -> str:
+		"""Property setting or returning the project's name."""
+		return self._name
+
+	@property
+	def RootDirectory(self) -> pathlib_Path:
+		"""Property setting or returning the root directory this project is located in."""
+		return self._rootDirectory
+
+	@RootDirectory.setter
+	def RootDirectory(self, value: pathlib_Path) -> None:
+		self._rootDirectory = value
+
+	@property
+	def ResolvedPath(self) -> pathlib_Path:
+		"""Read-only property returning the resolved path of this fileset."""
+		path = self._rootDirectory.resolve()
+		if self._rootDirectory.is_absolute():
+			return path
+		else:
+			# WORKAROUND: https://stackoverflow.com/questions/67452690/pathlib-path-relative-to-vs-os-path-relpath
+			return pathlib_Path(path_relpath(path, pathlib_Path.cwd()))
+
+	# TODO: return generator with another method
+	@property
+	def Designs(self) -> Dict[str, Design]:
+		return self._designs
+
+	@property
+	def DefaultDesign(self) -> Design:
+		return self._defaultDesign
+
+	def Validate(self) -> None:
+		"""Validate this project."""
+		if self._name is None or self._name == "":
+			raise Exception("Validation: Project has no name.")
+
+		if self._rootDirectory is None:
+			raise Exception(f"Validation: Project '{self._name}' has no root directory.")
+		try:
+			path = self.ResolvedPath
+		except Exception as ex:
+			raise Exception(f"Validation: Project '{self._name}' could not compute resolved path.") from ex
+		if not path.exists():
+			raise Exception(f"Validation: Project '{self._name}'s directory '{path}' does not exist.")
+		if not path.is_dir():
+			raise Exception(f"Validation: Project '{self._name}'s directory '{path}' is not a directory.")
+
+		if len(self._designs) == 0:
+			raise Exception(f"Validation: Project '{self._name}' has no design.")
+		try:
+			if self._defaultDesign is not self._designs[self._defaultDesign.Name]:
+				raise Exception(f"Validation: Project '{self._name}'s default design is the same as listed in designs.")
+		except KeyError as ex:
+			raise Exception(f"Validation: Project '{self._name}'s default design is not in list of designs.") from ex
+
+		for design in self._designs.values():
+			design.Validate()
+
+	@property
+	def DesignCount(self) -> int:
+		"""Returns number of designs."""
+		return len(self._designs)
+
+	@property
+	def VHDLVersion(self) -> VHDLVersion:
+		# TODO: check for None and return exception
+		return self._vhdlVersion
+
+	@VHDLVersion.setter
+	def VHDLVersion(self, value: VHDLVersion) -> None:
+		self._vhdlVersion = value
+
+	@property
+	def VerilogVersion(self) -> SystemVerilogVersion:
+		# TODO: check for None and return exception
+		return self._verilogVersion
+
+	@VerilogVersion.setter
+	def VerilogVersion(self, value: SystemVerilogVersion) -> None:
+		self._verilogVersion = value
+
+	@property
+	def SVVersion(self) -> SystemVerilogVersion:
+		# TODO: check for None and return exception
+		return self._svVersion
+
+	@SVVersion.setter
+	def SVVersion(self, value: SystemVerilogVersion) -> None:
+		self._svVersion = value
+
+	@property
+	def SRDLVersion(self) -> SystemRDLVersion:
+		# TODO: check for None and return exception
+		return self._srdlVersion
+
+	@SRDLVersion.setter
+	def SRDLVersion(self, value: SystemRDLVersion) -> None:
+		self._srdlVersion = value
+
+	def __len__(self) -> int:
+		"""
+		Returns number of attributes set on this project.
+
+		:returns: The number if attributes set on this project.
+		"""
+		return len(self._attributes)
+
+	def __getitem__(self, key: Type[Attribute]) -> Any:
+		"""Index access for returning attributes on this project.
+
+		:param key:        The attribute type.
+		:returns:          The attribute's value.
+		:raises TypeError: When parameter 'key' is not a subclass of Attribute.
+		"""
+		if not issubclass(key, Attribute):
+			raise TypeError("Parameter 'key' is not an 'Attribute'.")
+
+		try:
+			return self._attributes[key]
+		except KeyError:
+			return key.resolve(self, key)
+
+	def __setitem__(self, key: Type[Attribute], value: typing_Any) -> None:
+		"""
+		Index access for adding or setting attributes on this project.
+
+		:param key:        The attribute type.
+		:param value:      The attributes value.
+		:raises TypeError: When parameter 'key' is not a subclass of Attribute.
+		"""
+		if not issubclass(key, Attribute):
+			raise TypeError("Parameter 'key' is not an 'Attribute'.")
+
+		self._attributes[key] = value
+
+	def __delitem__(self, key: Type[Attribute]) -> None:
+		"""
+		Index access for deleting attributes on this project.
+
+		:param key: The attribute type.
+		"""
+		if not issubclass(key, Attribute):
+			raise TypeError("Parameter 'key' is not an 'Attribute'.")
+
+		del self._attributes[key]
+
+	def __str__(self) -> str:
+		return self._name
+
+ + diff --git a/typing/index.html b/typing/index.html new file mode 100644 index 00000000..bd8ebe8e --- /dev/null +++ b/typing/index.html @@ -0,0 +1,104 @@ + + + + + + +

Mypy Type Check Coverage Summary

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Summary from index
FileImprecisionLines
Total14.11% imprecise2735 LOC
ProjectModel11.49% imprecise1853 LOC
ProjectModel.Altera0.00% imprecise31 LOC
ProjectModel.Altera.Quartus2.27% imprecise44 LOC
ProjectModel.Attributes7.55% imprecise53 LOC
ProjectModel.GHDL2.56% imprecise39 LOC
ProjectModel.Intel0.00% imprecise31 LOC
ProjectModel.Intel.QuartusPrime2.27% imprecise44 LOC
ProjectModel.MentorGraphics0.00% imprecise31 LOC
ProjectModel.MentorGraphics.ModelSim2.04% imprecise49 LOC
ProjectModel.MentorGraphics.QuestaSim2.04% imprecise49 LOC
ProjectModel.OSVVM38.02% imprecise192 LOC
ProjectModel.VHDL0.00% imprecise0 LOC
ProjectModel.Verilog2.56% imprecise39 LOC
ProjectModel.Xilinx0.00% imprecise31 LOC
ProjectModel.Xilinx.ISE2.27% imprecise44 LOC
ProjectModel.Xilinx.Vivado43.41% imprecise205 LOC
+ + diff --git a/typing/mypy-html.css b/typing/mypy-html.css new file mode 100644 index 00000000..ec2bdf9c --- /dev/null +++ b/typing/mypy-html.css @@ -0,0 +1,104 @@ +/* CSS for type check coverage reports */ + +/* + Used by both summary and file. +*/ +body { + font-family: "Helvetica Neue", sans-serif; +} + +/* + Used only by summary. +*/ + +h1 { + text-align: center; + font-size: 135%; + margin: 20px; +} + +table.summary { + border-collapse: collapse; + margin-left: 7%; + margin-right: 7%; + width: 85%; +} + +table caption { + margin: 1em; +} + +table.summary, tr.summary, th.summary, td.summary { + border: 1px solid #aaa; +} + +th.summary, td.summary { + padding: 0.4em; +} + +td.summary a { + text-decoration: none; +} + +.summary-quality-0 { + background-color: #dfd; +} + +.summary-quality-1 { + background-color: #ffa; +} + +.summary-quality-2 { + background-color: #faa; +} + +td.summary-filename, th.summary-filename { + text-align: left; +} + +td.summary-filename { + width: 50%; +} + +.summary-precision { + text-align: center; +} + +.summary-lines { + text-align: center; +} + +/* + Used only by file. +*/ + +td.table-lines { + text-align: right; + padding-right: 0.5em; +} + +td.table-code { } + +span.lineno { + text-align: right; +} + +a:link.lineno, a:visited.lineno { + color: #999; text-decoration: none; +} + +a:hover.lineno, a:active.lineno { + color: #000; text-decoration: underline; +} + +.line-empty, .line-precise { + background-color: #dfd; +} + +.line-imprecise { + background-color: #ffa; +} + +.line-any, .line-unanalyzed { + background-color: #faa; +}