SimplHDL 0.4.0__tar.gz → 0.5.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. {simplhdl-0.4.0 → simplhdl-0.5.1}/PKG-INFO +2 -1
  2. {simplhdl-0.4.0 → simplhdl-0.5.1}/pyproject.toml +1 -0
  3. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/SimplHDL.egg-info/PKG-INFO +2 -1
  4. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/SimplHDL.egg-info/SOURCES.txt +2 -0
  5. simplhdl-0.5.1/src/simplhdl/__init__.py +1 -0
  6. simplhdl-0.5.1/src/simplhdl/flows/quartusexport/quartusexportflow.py +157 -0
  7. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/flows/quartusflow.py +7 -6
  8. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/flows/questasim/questasimflow.py +12 -0
  9. simplhdl-0.5.1/src/simplhdl/generators/spd.py +367 -0
  10. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/plugins.py +1 -0
  11. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/pyedaa/__init__.py +11 -0
  12. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/pyedaa/design.py +15 -1
  13. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/quartus/project.tcl.j2 +16 -2
  14. simplhdl-0.5.1/src/simplhdl/resources/templates/xsim/__init__.py +0 -0
  15. simplhdl-0.4.0/src/simplhdl/__init__.py +0 -1
  16. simplhdl-0.4.0/src/simplhdl/generators/spd.py +0 -211
  17. {simplhdl-0.4.0 → simplhdl-0.5.1}/.github/workflows/publish.yml +0 -0
  18. {simplhdl-0.4.0 → simplhdl-0.5.1}/.gitignore +0 -0
  19. {simplhdl-0.4.0 → simplhdl-0.5.1}/.readthedocs.yaml +0 -0
  20. {simplhdl-0.4.0 → simplhdl-0.5.1}/LICENSE +0 -0
  21. {simplhdl-0.4.0 → simplhdl-0.5.1}/README.md +0 -0
  22. {simplhdl-0.4.0 → simplhdl-0.5.1}/docs/_static/simplhdl_dark.png +0 -0
  23. {simplhdl-0.4.0 → simplhdl-0.5.1}/docs/_static/simplhdl_light.png +0 -0
  24. {simplhdl-0.4.0 → simplhdl-0.5.1}/docs/_static/simplhdl_light_1.png +0 -0
  25. {simplhdl-0.4.0 → simplhdl-0.5.1}/docs/conf.py +0 -0
  26. {simplhdl-0.4.0 → simplhdl-0.5.1}/docs/drawing.svg +0 -0
  27. {simplhdl-0.4.0 → simplhdl-0.5.1}/docs/flows/ghdl.rst +0 -0
  28. {simplhdl-0.4.0 → simplhdl-0.5.1}/docs/flows/icarus.rst +0 -0
  29. {simplhdl-0.4.0 → simplhdl-0.5.1}/docs/flows/quartus.rst +0 -0
  30. {simplhdl-0.4.0 → simplhdl-0.5.1}/docs/flows/questasim.rst +0 -0
  31. {simplhdl-0.4.0 → simplhdl-0.5.1}/docs/flows/vcs.rst +0 -0
  32. {simplhdl-0.4.0 → simplhdl-0.5.1}/docs/flows/vivado.rst +0 -0
  33. {simplhdl-0.4.0 → simplhdl-0.5.1}/docs/flows/xsim.rst +0 -0
  34. {simplhdl-0.4.0 → simplhdl-0.5.1}/docs/flows.rst +0 -0
  35. {simplhdl-0.4.0 → simplhdl-0.5.1}/docs/index.rst +0 -0
  36. {simplhdl-0.4.0 → simplhdl-0.5.1}/docs/intel-ips.md +0 -0
  37. {simplhdl-0.4.0 → simplhdl-0.5.1}/docs/introduction.rst +0 -0
  38. {simplhdl-0.4.0 → simplhdl-0.5.1}/docs/plugins.rst +0 -0
  39. {simplhdl-0.4.0 → simplhdl-0.5.1}/docs/requirements.txt +0 -0
  40. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/adder/adder.yml +0 -0
  41. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/adder/hdl/adder.sv +0 -0
  42. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/adder/sim/testbench.sv +0 -0
  43. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/adder/sim/testbench.yml +0 -0
  44. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/adder/syn/build.yml +0 -0
  45. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/adder/syn/placement.xdc +0 -0
  46. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/adder/syn/timing.xdc +0 -0
  47. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/adder/syn/top.sv +0 -0
  48. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/alu.yml +0 -0
  49. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/hdl/add.sv +0 -0
  50. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/hdl/alu.sv +0 -0
  51. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/hdl/mul.sv +0 -0
  52. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/hdl/sub.sv +0 -0
  53. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/pyuvm/alu_vip/__init__.py +0 -0
  54. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/pyuvm/alu_vip/agent.py +0 -0
  55. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/pyuvm/alu_vip/aluif.py +0 -0
  56. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/pyuvm/alu_vip/driver.py +0 -0
  57. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/pyuvm/alu_vip/monitor.py +0 -0
  58. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/pyuvm/alu_vip/sequenceitem.py +0 -0
  59. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/pyuvm/alu_vip/sequencer.py +0 -0
  60. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/pyuvm/clock_vip/__init__.py +0 -0
  61. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/pyuvm/clock_vip/agent.py +0 -0
  62. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/pyuvm/clock_vip/clockif.py +0 -0
  63. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/pyuvm/pyuvm.yml +0 -0
  64. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/pyuvm/test/__init__.py +0 -0
  65. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/pyuvm/test/env.py +0 -0
  66. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/pyuvm/test/seq_lib.py +0 -0
  67. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/pyuvm/test/test.py +0 -0
  68. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/pyuvm/testbench.py +0 -0
  69. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/uvm/alu_vip/agent.svh +0 -0
  70. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/uvm/alu_vip/alu_vip.sv +0 -0
  71. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/uvm/alu_vip/alu_vip.yml +0 -0
  72. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/uvm/alu_vip/driver.svh +0 -0
  73. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/uvm/alu_vip/env.svh +0 -0
  74. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/uvm/alu_vip/monitor.svh +0 -0
  75. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/uvm/alu_vip/sequence_item.svh +0 -0
  76. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/uvm/tb_env/seq_lib/add_seq.svh +0 -0
  77. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/uvm/tb_env/seq_lib/base_seq.svh +0 -0
  78. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/uvm/tb_env/tb_env.sv +0 -0
  79. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/uvm/tb_env/tb_env.yml +0 -0
  80. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/uvm/tb_env/test/base_test.svh +0 -0
  81. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/uvm/tb_env/test/test_add.svh +0 -0
  82. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/uvm/testbench/alu_if.sv +0 -0
  83. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/uvm/testbench/testbench.sv +0 -0
  84. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/uvm/testbench/testbench.yml +0 -0
  85. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/sim/uvm/testcases/test_add/test_add.yml +0 -0
  86. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/syn/build.yml +0 -0
  87. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/syn/placement.xdc +0 -0
  88. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/alu/syn/timing.xdc +0 -0
  89. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/hello/build.sbt +0 -0
  90. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/hello/hello.yml +0 -0
  91. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/hello/src/main/scala/Hello.scala +0 -0
  92. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/hdl/hello/syn/build.yml +0 -0
  93. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/plugins/simple_parser/setup.py +0 -0
  94. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/plugins/simple_parser/src/simple_parser/__init__.py +0 -0
  95. {simplhdl-0.4.0 → simplhdl-0.5.1}/examples/plugins/simple_parser/src/simple_parser/simple_parser.py +0 -0
  96. {simplhdl-0.4.0 → simplhdl-0.5.1}/setup.cfg +0 -0
  97. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/SimplHDL.egg-info/dependency_links.txt +0 -0
  98. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/SimplHDL.egg-info/entry_points.txt +0 -0
  99. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/SimplHDL.egg-info/requires.txt +0 -0
  100. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/SimplHDL.egg-info/top_level.txt +0 -0
  101. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/__main__.py +0 -0
  102. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/cocotb.py +0 -0
  103. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/flow.py +0 -0
  104. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/flows/__init__.py +0 -0
  105. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/flows/encrypt/__init__.py +0 -0
  106. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/flows/encrypt/encryptflow.py +0 -0
  107. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/flows/flake8/flake8flow.py +0 -0
  108. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/flows/implementationflow.py +0 -0
  109. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/flows/lint/lintflow.py +0 -0
  110. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/flows/modelsim/__init__.py +0 -0
  111. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/flows/modelsim/modelsimflow.py +0 -0
  112. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/flows/quartusdse/__init__.py +0 -0
  113. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/flows/quartusdse/quartusdseflow.py +0 -0
  114. {simplhdl-0.4.0/src/simplhdl/flows/questasim → simplhdl-0.5.1/src/simplhdl/flows/quartusexport}/__init__.py +0 -0
  115. {simplhdl-0.4.0/src/simplhdl/flows/rivierapro → simplhdl-0.5.1/src/simplhdl/flows/questasim}/__init__.py +0 -0
  116. {simplhdl-0.4.0/src/simplhdl/flows/vcs → simplhdl-0.5.1/src/simplhdl/flows/rivierapro}/__init__.py +0 -0
  117. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/flows/rivierapro/rivieraproflow.py +0 -0
  118. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/flows/simulationflow.py +0 -0
  119. {simplhdl-0.4.0/src/simplhdl/flows/verible → simplhdl-0.5.1/src/simplhdl/flows/vcs}/__init__.py +0 -0
  120. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/flows/vcs/vcsflow.py +0 -0
  121. {simplhdl-0.4.0/src/simplhdl/flows/vsg → simplhdl-0.5.1/src/simplhdl/flows/verible}/__init__.py +0 -0
  122. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/flows/verible/veribleflow.py +0 -0
  123. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/flows/vivadoflow.py +0 -0
  124. {simplhdl-0.4.0/src/simplhdl/flows/xsim → simplhdl-0.5.1/src/simplhdl/flows/vsg}/__init__.py +0 -0
  125. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/flows/vsg/vsgflow.py +0 -0
  126. {simplhdl-0.4.0/src/simplhdl/generators → simplhdl-0.5.1/src/simplhdl/flows/xsim}/__init__.py +0 -0
  127. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/flows/xsim/xsimflow.py +0 -0
  128. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/generator.py +0 -0
  129. {simplhdl-0.4.0/src/simplhdl/parsers → simplhdl-0.5.1/src/simplhdl/generators}/__init__.py +0 -0
  130. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/generators/chisel.py +0 -0
  131. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/generators/ipxact.py +0 -0
  132. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/generators/systemrdl.py +0 -0
  133. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/info.py +0 -0
  134. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/parser.py +0 -0
  135. {simplhdl-0.4.0/src/simplhdl/resources → simplhdl-0.5.1/src/simplhdl/parsers}/__init__.py +0 -0
  136. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/parsers/fusesocparser.py +0 -0
  137. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/parsers/simplhdlparser.py +0 -0
  138. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/pyedaa/attributes.py +0 -0
  139. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/pyedaa/fileset.py +0 -0
  140. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/pyedaa/filetypes.py +0 -0
  141. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/pyedaa/project.py +0 -0
  142. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/pyedaa/target.py +0 -0
  143. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/pyedaa/vhdllibrary.py +0 -0
  144. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/repo.py +0 -0
  145. {simplhdl-0.4.0/src/simplhdl/resources/templates → simplhdl-0.5.1/src/simplhdl/resources}/__init__.py +0 -0
  146. {simplhdl-0.4.0/src/simplhdl/resources/templates/flake8 → simplhdl-0.5.1/src/simplhdl/resources/templates}/__init__.py +0 -0
  147. {simplhdl-0.4.0/src/simplhdl/resources/templates/modelsim → simplhdl-0.5.1/src/simplhdl/resources/templates/flake8}/__init__.py +0 -0
  148. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/flake8/setup.cfg.j2 +0 -0
  149. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/modelsim/Makefile.j2 +0 -0
  150. {simplhdl-0.4.0/src/simplhdl/resources/templates/quartus → simplhdl-0.5.1/src/simplhdl/resources/templates/modelsim}/__init__.py +0 -0
  151. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/modelsim/cocotb.mk.j2 +0 -0
  152. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/modelsim/dependencies.mk.j2 +0 -0
  153. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/modelsim/files.j2 +0 -0
  154. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/modelsim/fileset.j2 +0 -0
  155. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/modelsim/modelsim.tcl.j2 +0 -0
  156. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/modelsim/project.mk.j2 +0 -0
  157. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/modelsim/run.do.j2 +0 -0
  158. {simplhdl-0.4.0/src/simplhdl/resources/templates/questasim → simplhdl-0.5.1/src/simplhdl/resources/templates/quartus}/__init__.py +0 -0
  159. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/quartus/run.tcl.j2 +0 -0
  160. {simplhdl-0.4.0/src/simplhdl/resources/templates/rivierapro → simplhdl-0.5.1/src/simplhdl/resources/templates/questasim}/__init__.py +0 -0
  161. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/questasim/modelsim.tcl.j2 +0 -0
  162. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/questasim/project.qrun.j2 +0 -0
  163. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/questasim/visualizer.tcl.j2 +0 -0
  164. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/questasim/vsim-run.do.j2 +0 -0
  165. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/rivierapro/Makefile.j2 +0 -0
  166. {simplhdl-0.4.0/src/simplhdl/resources/templates/vcs → simplhdl-0.5.1/src/simplhdl/resources/templates/rivierapro}/__init__.py +0 -0
  167. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/rivierapro/cocotb.mk.j2 +0 -0
  168. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/rivierapro/dependencies.mk.j2 +0 -0
  169. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/rivierapro/files.j2 +0 -0
  170. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/rivierapro/fileset.j2 +0 -0
  171. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/rivierapro/project.mk.j2 +0 -0
  172. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/vcs/Makefile.j2 +0 -0
  173. {simplhdl-0.4.0/src/simplhdl/resources/templates/verible → simplhdl-0.5.1/src/simplhdl/resources/templates/vcs}/__init__.py +0 -0
  174. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/vcs/cocotb.mk.j2 +0 -0
  175. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/vcs/dependencies.mk.j2 +0 -0
  176. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/vcs/files.j2 +0 -0
  177. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/vcs/fileset.j2 +0 -0
  178. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/vcs/pli.tab.j2 +0 -0
  179. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/vcs/project.mk.j2 +0 -0
  180. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/vcs/synopsys_sim.setup.j2 +0 -0
  181. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/vcs/vcs.parameters.j2 +0 -0
  182. {simplhdl-0.4.0/src/simplhdl/resources/templates/vivado → simplhdl-0.5.1/src/simplhdl/resources/templates/verible}/__init__.py +0 -0
  183. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/verible/rules.cfg.j2 +0 -0
  184. {simplhdl-0.4.0/src/simplhdl/resources/templates/vsg → simplhdl-0.5.1/src/simplhdl/resources/templates/vivado}/__init__.py +0 -0
  185. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/vivado/launch_run.sh.j2 +0 -0
  186. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/vivado/project.tcl.j2 +0 -0
  187. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/vivado/run.tcl.j2 +0 -0
  188. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/vivado/steps.tcl.j2 +0 -0
  189. {simplhdl-0.4.0/src/simplhdl/resources/templates/xsim → simplhdl-0.5.1/src/simplhdl/resources/templates/vsg}/__init__.py +0 -0
  190. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/vsg/files.json.j2 +0 -0
  191. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/vsg/rules.yml.j2 +0 -0
  192. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/xsim/Makefile.j2 +0 -0
  193. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/xsim/cocotb.mk.j2 +0 -0
  194. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/xsim/dependencies.mk.j2 +0 -0
  195. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/xsim/files.j2 +0 -0
  196. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/xsim/fileset.j2 +0 -0
  197. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/resources/templates/xsim/project.mk.j2 +0 -0
  198. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/run.py +0 -0
  199. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/simplhdl.py +0 -0
  200. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/tools.py +0 -0
  201. {simplhdl-0.4.0 → simplhdl-0.5.1}/src/simplhdl/utils.py +0 -0
  202. {simplhdl-0.4.0 → simplhdl-0.5.1}/tests/test_dummy.py +0 -0
  203. {simplhdl-0.4.0 → simplhdl-0.5.1}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: SimplHDL
