siliconcompiler 0.32.3__py3-none-any.whl → 0.33.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. siliconcompiler/__init__.py +19 -2
  2. siliconcompiler/_common.py +5 -0
  3. siliconcompiler/_metadata.py +1 -1
  4. siliconcompiler/apps/sc.py +2 -2
  5. siliconcompiler/apps/sc_install.py +10 -3
  6. siliconcompiler/apps/sc_issue.py +1 -1
  7. siliconcompiler/apps/sc_remote.py +10 -5
  8. siliconcompiler/apps/sc_show.py +2 -2
  9. siliconcompiler/apps/utils/replay.py +5 -3
  10. siliconcompiler/asic.py +120 -0
  11. siliconcompiler/checklist.py +150 -0
  12. siliconcompiler/core.py +299 -299
  13. siliconcompiler/flowgraph.py +803 -515
  14. siliconcompiler/fpga.py +84 -0
  15. siliconcompiler/metric.py +479 -0
  16. siliconcompiler/optimizer/vizier.py +2 -3
  17. siliconcompiler/package/__init__.py +29 -6
  18. siliconcompiler/pdk.py +415 -0
  19. siliconcompiler/record.py +453 -0
  20. siliconcompiler/remote/client.py +15 -5
  21. siliconcompiler/remote/schema.py +116 -112
  22. siliconcompiler/remote/server.py +9 -6
  23. siliconcompiler/report/dashboard/cli/__init__.py +14 -721
  24. siliconcompiler/report/dashboard/cli/board.py +899 -0
  25. siliconcompiler/report/dashboard/web/__init__.py +10 -10
  26. siliconcompiler/report/dashboard/web/components/__init__.py +5 -4
  27. siliconcompiler/report/dashboard/web/components/flowgraph.py +3 -3
  28. siliconcompiler/report/dashboard/web/components/graph.py +6 -3
  29. siliconcompiler/report/dashboard/web/state.py +1 -1
  30. siliconcompiler/report/dashboard/web/utils/__init__.py +4 -3
  31. siliconcompiler/report/html_report.py +2 -3
  32. siliconcompiler/report/report.py +22 -11
  33. siliconcompiler/report/summary_image.py +1 -1
  34. siliconcompiler/report/summary_table.py +3 -3
  35. siliconcompiler/report/utils.py +21 -14
  36. siliconcompiler/scheduler/__init__.py +234 -1206
  37. siliconcompiler/scheduler/run_node.py +2 -1
  38. siliconcompiler/scheduler/send_messages.py +11 -5
  39. siliconcompiler/scheduler/slurm.py +11 -44
  40. siliconcompiler/scheduler/taskscheduler.py +320 -0
  41. siliconcompiler/schema/__init__.py +19 -2
  42. siliconcompiler/schema/baseschema.py +493 -0
  43. siliconcompiler/schema/cmdlineschema.py +250 -0
  44. siliconcompiler/{sphinx_ext → schema/docs}/__init__.py +3 -1
  45. siliconcompiler/{sphinx_ext → schema/docs}/dynamicgen.py +63 -81
  46. siliconcompiler/{sphinx_ext → schema/docs}/schemagen.py +73 -85
  47. siliconcompiler/{sphinx_ext → schema/docs}/utils.py +12 -13
  48. siliconcompiler/schema/editableschema.py +136 -0
  49. siliconcompiler/schema/journalingschema.py +238 -0
  50. siliconcompiler/schema/namedschema.py +41 -0
  51. siliconcompiler/schema/packageschema.py +101 -0
  52. siliconcompiler/schema/parameter.py +791 -0
  53. siliconcompiler/schema/parametertype.py +323 -0
  54. siliconcompiler/schema/parametervalue.py +736 -0
  55. siliconcompiler/schema/safeschema.py +37 -0
  56. siliconcompiler/schema/schema_cfg.py +109 -1789
  57. siliconcompiler/schema/utils.py +5 -68
  58. siliconcompiler/schema_obj.py +119 -0
  59. siliconcompiler/tool.py +1416 -0
  60. siliconcompiler/tools/_common/__init__.py +6 -10
  61. siliconcompiler/tools/_common/asic.py +5 -5
  62. siliconcompiler/tools/_common/sdc/sc_constraints.sdc +1 -1
  63. siliconcompiler/tools/bluespec/convert.py +9 -8
  64. siliconcompiler/tools/builtin/_common.py +9 -2
  65. siliconcompiler/tools/builtin/concatenate.py +7 -3
  66. siliconcompiler/tools/builtin/minimum.py +7 -2
  67. siliconcompiler/tools/builtin/mux.py +8 -2
  68. siliconcompiler/tools/builtin/nop.py +7 -2
  69. siliconcompiler/tools/builtin/verify.py +11 -5
  70. siliconcompiler/tools/chisel/convert.py +10 -10
  71. siliconcompiler/tools/genfasm/bitstream.py +3 -3
  72. siliconcompiler/tools/ghdl/convert.py +1 -1
  73. siliconcompiler/tools/icarus/compile.py +4 -4
  74. siliconcompiler/tools/icepack/bitstream.py +6 -1
  75. siliconcompiler/tools/klayout/convert_drc_db.py +5 -0
  76. siliconcompiler/tools/klayout/drc.py +2 -2
  77. siliconcompiler/tools/klayout/klayout_export.py +0 -1
  78. siliconcompiler/tools/klayout/klayout_show.py +6 -6
  79. siliconcompiler/tools/klayout/klayout_utils.py +15 -22
  80. siliconcompiler/tools/netgen/count_lvs.py +2 -2
  81. siliconcompiler/tools/netgen/lvs.py +1 -1
  82. siliconcompiler/tools/nextpnr/apr.py +6 -1
  83. siliconcompiler/tools/nextpnr/nextpnr.py +4 -4
  84. siliconcompiler/tools/openroad/_apr.py +15 -2
  85. siliconcompiler/tools/openroad/rdlroute.py +3 -3
  86. siliconcompiler/tools/openroad/scripts/apr/postamble.tcl +1 -1
  87. siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +5 -5
  88. siliconcompiler/tools/openroad/scripts/apr/sc_antenna_repair.tcl +2 -2
  89. siliconcompiler/tools/openroad/scripts/apr/sc_clock_tree_synthesis.tcl +2 -2
  90. siliconcompiler/tools/openroad/scripts/apr/sc_detailed_placement.tcl +2 -2
  91. siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +2 -2
  92. siliconcompiler/tools/openroad/scripts/apr/sc_endcap_tapcell_insertion.tcl +2 -2
  93. siliconcompiler/tools/openroad/scripts/apr/sc_fillercell_insertion.tcl +2 -2
  94. siliconcompiler/tools/openroad/scripts/apr/sc_fillmetal_insertion.tcl +2 -2
  95. siliconcompiler/tools/openroad/scripts/apr/sc_global_placement.tcl +2 -2
  96. siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +2 -2
  97. siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +3 -9
  98. siliconcompiler/tools/openroad/scripts/apr/sc_macro_placement.tcl +3 -3
  99. siliconcompiler/tools/openroad/scripts/apr/sc_metrics.tcl +2 -2
  100. siliconcompiler/tools/openroad/scripts/apr/sc_pin_placement.tcl +2 -2
  101. siliconcompiler/tools/openroad/scripts/apr/sc_power_grid.tcl +2 -2
  102. siliconcompiler/tools/openroad/scripts/apr/sc_repair_design.tcl +2 -2
  103. siliconcompiler/tools/openroad/scripts/apr/sc_repair_timing.tcl +2 -2
  104. siliconcompiler/tools/openroad/scripts/apr/sc_write_data.tcl +2 -2
  105. siliconcompiler/tools/openroad/scripts/common/procs.tcl +75 -1
  106. siliconcompiler/tools/openroad/scripts/common/read_input_files.tcl +1 -7
  107. siliconcompiler/tools/openroad/scripts/common/screenshot.tcl +2 -2
  108. siliconcompiler/tools/openroad/scripts/common/write_images.tcl +28 -3
  109. siliconcompiler/tools/openroad/scripts/sc_rcx.tcl +1 -1
  110. siliconcompiler/tools/openroad/scripts/sc_rdlroute.tcl +3 -3
  111. siliconcompiler/tools/openroad/scripts/sc_show.tcl +6 -6
  112. siliconcompiler/tools/opensta/scripts/sc_timing.tcl +10 -0
  113. siliconcompiler/tools/opensta/timing.py +11 -0
  114. siliconcompiler/tools/slang/__init__.py +13 -13
  115. siliconcompiler/tools/slang/elaborate.py +6 -6
  116. siliconcompiler/tools/slang/lint.py +1 -3
  117. siliconcompiler/tools/surelog/parse.py +4 -4
  118. siliconcompiler/tools/sv2v/convert.py +20 -3
  119. siliconcompiler/tools/verilator/compile.py +2 -2
  120. siliconcompiler/tools/verilator/verilator.py +3 -3
  121. siliconcompiler/tools/vpr/_xml_constraint.py +8 -8
  122. siliconcompiler/tools/vpr/place.py +1 -1
  123. siliconcompiler/tools/vpr/route.py +4 -4
  124. siliconcompiler/tools/vpr/screenshot.py +1 -1
  125. siliconcompiler/tools/vpr/show.py +5 -5
  126. siliconcompiler/tools/vpr/vpr.py +24 -24
  127. siliconcompiler/tools/xdm/convert.py +2 -2
  128. siliconcompiler/tools/xyce/simulate.py +1 -1
  129. siliconcompiler/tools/yosys/prepareLib.py +2 -2
  130. siliconcompiler/tools/yosys/sc_synth_asic.tcl +111 -63
  131. siliconcompiler/tools/yosys/screenshot.py +1 -1
  132. siliconcompiler/tools/yosys/syn_asic.py +7 -7
  133. siliconcompiler/toolscripts/_tools.json +12 -10
  134. siliconcompiler/toolscripts/rhel8/install-chisel.sh +9 -2
  135. siliconcompiler/toolscripts/rhel8/install-icarus.sh +10 -3
  136. siliconcompiler/toolscripts/rhel8/install-klayout.sh +8 -1
  137. siliconcompiler/toolscripts/rhel8/install-magic.sh +9 -2
  138. siliconcompiler/toolscripts/rhel8/install-montage.sh +1 -1
  139. siliconcompiler/toolscripts/rhel8/install-netgen.sh +9 -2
  140. siliconcompiler/toolscripts/rhel8/install-slang.sh +11 -4
  141. siliconcompiler/toolscripts/rhel8/install-surelog.sh +9 -2
  142. siliconcompiler/toolscripts/rhel8/install-sv2v.sh +11 -4
  143. siliconcompiler/toolscripts/rhel8/install-verible.sh +11 -3
  144. siliconcompiler/toolscripts/rhel8/install-verilator.sh +10 -3
  145. siliconcompiler/toolscripts/rhel8/install-xyce.sh +15 -10
  146. siliconcompiler/toolscripts/rhel9/install-chisel.sh +9 -2
  147. siliconcompiler/toolscripts/rhel9/install-ghdl.sh +9 -2
  148. siliconcompiler/toolscripts/rhel9/install-gtkwave.sh +10 -3
  149. siliconcompiler/toolscripts/rhel9/install-icarus.sh +10 -3
  150. siliconcompiler/toolscripts/rhel9/install-klayout.sh +8 -1
  151. siliconcompiler/toolscripts/rhel9/install-magic.sh +9 -2
  152. siliconcompiler/toolscripts/rhel9/install-montage.sh +1 -1
  153. siliconcompiler/toolscripts/rhel9/install-netgen.sh +9 -2
  154. siliconcompiler/toolscripts/rhel9/install-openroad.sh +16 -3
  155. siliconcompiler/toolscripts/rhel9/install-opensta.sh +17 -5
  156. siliconcompiler/toolscripts/rhel9/install-slang.sh +11 -4
  157. siliconcompiler/toolscripts/rhel9/install-surelog.sh +9 -2
  158. siliconcompiler/toolscripts/rhel9/install-sv2v.sh +11 -4
  159. siliconcompiler/toolscripts/rhel9/install-verible.sh +11 -3
  160. siliconcompiler/toolscripts/rhel9/install-verilator.sh +10 -3
  161. siliconcompiler/toolscripts/rhel9/install-vpr.sh +9 -2
  162. siliconcompiler/toolscripts/rhel9/install-xdm.sh +10 -2
  163. siliconcompiler/toolscripts/rhel9/install-xyce.sh +15 -10
  164. siliconcompiler/toolscripts/rhel9/install-yosys-moosic.sh +9 -2
  165. siliconcompiler/toolscripts/rhel9/install-yosys-parmys.sh +10 -3
  166. siliconcompiler/toolscripts/rhel9/install-yosys-slang.sh +10 -2
  167. siliconcompiler/toolscripts/rhel9/install-yosys.sh +9 -2
  168. siliconcompiler/toolscripts/ubuntu20/install-bambu.sh +10 -2
  169. siliconcompiler/toolscripts/ubuntu20/install-bluespec.sh +10 -3
  170. siliconcompiler/toolscripts/ubuntu20/install-chisel.sh +9 -2
  171. siliconcompiler/toolscripts/ubuntu20/install-ghdl.sh +9 -2
  172. siliconcompiler/toolscripts/ubuntu20/install-gtkwave.sh +9 -2
  173. siliconcompiler/toolscripts/ubuntu20/install-icarus.sh +9 -2
  174. siliconcompiler/toolscripts/ubuntu20/install-icepack.sh +9 -2
  175. siliconcompiler/toolscripts/ubuntu20/install-klayout.sh +8 -1
  176. siliconcompiler/toolscripts/ubuntu20/install-magic.sh +9 -2
  177. siliconcompiler/toolscripts/ubuntu20/install-montage.sh +1 -1
  178. siliconcompiler/toolscripts/ubuntu20/install-netgen.sh +9 -2
  179. siliconcompiler/toolscripts/ubuntu20/install-nextpnr.sh +9 -2
  180. siliconcompiler/toolscripts/ubuntu20/install-openroad.sh +16 -3
  181. siliconcompiler/toolscripts/ubuntu20/install-opensta.sh +16 -5
  182. siliconcompiler/toolscripts/ubuntu20/install-slang.sh +11 -4
  183. siliconcompiler/toolscripts/ubuntu20/install-slurm.sh +9 -2
  184. siliconcompiler/toolscripts/ubuntu20/install-surelog.sh +10 -2
  185. siliconcompiler/toolscripts/ubuntu20/install-sv2v.sh +11 -4
  186. siliconcompiler/toolscripts/ubuntu20/install-verible.sh +11 -3
  187. siliconcompiler/toolscripts/ubuntu20/install-verilator.sh +9 -2
  188. siliconcompiler/toolscripts/ubuntu20/install-xdm.sh +10 -2
  189. siliconcompiler/toolscripts/ubuntu20/install-xyce.sh +13 -8
  190. siliconcompiler/toolscripts/ubuntu20/install-yosys-moosic.sh +9 -2
  191. siliconcompiler/toolscripts/ubuntu20/install-yosys.sh +9 -2
  192. siliconcompiler/toolscripts/ubuntu22/install-bambu.sh +10 -2
  193. siliconcompiler/toolscripts/ubuntu22/install-bluespec.sh +10 -3
  194. siliconcompiler/toolscripts/ubuntu22/install-chisel.sh +9 -2
  195. siliconcompiler/toolscripts/ubuntu22/install-ghdl.sh +9 -2
  196. siliconcompiler/toolscripts/ubuntu22/install-gtkwave.sh +9 -2
  197. siliconcompiler/toolscripts/ubuntu22/install-icarus.sh +9 -2
  198. siliconcompiler/toolscripts/ubuntu22/install-icepack.sh +9 -2
  199. siliconcompiler/toolscripts/ubuntu22/install-klayout.sh +8 -1
  200. siliconcompiler/toolscripts/ubuntu22/install-magic.sh +9 -2
  201. siliconcompiler/toolscripts/ubuntu22/install-montage.sh +1 -1
  202. siliconcompiler/toolscripts/ubuntu22/install-netgen.sh +9 -2
  203. siliconcompiler/toolscripts/ubuntu22/install-nextpnr.sh +9 -2
  204. siliconcompiler/toolscripts/ubuntu22/install-openroad.sh +16 -3
  205. siliconcompiler/toolscripts/ubuntu22/install-opensta.sh +17 -5
  206. siliconcompiler/toolscripts/ubuntu22/install-slang.sh +11 -4
  207. siliconcompiler/toolscripts/ubuntu22/install-slurm.sh +9 -2
  208. siliconcompiler/toolscripts/ubuntu22/install-surelog.sh +10 -2
  209. siliconcompiler/toolscripts/ubuntu22/install-sv2v.sh +11 -4
  210. siliconcompiler/toolscripts/ubuntu22/install-verible.sh +11 -3
  211. siliconcompiler/toolscripts/ubuntu22/install-verilator.sh +9 -2
  212. siliconcompiler/toolscripts/ubuntu22/install-vpr.sh +9 -4
  213. siliconcompiler/toolscripts/ubuntu22/install-xdm.sh +10 -2
  214. siliconcompiler/toolscripts/ubuntu22/install-xyce.sh +13 -8
  215. siliconcompiler/toolscripts/ubuntu22/install-yosys-moosic.sh +9 -2
  216. siliconcompiler/toolscripts/ubuntu22/install-yosys-parmys.sh +10 -3
  217. siliconcompiler/toolscripts/ubuntu22/install-yosys-slang.sh +10 -2
  218. siliconcompiler/toolscripts/ubuntu22/install-yosys.sh +9 -2
  219. siliconcompiler/toolscripts/ubuntu24/install-bambu.sh +12 -4
  220. siliconcompiler/toolscripts/ubuntu24/install-bluespec.sh +10 -3
  221. siliconcompiler/toolscripts/ubuntu24/install-chisel.sh +9 -2
  222. siliconcompiler/toolscripts/ubuntu24/install-ghdl.sh +9 -2
  223. siliconcompiler/toolscripts/ubuntu24/install-gtkwave.sh +9 -2
  224. siliconcompiler/toolscripts/ubuntu24/install-icarus.sh +9 -2
  225. siliconcompiler/toolscripts/ubuntu24/install-icepack.sh +9 -2
  226. siliconcompiler/toolscripts/ubuntu24/install-klayout.sh +8 -1
  227. siliconcompiler/toolscripts/ubuntu24/install-magic.sh +9 -2
  228. siliconcompiler/toolscripts/ubuntu24/install-montage.sh +1 -1
  229. siliconcompiler/toolscripts/ubuntu24/install-netgen.sh +9 -2
  230. siliconcompiler/toolscripts/ubuntu24/install-nextpnr.sh +9 -2
  231. siliconcompiler/toolscripts/ubuntu24/install-openroad.sh +16 -3
  232. siliconcompiler/toolscripts/ubuntu24/install-opensta.sh +17 -5
  233. siliconcompiler/toolscripts/ubuntu24/install-slang.sh +11 -4
  234. siliconcompiler/toolscripts/ubuntu24/install-slurm.sh +9 -2
  235. siliconcompiler/toolscripts/ubuntu24/install-surelog.sh +10 -2
  236. siliconcompiler/toolscripts/ubuntu24/install-sv2v.sh +11 -4
  237. siliconcompiler/toolscripts/ubuntu24/install-verible.sh +11 -3
  238. siliconcompiler/toolscripts/ubuntu24/install-verilator.sh +9 -2
  239. siliconcompiler/toolscripts/ubuntu24/install-vpr.sh +9 -4
  240. siliconcompiler/toolscripts/ubuntu24/install-xdm.sh +10 -2
  241. siliconcompiler/toolscripts/ubuntu24/install-xyce.sh +13 -8
  242. siliconcompiler/toolscripts/ubuntu24/install-yosys-moosic.sh +9 -2
  243. siliconcompiler/toolscripts/ubuntu24/install-yosys-parmys.sh +10 -3
  244. siliconcompiler/toolscripts/ubuntu24/install-yosys-slang.sh +10 -2
  245. siliconcompiler/toolscripts/ubuntu24/install-yosys.sh +9 -2
  246. siliconcompiler/utils/__init__.py +19 -112
  247. siliconcompiler/utils/flowgraph.py +244 -0
  248. siliconcompiler/{issue.py → utils/issue.py} +18 -25
  249. siliconcompiler/utils/logging.py +3 -4
  250. {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.1.dist-info}/METADATA +9 -8
  251. siliconcompiler-0.33.1.dist-info/RECORD +488 -0
  252. {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.1.dist-info}/WHEEL +1 -1
  253. {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.1.dist-info}/entry_points.txt +8 -8
  254. siliconcompiler/schema/schema_obj.py +0 -1936
  255. siliconcompiler/toolscripts/ubuntu20/install-vpr.sh +0 -29
  256. siliconcompiler/toolscripts/ubuntu20/install-yosys-parmys.sh +0 -61
  257. siliconcompiler-0.32.3.dist-info/RECORD +0 -470
  258. /siliconcompiler/{templates → data/templates}/__init__.py +0 -0
  259. /siliconcompiler/{templates → data/templates}/email/__init__.py +0 -0
  260. /siliconcompiler/{templates → data/templates}/email/general.j2 +0 -0
  261. /siliconcompiler/{templates → data/templates}/email/summary.j2 +0 -0
  262. /siliconcompiler/{templates → data/templates}/issue/README.txt +0 -0
  263. /siliconcompiler/{templates → data/templates}/issue/__init__.py +0 -0
  264. /siliconcompiler/{templates → data/templates}/issue/run.sh +0 -0
  265. /siliconcompiler/{templates → data/templates}/replay/replay.py.j2 +0 -0
  266. /siliconcompiler/{templates → data/templates}/replay/replay.sh.j2 +0 -0
  267. /siliconcompiler/{templates → data/templates}/replay/requirements.txt +0 -0
  268. /siliconcompiler/{templates → data/templates}/replay/setup.sh +0 -0
  269. /siliconcompiler/{templates → data/templates}/report/__init__.py +0 -0
  270. /siliconcompiler/{templates → data/templates}/report/bootstrap.min.css +0 -0
  271. /siliconcompiler/{templates → data/templates}/report/bootstrap.min.js +0 -0
  272. /siliconcompiler/{templates → data/templates}/report/bootstrap_LICENSE.md +0 -0
  273. /siliconcompiler/{templates → data/templates}/report/sc_report.j2 +0 -0
  274. /siliconcompiler/{templates → data/templates}/slurm/__init__.py +0 -0
  275. /siliconcompiler/{templates → data/templates}/slurm/run.sh +0 -0
  276. /siliconcompiler/{templates → data/templates}/tcl/__init__.py +0 -0
  277. /siliconcompiler/{templates → data/templates}/tcl/manifest.tcl.j2 +0 -0
  278. /siliconcompiler/{units.py → utils/units.py} +0 -0
  279. {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.1.dist-info}/licenses/LICENSE +0 -0
  280. {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.1.dist-info}/top_level.txt +0 -0
@@ -5,8 +5,9 @@ from docutils.statemachine import ViewList
5
5
  from sphinx.util.docutils import SphinxDirective
6
6
 
7
7
  import siliconcompiler
8
- from siliconcompiler.schema import Schema
9
- from siliconcompiler.sphinx_ext.utils import (
8
+ from siliconcompiler import Schema
9
+ from siliconcompiler.schema import utils, PerNode
10
+ from siliconcompiler.schema.docs.utils import (
10
11
  strong,
11
12
  code,
12
13
  para,
@@ -15,8 +16,7 @@ from siliconcompiler.sphinx_ext.utils import (
15
16
  build_section_with_target,
16
17
  build_list
17
18
  )
18
- from siliconcompiler.schema import utils
19
- from siliconcompiler.sphinx_ext import sc_root as SC_ROOT
19
+ from siliconcompiler.schema.docs import sc_root as SC_ROOT
20
20
 
21
21
 
22
22
  # Main Sphinx plugin
@@ -28,72 +28,71 @@ class SchemaGen(SphinxDirective):
28
28
  self.env.note_dependency(__file__)
29
29
  self.env.note_dependency(utils.__file__)
30
30
 
31
- schema = Schema().cfg
32
-
33
- return self.process_schema(schema)
34
-
35
- def process_schema(self, schema, parents=[]):
36
- if 'help' in schema:
37
- entries = [[strong('Description'), para(schema['shorthelp'])],
38
- [strong('Type'), para(schema['type'])]]
39
-
40
- if schema['pernode'] != utils.PerNode.NEVER:
41
- entries.append([strong('Per step/index'), para(schema['pernode'])])
42
-
43
- entries.append([strong('Scope'), para(schema['scope'])])
44
-
45
- if 'enum' in schema['type']:
46
- entries.append([strong('Allowed Values'),
47
- build_list([code(val) for val in schema['enum']])])
48
-
49
- if 'unit' in schema:
50
- entries.append([strong('Unit'), para(schema['unit'])])
51
-
52
- defvalue = schema['node']['default']['default']['value']
53
- switch_list = [code(switch) for switch in schema['switch']]
54
- entries.extend([[strong('Default Value'), para(defvalue)],
55
- [strong('CLI Switch'), build_list(switch_list)]])
56
-
57
- examples = {}
58
- for example in schema['example']:
59
- name, ex = example.split(':', 1)
60
- examples.setdefault(name, []).append(ex)
61
-
62
- for name, exs in examples.items():
63
- examples = [code(ex.strip()) for ex in exs]
64
- p = None
65
- for ex in examples:
66
- if not p:
67
- p = para("")
68
- else:
69
- p += para("")
70
- p += ex
71
- entries.append([strong(f'Example ({name.upper()})'), p])
72
-
73
- table = build_table(entries, colwidths=[25, 75])
74
- body = self.parse_rst(utils.trim(schema['help']))
75
-
76
- return [table, body]
77
- else:
78
- sections = []
79
- for key in schema.keys():
80
- if key == 'default':
81
- for n in self.process_schema(schema['default'], parents=parents):
82
- sections.append(n)
31
+ self.schema = Schema()
32
+
33
+ return self.process_schema([])
34
+
35
+ def process_parameter(self, parameter):
36
+ entries = [[strong('Description'), para(parameter.get(field='shorthelp'))],
37
+ [strong('Type'), para(parameter.get(field='type'))]]
38
+
39
+ if parameter.get(field='pernode') != PerNode.NEVER:
40
+ entries.append([strong('Per step/index'),
41
+ para(str(parameter.get(field='pernode').value).lower())])
42
+
43
+ entries.append([strong('Scope'), para(str(parameter.get(field='scope').value).lower())])
44
+
45
+ if parameter.get(field='unit'):
46
+ entries.append([strong('Unit'), para(parameter.get(field='unit'))])
47
+
48
+ switch_list = [code(switch) for switch in parameter.get(field='switch')]
49
+ entries.extend([[strong('Default Value'), para(parameter.default.get())],
50
+ [strong('CLI Switch'), build_list(switch_list)]])
51
+
52
+ examples = {}
53
+ for example in parameter.get(field='example'):
54
+ name, ex = example.split(':', 1)
55
+ examples.setdefault(name, []).append(ex)
56
+
57
+ for name, exs in examples.items():
58
+ examples = [code(ex.strip()) for ex in exs]
59
+ p = None
60
+ for ex in examples:
61
+ if not p:
62
+ p = para("")
83
63
  else:
84
- if not parents and key in ('history', 'library'):
85
- continue
86
- section_key = 'param-' + '-'.join(parents + [key])
87
- section = build_section_with_target(key, section_key, self.state.document)
88
- for n in self.process_schema(schema[key], parents=parents + [key]):
89
- section += n
90
- sections.append(section)
91
-
92
- # Sort all sections alphabetically by title. We may also have nodes
93
- # in this list that aren't sections if `schema` has a 'default'
94
- # entry that's a leaf. In this case, we sort this as an empty string
95
- # in order to put this node at the beginning of the list.
96
- return sorted(sections, key=lambda s: s[0][0] if isinstance(s, nodes.section) else '')
64
+ p += para("")
65
+ p += ex
66
+ entries.append([strong(f'Example ({name.upper()})'), p])
67
+
68
+ table = build_table(entries, colwidths=[25, 75])
69
+ body = self.parse_rst(utils.trim(parameter.get(field='help')))
70
+
71
+ return [table, body]
72
+
73
+ def process_schema(self, keypath):
74
+ if self.schema.valid(*keypath, default_valid=True, check_complete=True):
75
+ return self.process_parameter(self.schema.get(*keypath, field=None))
76
+
77
+ sections = []
78
+ if self.schema.valid(*keypath, "default"):
79
+ for n in self.process_schema(keypath + ["default"]):
80
+ sections.append(n)
81
+ for key in self.schema.getkeys(*keypath):
82
+ if not keypath and key in ('history', 'library'):
83
+ continue
84
+ section_key = 'param-' + '-'.join(
85
+ [key for key in (keypath + [key]) if key != "default"])
86
+ section = build_section_with_target(key, section_key, self.state.document)
87
+ for n in self.process_schema(keypath + [key]):
88
+ section += n
89
+ sections.append(section)
90
+
91
+ # Sort all sections alphabetically by title. We may also have nodes
92
+ # in this list that aren't sections if `schema` has a 'default'
93
+ # entry that's a leaf. In this case, we sort this as an empty string
94
+ # in order to put this node at the beginning of the list.
95
+ return sorted(sections, key=lambda s: s[0][0] if isinstance(s, nodes.section) else '')
97
96
 
98
97
  def parse_rst(self, content):
99
98
  rst = ViewList()
@@ -143,17 +142,6 @@ class CategorySummary(SphinxDirective):
143
142
 
144
143
  class CategoryGroupTable(SphinxDirective):
145
144
 
146
- def count_keys(self, schema, *keypath):
147
- cfgs = schema.getdict(*keypath)
148
- count = 0
149
- for key, cfg in cfgs.items():
150
- if schema._is_leaf(cfg):
151
- count += 1
152
- else:
153
- count += self.count_keys(schema, *keypath, key)
154
-
155
- return count
156
-
157
145
  def run(self):
158
146
  self.env.note_dependency(__file__)
159
147
 
@@ -182,22 +170,22 @@ class CategoryGroupTable(SphinxDirective):
182
170
  "arg": "",
183
171
  }
184
172
 
185
- schema = Schema()
173
+ self.schema = Schema()
186
174
 
187
175
  # Check if all groups have desc
188
- for group in schema.getkeys():
176
+ for group in self.schema.getkeys():
189
177
  if group not in desc:
190
178
  raise ValueError(f"{group} not found in group descriptions")
191
179
 
192
180
  # Check if all groups have schema
193
181
  for group in desc.keys():
194
- if group not in schema.getkeys():
182
+ if group not in self.schema.getkeys():
195
183
  raise ValueError(f"{group} not found in schema")
196
184
 
197
185
  table = [[strong('Group'), strong('Parameters'), strong('Description')]]
198
186
 
199
187
  total = 0
200
- for group in schema.getkeys():
188
+ for group in self.schema.getkeys():
201
189
  text = desc[group]
202
190
  if len(text) == 0:
203
191
  continue
@@ -205,7 +193,7 @@ class CategoryGroupTable(SphinxDirective):
205
193
  key = para('')
206
194
  key += keypath([group], self.env.docname)
207
195
 
208
- count = self.count_keys(schema, group)
196
+ count = len(self.schema.allkeys(group, include_default=True))
209
197
  total += count
210
198
 
211
199
  table.append([key, para(f'{count}'), para(text)])
@@ -1,7 +1,7 @@
1
1
  from docutils import nodes
2
2
  import sphinx.addnodes
3
3
 
4
- from siliconcompiler.schema import Schema
4
+ from siliconcompiler import Schema
5
5
 
6
6
 
7
7
  # Docutils helpers
@@ -127,32 +127,31 @@ def keypath(key_path, refdoc, key_text=None):
127
127
  '''Helper function for displaying Schema keypaths.'''
128
128
  text_parts = []
129
129
  key_parts = []
130
- cfg = Schema().cfg
130
+ schema = Schema()
131
131
  for key in key_path:
132
- if list(cfg.keys()) != ['default']:
133
- text_parts.append(f"'{key}'")
134
- key_parts.append(key)
135
- try:
136
- cfg = cfg[key]
137
- except KeyError:
138
- raise ValueError(f'Invalid keypath {key_path}')
139
- else:
140
- cfg = cfg['default']
132
+ if schema.valid(*key_parts, "default", default_valid=True):
133
+ key_parts.append("default")
141
134
  if key.startswith('<') and key.endswith('>'):
142
135
  # Placeholder
143
136
  text_parts.append(key)
144
137
  else:
145
138
  # Fully-qualified
146
139
  text_parts.append(f"'{key}'")
140
+ else:
141
+ key_parts.append(key)
142
+ text_parts.append(f"'{key}'")
143
+
144
+ if not schema.valid(*key_parts, default_valid=True):
145
+ raise ValueError(f'Invalid keypath {key_path}')
147
146
 
148
- if 'help' not in cfg:
147
+ if not schema.valid(*key_parts, default_valid=True, check_complete=True):
149
148
  # Not leaf
150
149
  text_parts.append('...')
151
150
 
152
151
  if key_text:
153
152
  text_parts = key_text
154
153
  text = f"[{', '.join(text_parts)}]"
155
- refid = get_ref_id('param-' + '-'.join(key_parts))
154
+ refid = get_ref_id('param-' + '-'.join([key for key in key_parts if key != "default"]))
156
155
 
157
156
  opt = {'refdoc': refdoc,
158
157
  'refdomain': 'sc',
@@ -0,0 +1,136 @@
1
+ # Copyright 2025 Silicon Compiler Authors. All Rights Reserved.
2
+
3
+ # NOTE: this file cannot rely on any third-party dependencies, including other
4
+ # SC dependencies outside of its directory, since it may be used by tool drivers
5
+ # that have isolated Python environments.
6
+
7
+ from .parameter import Parameter
8
+ from .baseschema import BaseSchema
9
+
10
+
11
+ class EditableSchema:
12
+ '''
13
+ This class provides access to modify the underlying schema.
14
+ This should only be used when creating new schema entries.
15
+
16
+ Args:
17
+ schema (:class:`BaseSchema`): schema to modify
18
+ '''
19
+
20
+ def __init__(self, schema):
21
+ # Grab manifest from base class
22
+ self.__schema = schema
23
+
24
+ def __insert(self, keypath, value, fullkey, clobber):
25
+ key = keypath[0]
26
+ keypath = keypath[1:]
27
+
28
+ if len(keypath) == 0:
29
+ if key in self.__schema._BaseSchema__manifest and not clobber:
30
+ raise KeyError(f"[{','.join(fullkey)}] is already defined")
31
+
32
+ if key == "default":
33
+ self.__schema._BaseSchema__default = value
34
+ else:
35
+ self.__schema._BaseSchema__manifest[key] = value
36
+ return
37
+
38
+ new_schema = BaseSchema()
39
+ if key == "default":
40
+ if self.__schema._BaseSchema__default:
41
+ new_schema = self.__schema._BaseSchema__default
42
+ else:
43
+ self.__schema._BaseSchema__default = new_schema
44
+ else:
45
+ new_schema = self.__schema._BaseSchema__manifest.setdefault(key, new_schema)
46
+ EditableSchema(new_schema).__insert(keypath, value, fullkey, clobber)
47
+
48
+ def __remove(self, keypath, fullkey):
49
+ key = keypath[0]
50
+ keypath = keypath[1:]
51
+
52
+ if key == "default":
53
+ next_param = self.__schema._BaseSchema__default
54
+ else:
55
+ next_param = self.__schema._BaseSchema__manifest.get(key, None)
56
+
57
+ if not next_param:
58
+ raise KeyError(f"[{','.join(fullkey)}] cannot be found")
59
+
60
+ if len(keypath) == 0:
61
+ if key == "default":
62
+ self.__schema._BaseSchema__default = None
63
+ else:
64
+ del self.__schema._BaseSchema__manifest[key]
65
+ else:
66
+ EditableSchema(next_param).__remove(keypath, fullkey)
67
+
68
+ def insert(self, *args, clobber=False):
69
+ '''
70
+ Inserts a :class:`Parameter` or a :class:`BaseSchema` to the schema,
71
+ based on the keypath and value provided in the ``*args``.
72
+
73
+ Args:
74
+ args (list): Parameter keypath followed by a item to add.
75
+ clobber (boolean): If true, will overwrite existing value,
76
+ otherwise will raise a KeyError if it is already defined.
77
+
78
+ Examples:
79
+ >>> schema.insert('option', 'value', Parameter('str'))
80
+ Adds the keypath [option,value] with a string parameter.
81
+ '''
82
+
83
+ value = args[-1]
84
+ keypath = args[0:-1]
85
+
86
+ if not keypath:
87
+ raise ValueError("A keypath is required")
88
+
89
+ if any([not isinstance(key, str) for key in keypath]):
90
+ raise ValueError("Keypath must only be strings")
91
+
92
+ if not isinstance(value, (Parameter, BaseSchema)):
93
+ raise ValueError(f"Value ({type(value)}) must be schema type: Parameter, BaseSchema")
94
+
95
+ self.__insert(keypath, value, keypath, clobber=clobber)
96
+
97
+ def remove(self, *keypath):
98
+ '''
99
+ Removes a keypath from the schema.
100
+
101
+ Args:
102
+ keypath (list): keypath to be removed.
103
+
104
+ Examples:
105
+ >>> schema.remove('option', 'value')
106
+ Removes the keypath [option,value] from the schema.
107
+ '''
108
+
109
+ if not keypath:
110
+ raise ValueError("A keypath is required")
111
+
112
+ if any([not isinstance(key, str) for key in keypath]):
113
+ raise ValueError("Keypath must only be strings")
114
+
115
+ self.__remove(keypath, keypath)
116
+
117
+ def search(self, *keypath):
118
+ '''
119
+ Finds an item in the schema. This will raise a KeyError if
120
+ the path is not found.
121
+
122
+ Args:
123
+ keypath (list): keypath to be found.
124
+
125
+ Examples:
126
+ >>> schema.search('option', 'value')
127
+ Returns the parameter stored in at [option,value].
128
+ '''
129
+
130
+ if not keypath:
131
+ raise ValueError("A keypath is required")
132
+
133
+ if any([not isinstance(key, str) for key in keypath]):
134
+ raise ValueError("Keypath must only be strings")
135
+
136
+ return self.__schema._BaseSchema__search(*keypath, require_leaf=False)
@@ -0,0 +1,238 @@
1
+ import copy
2
+ import types
3
+
4
+ from .baseschema import BaseSchema
5
+ from .baseschema import json
6
+
7
+
8
+ class JournalingSchema(BaseSchema):
9
+ """
10
+ This class provides the ability to record the schema transactions:
11
+ :meth:`set`, :meth:`add`, :meth:`remove`, and :meth:`unset`.
12
+
13
+ Args:
14
+ schema (:class:`BaseSchema`): schema to track
15
+ keyprefix (list of str): keypath to prefix on to recorded path
16
+ """
17
+
18
+ def __init__(self, schema, keyprefix=None):
19
+ if not isinstance(schema, BaseSchema):
20
+ raise TypeError(f"schema must be of BaseSchema type, not: {type(schema)}")
21
+ if isinstance(schema, JournalingSchema):
22
+ raise TypeError("schema must be of cannot be a JournalingSchema")
23
+
24
+ self.__schema = schema
25
+
26
+ journal_attrs = dir(self)
27
+
28
+ # Transfer access to internal schema
29
+ for param, value in self.__schema.__dict__.items():
30
+ setattr(self, param, value)
31
+ for param in dir(type(self.__schema)):
32
+ if param in journal_attrs:
33
+ continue
34
+ method = getattr(type(self.__schema), param)
35
+ if callable(method):
36
+ setattr(self, param, types.MethodType(method, self))
37
+
38
+ if not keyprefix:
39
+ self.__keyprefix = tuple()
40
+ else:
41
+ self.__keyprefix = tuple(keyprefix)
42
+
43
+ self.__record_types = set()
44
+ self.stop_journal()
45
+
46
+ self.__parent = self
47
+
48
+ def get(self, *keypath, field='value', step=None, index=None):
49
+ get_ret = super().get(*keypath, field=field, step=step, index=index)
50
+ self.__record_journal("get", keypath, field=field, step=step, index=index)
51
+ if field == 'schema':
52
+ child = JournalingSchema(get_ret, keyprefix=[*self.__keyprefix, *keypath])
53
+ child.__parent = self.__parent
54
+ return child
55
+
56
+ return get_ret
57
+
58
+ def set(self, *args, field='value', clobber=True, step=None, index=None):
59
+ ret = super().set(*args, field=field, clobber=clobber, step=step, index=index)
60
+ if ret:
61
+ *keypath, value = args
62
+ self.__record_journal("set", keypath, value=value, field=field, step=step, index=index)
63
+ return ret
64
+
65
+ def add(self, *args, field='value', step=None, index=None):
66
+ ret = super().add(*args, field=field, step=step, index=index)
67
+ if ret:
68
+ *keypath, value = args
69
+ self.__record_journal("add", keypath, value=value, field=field, step=step, index=index)
70
+ return ret
71
+
72
+ def remove(self, *keypath):
73
+ self.__record_journal("remove", keypath)
74
+ return super().remove(*keypath)
75
+
76
+ def unset(self, *keypath, step=None, index=None):
77
+ self.__record_journal("unset", keypath, step=step, index=index)
78
+ return super().unset(*keypath, step=step, index=index)
79
+
80
+ def _from_dict(self, manifest, keypath, version=None):
81
+ if "__journal__" in manifest:
82
+ self.__journal = manifest["__journal__"]
83
+ del manifest["__journal__"]
84
+
85
+ self.__schema._from_dict(manifest, keypath, version=version)
86
+
87
+ def getdict(self, *keypath, include_default=True):
88
+ manifest = super().getdict(*keypath, include_default=include_default)
89
+
90
+ if self.__journal:
91
+ manifest["__journal__"] = self.get_journal()
92
+
93
+ return manifest
94
+
95
+ def get_journal(self):
96
+ """
97
+ Returns a copy of the current journal
98
+ """
99
+
100
+ return copy.deepcopy(self.__journal)
101
+
102
+ def is_journaling(self):
103
+ """
104
+ Returns true if the schema is currently setup for journaling
105
+ """
106
+ return self.__journal is not None
107
+
108
+ def get_journaling_types(self):
109
+ """
110
+ Returns the current schema accesses that are being recorded
111
+ """
112
+
113
+ return self.__record_types.copy()
114
+
115
+ def add_journaling_type(self, value):
116
+ """
117
+ Adds a new access type to the journal record.
118
+
119
+ Args:
120
+ value (str): access type
121
+ """
122
+
123
+ if value not in ("set", "add", "remove", "unset", "get"):
124
+ raise ValueError(f"{value} is not a valid type")
125
+
126
+ return self.__record_types.add(value)
127
+
128
+ def remove_journaling_type(self, value):
129
+ """
130
+ Removes a new access type to the journal record.
131
+
132
+ Args:
133
+ value (str): access type
134
+ """
135
+
136
+ try:
137
+ self.__record_types.remove(value)
138
+ except KeyError:
139
+ pass
140
+
141
+ def get_base_schema(self):
142
+ """
143
+ Returns the base schema
144
+ """
145
+
146
+ return self.__schema
147
+
148
+ def __record_journal(self, record_type, key, value=None, field=None, step=None, index=None):
149
+ '''
150
+ Record the schema transaction
151
+ '''
152
+
153
+ if self.__parent.__journal is None:
154
+ return
155
+
156
+ if record_type not in self.__parent.__record_types:
157
+ return
158
+
159
+ self.__parent.__journal.append({
160
+ "type": record_type,
161
+ "key": tuple([*self.__keyprefix, *key]),
162
+ "value": value,
163
+ "field": field,
164
+ "step": step,
165
+ "index": index
166
+ })
167
+
168
+ def start_journal(self):
169
+ '''
170
+ Start journaling the schema transactions
171
+ '''
172
+ self.__journal = []
173
+ self.add_journaling_type("set")
174
+ self.add_journaling_type("add")
175
+ self.add_journaling_type("remove")
176
+ self.add_journaling_type("unset")
177
+
178
+ def stop_journal(self):
179
+ '''
180
+ Stop journaling the schema transactions
181
+ '''
182
+ self.__journal = None
183
+ self.__record_types.clear()
184
+
185
+ def read_journal(self, filename):
186
+ '''
187
+ Reads a manifest and replays the journal
188
+ '''
189
+
190
+ with open(filename) as f:
191
+ data = json.loads(f.read())
192
+
193
+ self.import_journal(cfg=data)
194
+
195
+ def import_journal(self, schema=None, cfg=None):
196
+ '''
197
+ Import the journaled transactions from a different schema.
198
+ Only one argument is supported at a time.
199
+
200
+ Args:
201
+ schema (:class:`JournalingSchema`): schema to replay transactions from
202
+ cfg (dict): dictionary to replay transactions from
203
+ '''
204
+
205
+ if schema and cfg:
206
+ raise ValueError("only one argument is supported")
207
+
208
+ journal = []
209
+ if schema:
210
+ if isinstance(schema, JournalingSchema):
211
+ journal = schema.__journal
212
+ else:
213
+ raise TypeError(f"schema must be a JournalingSchema, not {type(schema)}")
214
+ elif cfg and "__journal__" in cfg:
215
+ journal = cfg["__journal__"]
216
+
217
+ if journal is None:
218
+ return
219
+
220
+ for action in journal:
221
+ record_type = action['type']
222
+ keypath = action['key']
223
+ value = action['value']
224
+ field = action['field']
225
+ step = action['step']
226
+ index = action['index']
227
+ if record_type == 'set':
228
+ self.set(*keypath, value, field=field, step=step, index=index)
229
+ elif record_type == 'add':
230
+ self.add(*keypath, value, field=field, step=step, index=index)
231
+ elif record_type == 'unset':
232
+ self.unset(*keypath, step=step, index=index)
233
+ elif record_type == 'remove':
234
+ self.remove(*keypath)
235
+ elif record_type == 'get':
236
+ continue
237
+ else:
238
+ raise ValueError(f'Unknown record type {record_type}')
@@ -0,0 +1,41 @@
1
+ # Copyright 2025 Silicon Compiler Authors. All Rights Reserved.
2
+
3
+ # NOTE: this file cannot rely on any third-party dependencies, including other
4
+ # SC dependencies outside of its directory, since it may be used by tool drivers
5
+ # that have isolated Python environments.
6
+
7
+ from .baseschema import BaseSchema
8
+
9
+
10
+ class NamedSchema(BaseSchema):
11
+ '''
12
+ This object provides a named :class:`BaseSchema`.
13
+
14
+ Args:
15
+ name (str): name of the schema
16
+ '''
17
+
18
+ def __init__(self, name=None):
19
+ super().__init__()
20
+
21
+ self.__name = name
22
+
23
+ def name(self):
24
+ '''
25
+ Returns the name of the schema
26
+ '''
27
+ return self.__name
28
+
29
+ def _from_dict(self, manifest, keypath, version=None):
30
+ if keypath:
31
+ self.__name = keypath[-1]
32
+
33
+ return super()._from_dict(manifest, keypath, version=version)
34
+
35
+ def copy(self, key=None):
36
+ copy = super().copy(key=key)
37
+
38
+ if not self.__name and key and key[-1] != "default":
39
+ copy.__name = key[-1]
40
+
41
+ return copy