PySHDL 0.2.3__tar.gz → 0.2.4__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 (147) hide show
  1. {pyshdl-0.2.3 → pyshdl-0.2.4}/PKG-INFO +1 -1
  2. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/SHDL_components/adder16.shdl +1 -1
  3. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/SHDL_components/clock.shdl +1 -1
  4. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/SHDL_components/shift1.shdl +1 -1
  5. {pyshdl-0.2.3 → pyshdl-0.2.4}/pyproject.toml +1 -1
  6. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/__init__.py +1 -1
  7. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/flattener/flattener.py +46 -12
  8. {pyshdl-0.2.3 → pyshdl-0.2.4}/.github/workflows/deploy-docs.yml +0 -0
  9. {pyshdl-0.2.3 → pyshdl-0.2.4}/.github/workflows/publish.yml +0 -0
  10. {pyshdl-0.2.3 → pyshdl-0.2.4}/.github/workflows/test.yml +0 -0
  11. {pyshdl-0.2.3 → pyshdl-0.2.4}/.gitignore +0 -0
  12. {pyshdl-0.2.3 → pyshdl-0.2.4}/LICENSE +0 -0
  13. {pyshdl-0.2.3 → pyshdl-0.2.4}/README.md +0 -0
  14. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/README.md +0 -0
  15. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/architecture/_category_.json +0 -0
  16. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/architecture/base-shdl.md +0 -0
  17. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/architecture/compiler-internals.md +0 -0
  18. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/architecture/flattening-pipeline.md +0 -0
  19. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/architecture/overview.md +0 -0
  20. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/architecture/pyshdl-internals.md +0 -0
  21. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/debugger/_category_.json +0 -0
  22. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/debugger/breakpoints.md +0 -0
  23. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/debugger/commands.md +0 -0
  24. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/debugger/common-problems.md +0 -0
  25. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/debugger/debug-build.md +0 -0
  26. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/debugger/getting-started.md +0 -0
  27. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/debugger/hierarchy.md +0 -0
  28. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/debugger/inspection.md +0 -0
  29. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/debugger/overview.md +0 -0
  30. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/debugger/python-api.md +0 -0
  31. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/debugger/scripting.md +0 -0
  32. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/debugger/waveforms.md +0 -0
  33. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/examples/8-bit-adder.md +0 -0
  34. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/examples/_category_.json +0 -0
  35. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/examples/comparator.md +0 -0
  36. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/examples/decoder.md +0 -0
  37. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/examples/full-adder.md +0 -0
  38. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/examples/half-adder.md +0 -0
  39. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/examples/multiplexer.md +0 -0
  40. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/examples/register.md +0 -0
  41. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/getting-started/_category_.json +0 -0
  42. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/getting-started/first-circuit.md +0 -0
  43. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/getting-started/installation.md +0 -0
  44. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/getting-started/using-pyshdl.md +0 -0
  45. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/intro.md +0 -0
  46. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/language-reference/_category_.json +0 -0
  47. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/language-reference/components.md +0 -0
  48. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/language-reference/connections.md +0 -0
  49. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/language-reference/constants.md +0 -0
  50. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/language-reference/errors.md +0 -0
  51. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/language-reference/generators.md +0 -0
  52. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/language-reference/imports.md +0 -0
  53. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/language-reference/lexical-elements.md +0 -0
  54. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/language-reference/overview.md +0 -0
  55. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/language-reference/signals.md +0 -0
  56. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docs/language-reference/standard-gates.md +0 -0
  57. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/docusaurus.config.ts +0 -0
  58. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/package.json +0 -0
  59. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/sidebars.ts +0 -0
  60. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/src/components/HomepageFeatures/index.tsx +0 -0
  61. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/src/components/HomepageFeatures/styles.module.css +0 -0
  62. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/src/css/custom.css +0 -0
  63. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/src/pages/index.module.css +0 -0
  64. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/src/pages/index.tsx +0 -0
  65. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/src/pages/markdown-page.md +0 -0
  66. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/static/.nojekyll +0 -0
  67. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/static/img/docusaurus-social-card.jpg +0 -0
  68. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/static/img/docusaurus.png +0 -0
  69. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/static/img/favicon.ico +0 -0
  70. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/static/img/halfAdder.png +0 -0
  71. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/static/img/logo.svg +0 -0
  72. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/static/img/undraw_docusaurus_mountain.svg +0 -0
  73. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/static/img/undraw_docusaurus_react.svg +0 -0
  74. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/static/img/undraw_docusaurus_tree.svg +0 -0
  75. {pyshdl-0.2.3 → pyshdl-0.2.4}/docs/tsconfig.json +0 -0
  76. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/SHDL_components/add100.shdl +0 -0
  77. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/SHDL_components/addSub16.shdl +0 -0
  78. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/SHDL_components/alu.shdl +0 -0
  79. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/SHDL_components/and16inputs.shdl +0 -0
  80. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/SHDL_components/bitwise_and16.shdl +0 -0
  81. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/SHDL_components/bitwise_not16.shdl +0 -0
  82. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/SHDL_components/bitwise_or16.shdl +0 -0
  83. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/SHDL_components/bitwise_xor16.shdl +0 -0
  84. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/SHDL_components/demux.shdl +0 -0
  85. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/SHDL_components/flagsZN.shdl +0 -0
  86. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/SHDL_components/fullAdder.shdl +0 -0
  87. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/SHDL_components/mux2.shdl +0 -0
  88. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/SHDL_components/mux2_16.shdl +0 -0
  89. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/SHDL_components/mux8.shdl +0 -0
  90. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/SHDL_components/mux8_16.shdl +0 -0
  91. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/SHDL_components/negate16.shdl +0 -0
  92. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/SHDL_components/or16inputs.shdl +0 -0
  93. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/SHDL_components/reg16.shdl +0 -0
  94. {pyshdl-0.2.3 → pyshdl-0.2.4}/examples/interacting.py +0 -0
  95. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDB/__init__.py +0 -0
  96. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/compiler/__init__.py +0 -0
  97. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/compiler/analyzer.py +0 -0
  98. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/compiler/ast.py +0 -0
  99. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/compiler/cli.py +0 -0
  100. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/compiler/codegen.py +0 -0
  101. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/compiler/compiler.py +0 -0
  102. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/compiler/debug_codegen.py +0 -0
  103. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/compiler/debug_info_gen.py +0 -0
  104. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/compiler/lexer.py +0 -0
  105. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/compiler/parser.py +0 -0
  106. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/debugger/__init__.py +0 -0
  107. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/debugger/circuit.py +0 -0
  108. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/debugger/cli.py +0 -0
  109. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/debugger/controller.py +0 -0
  110. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/debugger/debuginfo.py +0 -0
  111. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/debugger/sourcemap.py +0 -0
  112. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/debugger/symbols.py +0 -0
  113. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/driver/__init__.py +0 -0
  114. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/driver/circuit.py +0 -0
  115. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/driver/exceptions.py +0 -0
  116. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/errors.py +0 -0
  117. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/flattener/__init__.py +0 -0
  118. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/flattener/ast.py +0 -0
  119. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/flattener/lexer.py +0 -0
  120. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/flattener/parser.py +0 -0
  121. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/flattener/tokens.py +0 -0
  122. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/py.typed +0 -0
  123. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/semantic/__init__.py +0 -0
  124. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/semantic/analyzer.py +0 -0
  125. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/semantic/connection.py +0 -0
  126. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/semantic/resolver.py +0 -0
  127. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/semantic/type_check.py +0 -0
  128. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/semantic/warnings.py +0 -0
  129. {pyshdl-0.2.3 → pyshdl-0.2.4}/src/SHDL/source_map.py +0 -0
  130. {pyshdl-0.2.3 → pyshdl-0.2.4}/tests/README.md +0 -0
  131. {pyshdl-0.2.3 → pyshdl-0.2.4}/tests/TEST_REPORT.md +0 -0
  132. {pyshdl-0.2.3 → pyshdl-0.2.4}/tests/circuits/test_adder4.shdl +0 -0
  133. {pyshdl-0.2.3 → pyshdl-0.2.4}/tests/circuits/test_adder8.shdl +0 -0
  134. {pyshdl-0.2.3 → pyshdl-0.2.4}/tests/circuits/test_bitwise.shdl +0 -0
  135. {pyshdl-0.2.3 → pyshdl-0.2.4}/tests/circuits/test_comparator.shdl +0 -0
  136. {pyshdl-0.2.3 → pyshdl-0.2.4}/tests/circuits/test_constants.shdl +0 -0
  137. {pyshdl-0.2.3 → pyshdl-0.2.4}/tests/circuits/test_decoder.shdl +0 -0
  138. {pyshdl-0.2.3 → pyshdl-0.2.4}/tests/circuits/test_gates.shdl +0 -0
  139. {pyshdl-0.2.3 → pyshdl-0.2.4}/tests/circuits/test_generators.shdl +0 -0
  140. {pyshdl-0.2.3 → pyshdl-0.2.4}/tests/circuits/test_half_full_adder.shdl +0 -0
  141. {pyshdl-0.2.3 → pyshdl-0.2.4}/tests/circuits/test_mux.shdl +0 -0
  142. {pyshdl-0.2.3 → pyshdl-0.2.4}/tests/conftest.py +0 -0
  143. {pyshdl-0.2.3 → pyshdl-0.2.4}/tests/test_debugger.py +0 -0
  144. {pyshdl-0.2.3 → pyshdl-0.2.4}/tests/test_errors.py +0 -0
  145. {pyshdl-0.2.3 → pyshdl-0.2.4}/tests/test_shdl.py +0 -0
  146. {pyshdl-0.2.3 → pyshdl-0.2.4}/tests/test_shdl_comprehensive.py +0 -0
  147. {pyshdl-0.2.3 → pyshdl-0.2.4}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PySHDL