3
- Version: 0.4.0
3
+ Version: 0.5.1
4
4
  Summary: A framework for simulating and implementing HDL designs
5
5
  Author-email: Rasmus Grøndahl Olsen <simplhdl@gmail.com>
6
6
  Maintainer-email: Rasmus Grøndahl Olsen <simplhdl@gmail.com>
@@ -37,6 +37,7 @@ Classifier: Programming Language :: Python :: 3.9
37
37
  Classifier: Programming Language :: Python :: 3.10
38
38
  Classifier: Programming Language :: Python :: 3.11
39
39
  Classifier: Programming Language :: Python :: 3.12
40
+ Classifier: Programming Language :: Python :: 3.13
40
41
  Classifier: Intended Audience :: Developers
41
42
  Classifier: License :: OSI Approved :: MIT License
42
43
  Classifier: Operating System :: OS Independent
@@ -43,6 +43,7 @@ classifiers = [
43
43
  "Programming Language :: Python :: 3.10",
44
44
  "Programming Language :: Python :: 3.11",
45
45
  "Programming Language :: Python :: 3.12",
46
+ "Programming Language :: Python :: 3.13",
46
47
  "Intended Audience :: Developers",
47
48
  "License :: OSI Approved :: MIT License",
48
49
  "Operating System :: OS Independent",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: SimplHDL
3
- Version: 0.4.0
3
+ Version: 0.5.1
4
4
  Summary: A framework for simulating and implementing HDL designs
5
5
  Author-email: Rasmus Grøndahl Olsen <simplhdl@gmail.com>
6
6
  Maintainer-email: Rasmus Grøndahl Olsen <simplhdl@gmail.com>
@@ -37,6 +37,7 @@ Classifier: Programming Language :: Python :: 3.9
37
37
  Classifier: Programming Language :: Python :: 3.10
38
38
  Classifier: Programming Language :: Python :: 3.11
39
39
  Classifier: Programming Language :: Python :: 3.12
40
+ Classifier: Programming Language :: Python :: 3.13
40
41
  Classifier: Intended Audience :: Developers
41
42
  Classifier: License :: OSI Approved :: MIT License
42
43
  Classifier: Operating System :: OS Independent
@@ -111,6 +111,8 @@ src/simplhdl/flows/modelsim/__init__.py
111
111
  src/simplhdl/flows/modelsim/modelsimflow.py
112
112
  src/simplhdl/flows/quartusdse/__init__.py
113
113
  src/simplhdl/flows/quartusdse/quartusdseflow.py
114
+ src/simplhdl/flows/quartusexport/__init__.py
115
+ src/simplhdl/flows/quartusexport/quartusexportflow.py
114
116
  src/simplhdl/flows/questasim/__init__.py
115
117
  src/simplhdl/flows/questasim/questasimflow.py
116
118
  src/simplhdl/flows/rivierapro/__init__.py
@@ -0,0 +1 @@
1
+ __version__ = "0.5.1"
@@ -0,0 +1,157 @@
1
+ import shutil
2
+ import logging
3
+ import zipfile
4
+
5
+ from argparse import Namespace
6
+ from pathlib import Path
7
+
8
+ from simplhdl.flow import FlowFactory, FlowTools
9
+ from simplhdl.flows.implementationflow import ImplementationFlow
10
+ from simplhdl.flows.quartusflow import QuartusFlow
11
+ from simplhdl.resources.templates import quartus as templates
12
+ from simplhdl.flows.encrypt.encryptflow import encrypt
13
+ from simplhdl.pyedaa.project import Project
14
+ from simplhdl.pyedaa.attributes import UsedIn
15
+ from simplhdl.pyedaa import (
16
+ File,
17
+ HDLSearchPath,
18
+ HDLIncludeFile,
19
+ HDLSourceFile,
20
+ VerilogIncludeFile,
21
+ VerilogSourceFile,
22
+ SystemVerilogSourceFile,
23
+ VHDLSourceFile,
24
+ ConstraintFile,
25
+ QuartusQIPSpecificationFile,
26
+ QuartusIPSpecificationFile,
27
+ SettingFile
28
+ )
29
+
30
+ logger = logging.getLogger(__name__)
31
+
32
+
33
+ @FlowFactory.register('quartus-export')
34
+ class QuartusExportFlow(ImplementationFlow):
35
+
36
+ @classmethod
37
+ def parse_args(self, subparsers) -> None:
38
+ parser = subparsers.add_parser('quartus-export', help='Export Quartus project')
39
+ parser.add_argument(
40
+ '--encrypt',
41
+ action='store_true',
42
+ help="Encrypt HDL source files"
43
+ )
44
+ parser.add_argument(
45
+ '-o',
46
+ '--output',
47
+ action='store',
48
+ metavar='FILE',
49
+ dest='archivefile',
50
+ type=Path,
51
+ help="Output zip file"
52
+ )
53
+
54
+ def __init__(self, name, args: Namespace, project: Project, builddir: Path):
55
+ super().__init__(name, args, project, builddir)
56
+ self.vendors = ['mentor', 'synopsys']
57
+ self.templates = templates
58
+ self.tools.add(FlowTools.QUARTUS)
59
+
60
+ def copy_files(self):
61
+ seen = dict()
62
+ files = [f for f in self.project.DefaultDesign.Files() if 'implementation' in f[UsedIn]]
63
+ for file in files:
64
+ fileid = str(file.Path.resolve())
65
+ if fileid in seen:
66
+ file._path = seen.get(fileid)._path
67
+ continue
68
+ elif isinstance(file, SettingFile):
69
+ continue
70
+ elif isinstance(file, (ConstraintFile, QuartusQIPSpecificationFile)):
71
+ dest = self.builddir.joinpath('constraints', file.Path.name)
72
+ dest.parent.mkdir(parents=True, exist_ok=True)
73
+ shutil.copyfile(file.Path, dest)
74
+ elif isinstance(file, (HDLSearchPath, QuartusIPSpecificationFile)):
75
+ dest = file.Path
76
+ elif isinstance(file, (HDLSourceFile, HDLIncludeFile)):
77
+ if isinstance(file, HDLSourceFile):
78
+ dest = self.builddir.joinpath('rtl', file.Path.name)
79
+ else:
80
+ dest = self.builddir.joinpath('rtl', 'include', file.Path.name)
81
+ dest.parent.mkdir(parents=True, exist_ok=True)
82
+ if self.args.encrypt:
83
+ encrypt(file.Path, dest, language=get_language(file), vendors=self.vendors)
84
+ else:
85
+ shutil.copyfile(file.Path, dest)
86
+ else:
87
+ dest = self.builddir.joinpath('misc', file.Path.name)
88
+ dest.parent.mkdir(parents=True, exist_ok=True)
89
+ shutil.copyfile(file.Path, dest)
90
+ file._path = dest.absolute().relative_to(self.builddir.absolute())
91
+ # Convert to relative path
92
+ file._path = dest.absolute().relative_to(self.builddir.absolute())
93
+ seen[fileid] = file
94
+
95
+ def create_project(self) -> None:
96
+ args = Namespace(step='project', archive=False, gui=False)
97
+ quartus = QuartusFlow('quartus', args, self.project, self.builddir)
98
+ quartus.run()
99
+
100
+ def archive_project(self) -> None:
101
+ if self.args.archivefile:
102
+ archive(self.builddir, self.args.archivefile)
103
+ else:
104
+ output = self.builddir.parrent.joinpath(self.project.Name).with_suffix('.zip')
105
+ archive(self.builddir, output)
106
+ shutil.move(output, self.builddir)
107
+
108
+ def run(self) -> None:
109
+ self.copy_files()
110
+ self.create_project()
111
+ self.archive_project()
112
+
113
+ def is_tool_setup(self) -> None:
114
+ exit: bool = False
115
+ if shutil.which('quartus_sh') is None:
116
+ logger.error('quartus_sh: not found in PATH')
117
+ exit = True
118
+ if shutil.which('quartus') is None:
119
+ logger.error('quartus: not found in PATH')
120
+ exit = True
121
+ if exit:
122
+ raise FileNotFoundError("Quartus is not setup correctly")
123
+
124
+
125
+ def get_language(file: File) -> str:
126
+ fileMap = {
127
+ SystemVerilogSourceFile: 'systemverilog',
128
+ VerilogSourceFile: 'verilog',
129
+ VerilogIncludeFile: 'systemverilog',
130
+ VHDLSourceFile: 'vhdl'
131
+ }
132
+ return fileMap[file.FileType]
133
+
134
+
135
+ def archive(directory: Path, destination: Path) -> Path:
136
+ """
137
+ Recursively zip all contents of the given folder into a zip file.
138
+ The zip archive will contain a top-level folder with the same name
139
+ as the zip file (excluding the extension).
140
+
141
+ Parameters:
142
+ directory (Path): The folder whose contents will be zipped.
143
+ destination (Path): The path to the resulting zip file.
144
+ Its stem will be used as the top-level folder name.
145
+
146
+ Returns:
147
+ Path: The path to the created zip archive.
148
+ """
149
+ top_folder = destination.stem # top folder inside the archive
150
+ with zipfile.ZipFile(destination, 'w', zipfile.ZIP_DEFLATED) as zipf:
151
+ # Walk through all files in the directory
152
+ for file in directory.rglob('*'):
153
+ if file.is_file():
154
+ # Place each file under the top_folder
155
+ arcname = Path(top_folder) / file.relative_to(directory)
156
+ zipf.write(file, arcname=arcname)
157
+ return destination
@@ -18,7 +18,7 @@ from ..pyedaa import (QuartusIPSpecificationFile, VerilogIncludeFile, VerilogSou
18
18
  SystemVerilogSourceFile, VHDLSourceFile, ConstraintFile,
19
19
  EDIFNetlistFile, NetlistFile, SettingFile, QuartusSignalTapFile,
20
20
  QuartusIniFile, QuartusQIPSpecificationFile, QuartusQSYSSpecificationFile,
21
- HDLSearchPath, VerilogIncludeSearchPath)
21
+ HDLSearchPath, VerilogIncludeSearchPath, MemoryInitFile)
22
22
  from ..pyedaa.project import Project
23
23
  from ..pyedaa.attributes import UsedIn
24
24
 
@@ -62,10 +62,11 @@ class QuartusFlow(ImplementationFlow):
62
62
  def run(self) -> None:
63
63
  if self.args.archive:
64
64
  self.archive()
65
- self.validate()
66
- self.configure()
67
- self.generate()
68
- self.execute(self.args.step)
65
+ else:
66
+ self.validate()
67
+ self.configure()
68
+ self.generate()
69
+ self.execute(self.args.step)
69
70
 
70
71
  def archive(self) -> None:
71
72
  name = self.project.Name
@@ -79,7 +80,6 @@ class QuartusFlow(ImplementationFlow):
79
80
  raise Exception("Unknown value for argument --archive: {self.args.archive}")
80
81
  command = f"quartus_sh --archive -use_file_set {fileset} -revision {name} -no_discover -output {name}.qar {name}" # noqa
81
82
  sh(command.split(), output=True, cwd=self.builddir)
82
- raise SystemExit
83
83
 
84
84
  def validate(self):
85
85
  if self.project.DefaultDesign.DefaultFileSet.TopLevel is None:
@@ -113,6 +113,7 @@ class QuartusFlow(ImplementationFlow):
113
113
  QuartusQIPSpecificationFile=QuartusQIPSpecificationFile,
114
114
  QuartusQSYSSpecificationFile=QuartusQSYSSpecificationFile,
115
115
  QuartusIniFile=QuartusIniFile,
116
+ MemoryInitFile=MemoryInitFile,
116
117
  project=self.project,
117
118
  UsedIn=UsedIn)
118
119
  template = environment.get_template('run.tcl.j2')
@@ -16,6 +16,7 @@ from jinja2 import Template
16
16
  from simplhdl.pyedaa.project import Project
17
17
  from simplhdl.utils import sh, escape
18
18
  from simplhdl.flow import FlowFactory, FlowTools
19
+ from simplhdl.info import Info
19
20
  from simplhdl.resources.templates import questasim as questasimtemplates
20
21
  from simplhdl.flows.simulationflow import SimulationFlow, FileSetWalker
21
22
  from simplhdl.utils import generate_from_template
@@ -45,6 +46,11 @@ class QuestaSimFlow(SimulationFlow):
45
46
  default='',
46
47
  help="flow step to run"
47
48
  )
49
+ parser.add_argument(
50
+ '--info',
51
+ action='store_true',
52
+ help="Print project"
53
+ )
48
54
  parser.add_argument(
49
55
  '-w',
50
56
  '--wavedump',
@@ -225,6 +231,12 @@ class QuestaSimFlow(SimulationFlow):
225
231
  sh(['qrun', '-clean'], cwd=self.builddir, output=True)
226
232
  return
227
233
 
234
+ if self.args.info:
235
+ args = Namespace(files=False, filesets=False, libraries=False, hooks=False)
236
+ info = Info(self.name, args, self.project, self.builddir)
237
+ info.run()
238
+ return
239
+
228
240
  self.run_hooks('pre')
229
241
 
230
242
  if step == 'generate':
@@ -0,0 +1,367 @@
1
+ import re
2
+ import logging
3
+
4
+ from typing import List, Generator, Optional
5
+ from pathlib import Path
6
+ from xml.etree.ElementTree import Element, parse
7
+ from zipfile import ZipFile
8
+ from shutil import copy, copytree, rmtree
9
+
10
+ from simplhdl.pyedaa import (
11
+ File,
12
+ HDLSourceFile,
13
+ HDLSearchPath,
14
+ VerilogSourceFile,
15
+ SystemVerilogSourceFile,
16
+ VHDLSourceFile,
17
+ ConstraintFile,
18
+ HDLLibrary,
19
+ MemoryInitFile,
20
+ QuartusIPSpecificationFile,
21
+ QuartusIPCompressedSpecificationFile,
22
+ QuartusQSYSSpecificationFile,
23
+ QuartusQSYSCompressedSpecificationFile,
24
+ QuartusQIPSpecificationFile
25
+ )
26
+ from simplhdl.pyedaa.fileset import FileSet
27
+ from simplhdl.pyedaa.attributes import UsedIn
28
+ from simplhdl.flow import FlowBase, FlowCategory, FlowTools
29
+ from simplhdl.generator import GeneratorFactory, GeneratorBase, GeneratorError
30
+ from simplhdl.utils import md5write, md5check, sh
31
+
32
+ logger = logging.getLogger(__name__)
33
+
34
+
35
+ FILETYPE_MAP = {
36
+ 'SYSTEM_VERILOG': SystemVerilogSourceFile,
37
+ 'SYSTEM_VERILOG_ENCRYPT': SystemVerilogSourceFile,
38
+ 'VERILOG': VerilogSourceFile,
39
+ 'VERILOG_ENCRYPT': VerilogSourceFile,
40
+ 'VHDL': VHDLSourceFile,
41
+ 'VHDL_ENCRYPT': VHDLSourceFile,
42
+ 'SDC_ENTITY': ConstraintFile,
43
+ 'HEX': MemoryInitFile
44
+ }
45
+
46
+ TOOL_MAP = {
47
+ FlowTools.VCS: 'vcs',
48
+ FlowTools.NCSIM: 'ncsim',
49
+ FlowTools.QUESTASIM: 'modelsim',
50
+ FlowTools.MODELSIM: 'modelsim',
51
+ FlowTools.VCS: 'vcs',
52
+ FlowTools.RIVIERAPRO: 'riviera'
53
+ }
54
+
55
+
56
+ class Spd:
57
+
58
+ def __init__(self, filename: Path, flow: FlowBase, ip_path: Optional[Path] = None) -> None:
59
+ self._files = list()
60
+ self._filename = filename.absolute()
61
+ self.flow = flow
62
+ self.libraries = dict()
63
+ self.simulators = set()
64
+ spdfile = filename.parent.joinpath(filename.stem, filename.name).with_suffix('.spd')
65
+ if not spdfile.exists():
66
+ if ip_path:
67
+ command = f"qsys-generate --simulation=VERILOG --search-path={ip_path},$ {filename.absolute()}".split()
68
+ else:
69
+ command = f"qsys-generate --simulation=VERILOG {filename.absolute()}".split()
70
+ logger.info(f'Generate simulation files for {filename}')
71
+ sh(command, cwd=filename.parent)
72
+ if not spdfile.exists():
73
+ raise FileNotFoundError(f"{spdfile}: doesn't exits")
74
+ self.tree = parse(spdfile)
75
+ self.root = self.tree.getroot()
76
+ self.location = spdfile.parent.absolute()
77
+ for element in self.file_elements():
78
+ self._files.append(self.element_to_file(element))
79
+ if self.simulators and not self.supported(self.flow, self.simulators):
80
+ names = [n.name.capitalize() for n in self.flow.tools]
81
+ raise GeneratorError(f"Encrypted IP {filename} does not support {','.join(names)}")
82
+
83
+ def file_elements(self) -> Generator[Element, None, None]:
84
+ for f in self.root:
85
+ if f.tag == 'file':
86
+ properties = f.attrib
87
+ if 'simulator' in properties:
88
+ simulators = re.split(r'\s*,\s*', properties['simulator'])
89
+ if not self.supported(self.flow, simulators):
90
+ continue
91
+ yield f
92
+
93
+ def element_to_file(self, element: Element) -> File:
94
+ properties = element.attrib
95
+ if properties['path'].startswith('/'):
96
+ path = Path(properties['path'])
97
+ else:
98
+ path = Path(self.location, properties['path'])
99
+ libraryname = properties['library']
100
+ if libraryname not in self.libraries:
101
+ self.libraries[libraryname] = HDLLibrary(libraryname)
102
+ fileclass = FILETYPE_MAP.get(properties['type'], File)
103
+ if issubclass(fileclass, HDLSourceFile):
104
+ return fileclass(path=path, library=self.libraries[libraryname])
105
+ else:
106
+ return fileclass(path=path)
107
+
108
+ def supported(self, flow: FlowBase, simulators: List) -> bool:
109
+ self.simulators.update(simulators)
110
+ for tool in flow.tools:
111
+ if TOOL_MAP.get(tool, None) in simulators:
112
+ return True
113
+ return False
114
+
115
+ @property
116
+ def filesets(self):
117
+ filesets = list()
118
+ for library in self.libraries.values():
119
+ name = f"{self._filename}.{library.Name}"
120
+ fileset = FileSet(name, vhdlLibrary=library)
121
+ for file in self._files:
122
+ if isinstance(file, HDLSourceFile):
123
+ if file.Library == library:
124
+ fileset.AddFile(file)
125
+ else:
126
+ fileset.AddFile(file)
127
+ filesets.append(fileset)
128
+ return filesets
129
+
130
+
131
+ @GeneratorFactory.register('QuartusIP')
132
+ class QuartusIP(GeneratorBase):
133
+
134
+ def unpack_ip(self, filename: QuartusIPSpecificationFile) -> QuartusIPSpecificationFile: # noqa: C901
135
+ ipdir = self.builddir.joinpath('ips')
136
+ dest = ipdir.joinpath(filename.Path.name).with_suffix('')
137
+ md5file = dest.with_suffix('.md5')
138
+ ipdir.mkdir(exist_ok=True)
139
+ if filename.FileType == QuartusQSYSSpecificationFile:
140
+ filename = self.copy_qsys(filename, dest, md5file)
141
+ ipfiles = self.parse_qsys(filename)
142
+ if self.flow.category == FlowCategory.SIMULATION:
143
+ for ipfile in ipfiles:
144
+ spd = Spd(ipfile.Path, self.flow, dest.absolute())
145
+ parent = filename.FileSet
146
+ for fileset in reversed(spd.filesets):
147
+ # Add fileset to parent, then set parent to fileset to make a chain
148
+ parent._fileSets[fileset.Name] = fileset
149
+ parent = fileset
150
+ else:
151
+ fileset = FileSet(filename.Path.name, vhdlLibrary=self.project.DefaultDesign.DefaultFileSet.VHDLLibrary)
152
+ fileset.AddFiles(ipfiles)
153
+ filename.FileSet.AddFileSet(fileset)
154
+ elif filename.FileType == QuartusIPCompressedSpecificationFile:
155
+ update = True
156
+ if md5file.exists():
157
+ update = not md5check(filename.Path, filename=md5file)
158
+ if update:
159
+ with ZipFile(filename.Path, 'r') as zip:
160
+ zip.extractall(ipdir)
161
+ md5write(filename.Path, filename=md5file)
162
+ logger.debug(f"Copy {filename.Path} to {dest}")
163
+
164
+ if filename.Path.suffix == '.zip':
165
+ filename._path = dest.absolute()
166
+ else:
167
+ filename._path = dest.with_suffix('.ip').absolute()
168
+ filename._fileType = QuartusIPSpecificationFile
169
+
170
+ elif filename.FileType == QuartusIPSpecificationFile:
171
+ update = True
172
+ dir = filename.Path.with_suffix('')
173
+ if dir.exists():
174
+ if md5file.exists():
175
+ update = not md5check(filename.Path, dir, filename=md5file)
176
+ if update:
177
+ copy(str(filename.Path), str(dest.with_suffix('.ip')))
178
+ md5write(filename.Path, filename=md5file)
179
+ if dir.exists():
180
+ copytree(str(dir), str(dest.with_suffix('')), dirs_exist_ok=True)
181
+ md5write(filename.Path, dir, filename=md5file)
182
+ logger.debug(f"Copy {filename.Path} to {dest}")
183
+ filename._path = dest.with_suffix('.ip').absolute()
184
+ return filename
185
+
186
+ def run(self, flow: FlowBase) -> None:
187
+ seen = dict()
188
+ self.flow = flow
189
+ ip_dir = self.builddir.joinpath('ips')
190
+ qsys_dir = self.builddir.joinpath('qsys')
191
+ files = list(self.project.DefaultDesign.DefaultFileSet.Files(fileType=QuartusIPSpecificationFile))
192
+ # files = filter_duplicated_files(files)
193
+ if not flow.category == FlowCategory.DEFAULT:
194
+ for file in files:
195
+ # The second time we see a file it is already proccessed and we just
196
+ # Update the file path
197
+ fileid = str(file.Path.resolve())
198
+ if fileid in seen:
199
+ file._path = seen.get(fileid)._path
200
+ continue
201
+ if file.FileType == QuartusQIPSpecificationFile:
202
+ continue
203
+ elif file.FileType == QuartusIPCompressedSpecificationFile:
204
+ file = unpack_ipfile(file, ip_dir)
205
+ elif file.FileType == QuartusIPSpecificationFile:
206
+ file = copy_ipfile(file, ip_dir)
207
+ elif file.FileType == QuartusQSYSCompressedSpecificationFile:
208
+ file = unpack_qsysfile(file, qsys_dir)
209
+ elif file.FileType == QuartusQSYSSpecificationFile:
210
+ file = copy_qsysfile(file, qsys_dir)
211
+ parse_file(file, flow, self.project.DefaultDesign.DefaultFileSet.VHDLLibrary)
212
+ # register the file as seen
213
+ seen[fileid] = file
214
+
215
+
216
+ def parse_qsys(filename: QuartusQSYSSpecificationFile) -> List[File]:
217
+ """
218
+ Search for IP files in a QSYS file and return a list of QuartusIPSpecificationFile objects.
219
+ """
220
+ files = list()
221
+ with filename.Path.open() as file:
222
+ lines = file.readlines()
223
+ for line in lines:
224
+ m = re.search(r'<ipxact:value>(.*\.ip)</ipxact:value>', line)
225
+ if m:
226
+ ipfile = filename.Path.parent.joinpath(m.group(1))
227
+ if ipfile.exists():
228
+ files.append(QuartusIPSpecificationFile(ipfile))
229
+ else:
230
+ logger.warning(f"File {ipfile} not found")
231
+ return files
232
+
233
+
234
+ def qsys_to_fileset(file: QuartusQSYSSpecificationFile, flow: FlowBase, library) -> FileSet:
235
+ """
236
+ Parse a QSYS file and return a FileSet object.
237
+ """
238
+ ipfiles = parse_qsys(file)
239
+ if flow.category == FlowCategory.SIMULATION:
240
+ parent = file.FileSet
241
+ for ipfile in ipfiles + [file]:
242
+ spd = Spd(ipfile.Path, flow, file.Path.parent.absolute())
243
+ for fileset in reversed(spd.filesets):
244
+ # Add fileset to parent, then set parent to fileset to make a chain
245
+ parent._fileSets[fileset.Name] = fileset
246
+ parent = fileset
247
+ elif flow.category == FlowCategory.IMPLEMENTATION:
248
+ # NOTE: Some qsys require a search path to find the HEX files
249
+ searchpath = HDLSearchPath(file.Path.parent)
250
+ searchpath[UsedIn] = {'implementation'}
251
+ fileset = FileSet(file.Path.name, vhdlLibrary=library)
252
+ fileset.AddFiles(ipfiles + [searchpath])
253
+ file.FileSet.AddFileSet(fileset)
254
+
255
+
256
+ def parse_file(file: File, flow: FlowBase, library) -> FileSet:
257
+ if file.FileType == QuartusQSYSSpecificationFile:
258
+ return qsys_to_fileset(file, flow, library)
259
+ elif file.FileType == QuartusIPSpecificationFile:
260
+ if flow.category == FlowCategory.SIMULATION:
261
+ spd = Spd(file.Path, flow)
262
+ parent = file.FileSet
263
+ for fileset in reversed(spd.filesets):
264
+ # Add fileset to parent, then set parent to fileset to make a chain
265
+ parent._fileSets[fileset.Name] = fileset
266
+ parent = fileset
267
+ else:
268
+ return file
269
+ else:
270
+ raise GeneratorError(f"Unsupported file type: {file.FileType}")
271
+
272
+
273
+ def copy_ipfile(file: QuartusIPSpecificationFile, dest: Path) -> QuartusIPSpecificationFile:
274
+ """
275
+ Copy IP files to a directory and return a new QuartusIPSpecificationFile object with the new path.
276
+ """
277
+ dest.mkdir(parents=True, exist_ok=True)
278
+ md5file = dest.joinpath(file.Path.name).with_suffix('.md5')
279
+ srcdir = file.Path.with_suffix('')
280
+ destdir = dest.joinpath(file.Path.name).with_suffix('')
281
+ destfile = dest.joinpath(file.Path.name)
282
+ if srcdir.exists():
283
+ if not md5file.exists() or not md5check(file.Path, srcdir, filename=md5file):
284
+ logger.info(f"Copy {file.Path} to {destfile}")
285
+ logger.info(f"Copy {srcdir} to {destdir}")
286
+ copy(str(file.Path), str(destfile))
287
+ copytree(str(srcdir), str(destdir), dirs_exist_ok=True)
288
+ md5write(file.Path, srcdir, filename=md5file)
289
+ else:
290
+ if not md5file.exists() or not md5check(file.Path, filename=md5file):
291
+ logger.info(f"Copy {file.Path} to {destfile}")
292
+ rmtree(destdir, ignore_errors=True)
293
+ copy(str(file.Path), str(destfile))
294
+ md5write(file.Path, filename=md5file)
295
+ file._fileType = QuartusIPSpecificationFile
296
+ file._path = destfile.resolve()
297
+ return file
298
+
299
+
300
+ def copy_qsysfile(file: QuartusQSYSSpecificationFile, dest: Path) -> QuartusQSYSSpecificationFile:
301
+ """
302
+ Copy QSYS files to a directory and return a new QuartusQSYSSpecificationFile object with the new path.
303
+ """
304
+ md5file = dest.joinpath(file.Path.name).with_suffix('.md5')
305
+ qsysdir = dest.joinpath(file.Path.name)
306
+ src = file.Path.parent
307
+ if not md5file.exists() or not md5check(src, filename=md5file):
308
+ copytree(str(src), str(qsysdir), dirs_exist_ok=True)
309
+ md5write(src, filename=md5file)
310
+ file._fileType = QuartusQSYSSpecificationFile
311
+ file._path = qsysdir.joinpath(file.Path.name).with_suffix('.qsys').resolve()
312
+ if file.Path.exists():
313
+ return file
314
+ else:
315
+ raise FileNotFoundError(f"{file.Path}: doesn't exits")
316
+
317
+
318
+ def unpack_ipfile(file: QuartusIPCompressedSpecificationFile, dest: Path) -> QuartusIPSpecificationFile:
319
+ """
320
+ Unpack IP files to a directory and return a new QuartusIPSpecificationFile object with the new path.
321
+ """
322
+ unpack(file.Path, dest)
323
+ file._fileType = QuartusIPSpecificationFile
324
+ file._path = dest.joinpath(file.Path.name).with_suffix('').resolve()
325
+ if file.Path.exists():
326
+ return file
327
+ else:
328
+ raise FileNotFoundError(f"{file.Path.resolve()}: doesn't exits")
329
+
330
+
331
+ def unpack_qsysfile(file: QuartusQSYSCompressedSpecificationFile, dest: Path) -> QuartusQSYSSpecificationFile:
332
+ """
333
+ Unpack QSYS files to a directory and return a new QuartusQSYSSpecificationFile object with the new path.
334
+ """
335
+ dest = dest.joinpath(file.Path.name).with_suffix('').with_suffix('')
336
+ unpack(file.Path, dest)
337
+ file._fileType = QuartusQSYSSpecificationFile
338
+ file._path = dest.joinpath(file.Path.name).with_suffix('').resolve()
339
+ if file.Path.exists():
340
+ return file
341
+ else:
342
+ raise FileNotFoundError(f"{file.Path}: doesn't exits")
343
+
344
+
345
+ def unpack(file: Path, dest: Path) -> None:
346
+ """
347
+ Unpack a file to a directory and return the new path.
348
+ """
349
+ md5file = dest.joinpath(file.name).with_suffix('.md5')
350
+ if not md5file.exists() or not md5check(file, filename=md5file):
351
+ logger.info(f"Unpack {file} to {dest}")
352
+ with ZipFile(file, 'r') as zip:
353
+ zip.extractall(dest)
354
+ md5write(file, filename=md5file)
355
+
356
+
357
+ def filter_duplicated_files(files: List[File]) -> List[File]:
358
+ """
359
+ Filter duplicated files in a list of files.
360
+ """
361
+ unique_files = set(files)
362
+ filtered_files = dict()
363
+ for file in unique_files:
364
+ # if file.Path.name in filtered_files:
365
+ # logger.warning(f"Duplicate files - {file.Path} will override {filtered_files[file.Path.name].Path}")
366
+ filtered_files[file.Path.name] = file
367
+ return list(filtered_files.values())
@@ -30,6 +30,7 @@ def load_builtin_plugins() -> None:
30
30
  import_module('simplhdl.flows.xsim.xsimflow')
31
31
  import_module('simplhdl.flows.rivierapro.rivieraproflow')
32
32
  import_module('simplhdl.flows.quartusdse.quartusdseflow')
33
+ import_module('simplhdl.flows.quartusexport.quartusexportflow')
33
34
  import_module('simplhdl.flows.encrypt.encryptflow')
34
35
  import_module('simplhdl.flows.vsg.vsgflow')
35
36
  import_module('simplhdl.flows.verible.veribleflow')
@@ -154,6 +154,10 @@ class QuartusQSYSSpecificationFile(QuartusIPSpecificationFile):
154
154
  pass
155
155
 
156
156
 
157
+ class QuartusQSYSCompressedSpecificationFile(QuartusQSYSSpecificationFile):
158
+ pass
159
+
160
+
157
161
  class QuartusQIPSpecificationFile(QuartusIPSpecificationFile):
158
162
  pass
159
163
 
@@ -165,6 +169,13 @@ class QuartusIniFile(File):
165
169
  self[UsedIn] = {IMPLEMENTATION}
166
170
 
167
171
 
172
+ class QuartusSourceTCLFile(TCLSourceFile):
173
+ def _registerAttributes(self):
174
+ super()._registerAttributes()
175
+ FileMixIn._registerAttributes(self)
176
+ self[UsedIn] = {IMPLEMENTATION}
177
+
178
+
168
179
  class VivadoIPSpecificationFile(IPSpecificationFile):
169
180
  pass
170
181