3
- Version: 0.2.3
3
+ Version: 0.2.4
4
4
  Summary: SHDL (Simple Hardware Description Language) is a minimal HDL designed for creating digital circuits and easily simulating them. It compiles directly to C for maximum performance and portability. PySHDL is the Python interface for SHDL.
5
5
  Project-URL: Homepage, https://github.com/rafa-rrayes/SHDL
6
6
  Project-URL: Repository, https://github.com/rafa-rrayes/SHDL
@@ -5,7 +5,7 @@ component Adder16(A[16], B[16], Cin) -> (Sum[16], Cout) {
5
5
  connect {
6
6
  A[1] -> fa1.A; B[1] -> fa1.B; Cin -> fa1.Cin; fa1.Sum -> Sum[1];
7
7
 
8
- >i[2,16]{
8
+ >i[2:16]{
9
9
  A[{i}] -> fa{i}.A;
10
10
  B[{i}] -> fa{i}.B;
11
11
  fa{i-1}.Cout -> fa{i}.Cin;
@@ -10,7 +10,7 @@ component Clock(clk)->(out[20]) {
10
10
 
11
11
  connect {
12
12
  clk -> o1.A;
13
- >i[2, 20]{
13
+ >i[2: 20]{
14
14
  o{i-1}.O -> o{i}.A;
15
15
  o{i-1}.O -> o{i}.B;
16
16
  o{i-1}.O -> out[{i-1}];
@@ -29,7 +29,7 @@ component Shift1(A[16], dir, arith) -> (Y[16], Cout) {
29
29
  ZERO -> bitmux1.a; A[2] -> bitmux1.b; dir -> bitmux1.sel; bitmux1.y -> Y[1];
30
30
 
31
31
  # Bits 2..15:
32
- >i[2,15]{
32
+ >i[2:15]{
33
33
  # left candidate: A[i-1]; right candidate: A[i+1]
34
34
  A[{i-1}] -> bitmux{i}.a;
35
35
  A[{i+1}] -> bitmux{i}.b;
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "PySHDL"
3
- version = "0.2.3"
3
+ version = "0.2.4"
4
4
  description = "SHDL (Simple Hardware Description Language) is a minimal HDL designed for creating digital circuits and easily simulating them. It compiles directly to C for maximum performance and portability. PySHDL is the Python interface for SHDL."
5
5
  readme = "README.md"
6
6
  authors = [
@@ -79,7 +79,7 @@ from .debugger import (
79
79
  SourceMap,
80
80
  )
81
81
 
82
- __version__ = "0.2.3"
82
+ __version__ = "0.2.4"
83
83
 
84
84
  __all__ = [
85
85
  # Version
@@ -22,6 +22,7 @@ from .ast import (
22
22
  )
23
23
  from .parser import parse, parse_file
24
24
  from ..errors import FlattenerError
25
+ from ..semantic.analyzer import SemanticAnalyzer
25
26
 
26
27
 
27
28
  # =============================================================================
@@ -760,7 +761,12 @@ def rewire_signal_for_source(signal: Signal, port_mappings: dict[str, PortMappin
760
761
  return Signal(name=parts[1], instance=parts[0], index=None)
761
762
  else:
762
763
  return Signal(name=internal, instance=None, index=signal.index)
763
-
764
+
765
+ # Defensive guard: port not found in mappings for a flattened instance
766
+ raise FlattenerError(
767
+ f"Port '{signal.name}' not found on flattened instance '{signal.instance}'"
768
+ )
769
+
764
770
  # It's a reference to a primitive instance - apply prefix
765
771
  new_instance = f"{prefix}{signal.instance}" if prefix else signal.instance
766
772
  return Signal(name=signal.name, instance=new_instance, index=signal.index)
@@ -796,7 +802,12 @@ def rewire_signal_for_dest(signal: Signal, port_mappings: dict[str, PortMapping]
796
802
  return Signal(name=parts[1], instance=parts[0], index=None)
797
803
  else:
798
804
  return Signal(name=internal, instance=None, index=signal.index)
799
-
805
+
806
+ # Defensive guard: port not found in mappings for a flattened instance
807
+ raise FlattenerError(
808
+ f"Port '{signal.name}' not found on flattened instance '{signal.instance}'"
809
+ )
810
+
800
811
  # It's a reference to a primitive instance - apply prefix
801
812
  new_instance = f"{prefix}{signal.instance}" if prefix else signal.instance
802
813
  return Signal(name=signal.name, instance=new_instance, index=signal.index)
@@ -847,45 +858,68 @@ def flatten_component_full(component: Component, library: ComponentLibrary, pref
847
858
  @dataclass
848
859
  class Flattener:
849
860
  """Main flattener class for transforming SHDL."""
850
-
861
+
851
862
  search_paths: list[str] = field(default_factory=list)
852
-
863
+ validate: bool = True
864
+
853
865
  def __post_init__(self) -> None:
854
866
  self._library = ComponentLibrary(
855
867
  search_paths=[Path(p) for p in self.search_paths]
856
868
  )
857
-
869
+ self._module: Optional[Module] = None
870
+ self._file_path: Optional[str] = None
871
+
858
872
  def add_component(self, component: Component) -> None:
859
873
  """Add a component to the library."""
860
874
  self._library.add(component)
861
-
875
+
862
876
  def load_file(self, path: str) -> Module:
863
877
  """Load and parse an SHDL file, adding its components to the library."""
864
878
  module = parse_file(path)
865
-
879
+ self._file_path = path
880
+
866
881
  # Process imports first - load all referenced modules
867
882
  for imp in module.imports:
868
883
  if not self._library.load_module(imp.module):
869
884
  raise FlattenerError(f"Cannot find module: {imp.module}")
870
-
885
+
871
886
  # Then add components from this file
872
887
  for comp in module.components:
873
888
  self._library.add(comp)
874
-
889
+
890
+ self._module = module
875
891
  return module
876
-
892
+
877
893
  def load_source(self, source: str) -> Module:
878
894
  """Load and parse SHDL source code, adding its components to the library."""
879
895
  module = parse(source)
880
896
  for comp in module.components:
881
897
  self._library.add(comp)
898
+ self._module = module
882
899
  return module
883
-
900
+
901
+ def _run_semantic_analysis(self) -> None:
902
+ """Run the semantic analyzer on the loaded module before flattening."""
903
+ if self._module is None:
904
+ return
905
+
906
+ search_paths = [str(p) for p in self._library.search_paths]
907
+ analyzer = SemanticAnalyzer(
908
+ search_paths=search_paths,
909
+ enable_warnings=False,
910
+ )
911
+ result = analyzer.analyze(self._module)
912
+ if result.has_errors:
913
+ result.diagnostics.print_all()
914
+ result.raise_if_errors()
915
+
884
916
  def flatten(self, component_name: str) -> Component:
885
917
  """Flatten a component by name."""
918
+ if self.validate:
919
+ self._run_semantic_analysis()
886
920
  component = self._library.resolve(component_name)
887
921
  return flatten_component_full(component, self._library)
888
-
922
+
889
923
  def flatten_to_base_shdl(self, component_name: str) -> str:
890
924
  """Flatten a component and return Base SHDL source code."""
891
925
  flattened = self.flatten(component_name)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes