librelane 2.4.0__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.

Potentially problematic release.


This version of librelane might be problematic. Click here for more details.

Files changed (170) hide show
  1. librelane/__init__.py +38 -0
  2. librelane/__main__.py +479 -0
  3. librelane/__version__.py +43 -0
  4. librelane/common/__init__.py +63 -0
  5. librelane/common/cli.py +75 -0
  6. librelane/common/drc.py +246 -0
  7. librelane/common/generic_dict.py +319 -0
  8. librelane/common/metrics/__init__.py +35 -0
  9. librelane/common/metrics/__main__.py +413 -0
  10. librelane/common/metrics/library.py +354 -0
  11. librelane/common/metrics/metric.py +186 -0
  12. librelane/common/metrics/util.py +279 -0
  13. librelane/common/misc.py +456 -0
  14. librelane/common/ring_buffer.py +63 -0
  15. librelane/common/tcl.py +80 -0
  16. librelane/common/toolbox.py +549 -0
  17. librelane/common/tpe.py +41 -0
  18. librelane/common/types.py +116 -0
  19. librelane/config/__init__.py +32 -0
  20. librelane/config/__main__.py +155 -0
  21. librelane/config/config.py +1025 -0
  22. librelane/config/flow.py +490 -0
  23. librelane/config/pdk_compat.py +255 -0
  24. librelane/config/preprocessor.py +464 -0
  25. librelane/config/removals.py +45 -0
  26. librelane/config/variable.py +743 -0
  27. librelane/container.py +285 -0
  28. librelane/env_info.py +320 -0
  29. librelane/examples/spm/config.yaml +33 -0
  30. librelane/examples/spm/pin_order.cfg +14 -0
  31. librelane/examples/spm/src/impl.sdc +73 -0
  32. librelane/examples/spm/src/signoff.sdc +68 -0
  33. librelane/examples/spm/src/spm.v +73 -0
  34. librelane/examples/spm/verify/spm_tb.v +106 -0
  35. librelane/examples/spm-user_project_wrapper/SPM_example.v +286 -0
  36. librelane/examples/spm-user_project_wrapper/base_sdc_file.sdc +145 -0
  37. librelane/examples/spm-user_project_wrapper/config-tut.json +12 -0
  38. librelane/examples/spm-user_project_wrapper/config.json +13 -0
  39. librelane/examples/spm-user_project_wrapper/defines.v +66 -0
  40. librelane/examples/spm-user_project_wrapper/template.def +7656 -0
  41. librelane/examples/spm-user_project_wrapper/user_project_wrapper.v +123 -0
  42. librelane/flows/__init__.py +24 -0
  43. librelane/flows/builtins.py +18 -0
  44. librelane/flows/classic.py +327 -0
  45. librelane/flows/cli.py +463 -0
  46. librelane/flows/flow.py +1049 -0
  47. librelane/flows/misc.py +71 -0
  48. librelane/flows/optimizing.py +179 -0
  49. librelane/flows/sequential.py +367 -0
  50. librelane/flows/synth_explore.py +173 -0
  51. librelane/help/__main__.py +39 -0
  52. librelane/logging/__init__.py +40 -0
  53. librelane/logging/logger.py +323 -0
  54. librelane/open_pdks_rev +1 -0
  55. librelane/plugins.py +21 -0
  56. librelane/py.typed +0 -0
  57. librelane/scripts/base.sdc +80 -0
  58. librelane/scripts/klayout/Readme.md +2 -0
  59. librelane/scripts/klayout/open_design.py +63 -0
  60. librelane/scripts/klayout/render.py +121 -0
  61. librelane/scripts/klayout/stream_out.py +176 -0
  62. librelane/scripts/klayout/xml_drc_report_to_json.py +45 -0
  63. librelane/scripts/klayout/xor.drc +120 -0
  64. librelane/scripts/magic/Readme.md +1 -0
  65. librelane/scripts/magic/common/read.tcl +114 -0
  66. librelane/scripts/magic/def/antenna_check.tcl +35 -0
  67. librelane/scripts/magic/def/mag.tcl +19 -0
  68. librelane/scripts/magic/def/mag_gds.tcl +79 -0
  69. librelane/scripts/magic/drc.tcl +78 -0
  70. librelane/scripts/magic/extract_spice.tcl +98 -0
  71. librelane/scripts/magic/gds/drc_batch.tcl +74 -0
  72. librelane/scripts/magic/gds/erase_box.tcl +32 -0
  73. librelane/scripts/magic/gds/extras_mag.tcl +45 -0
  74. librelane/scripts/magic/gds/mag_with_pointers.tcl +31 -0
  75. librelane/scripts/magic/get_bbox.tcl +11 -0
  76. librelane/scripts/magic/lef/extras_maglef.tcl +61 -0
  77. librelane/scripts/magic/lef/maglef.tcl +26 -0
  78. librelane/scripts/magic/lef.tcl +57 -0
  79. librelane/scripts/magic/open.tcl +28 -0
  80. librelane/scripts/magic/wrapper.tcl +21 -0
  81. librelane/scripts/netgen/setup.tcl +28 -0
  82. librelane/scripts/odbpy/apply_def_template.py +49 -0
  83. librelane/scripts/odbpy/cell_frequency.py +107 -0
  84. librelane/scripts/odbpy/check_antenna_properties.py +116 -0
  85. librelane/scripts/odbpy/contextualize.py +109 -0
  86. librelane/scripts/odbpy/defutil.py +573 -0
  87. librelane/scripts/odbpy/diodes.py +373 -0
  88. librelane/scripts/odbpy/disconnected_pins.py +305 -0
  89. librelane/scripts/odbpy/eco_buffer.py +181 -0
  90. librelane/scripts/odbpy/eco_diode.py +139 -0
  91. librelane/scripts/odbpy/filter_unannotated.py +100 -0
  92. librelane/scripts/odbpy/io_place.py +482 -0
  93. librelane/scripts/odbpy/ioplace_parser/__init__.py +23 -0
  94. librelane/scripts/odbpy/ioplace_parser/parse.py +147 -0
  95. librelane/scripts/odbpy/label_macro_pins.py +277 -0
  96. librelane/scripts/odbpy/lefutil.py +97 -0
  97. librelane/scripts/odbpy/placers.py +162 -0
  98. librelane/scripts/odbpy/power_utils.py +397 -0
  99. librelane/scripts/odbpy/random_place.py +57 -0
  100. librelane/scripts/odbpy/reader.py +250 -0
  101. librelane/scripts/odbpy/remove_buffers.py +173 -0
  102. librelane/scripts/odbpy/snap_to_grid.py +57 -0
  103. librelane/scripts/odbpy/wire_lengths.py +93 -0
  104. librelane/scripts/openroad/antenna_check.tcl +20 -0
  105. librelane/scripts/openroad/antenna_repair.tcl +31 -0
  106. librelane/scripts/openroad/basic_mp.tcl +24 -0
  107. librelane/scripts/openroad/buffer_list.tcl +10 -0
  108. librelane/scripts/openroad/common/dpl.tcl +24 -0
  109. librelane/scripts/openroad/common/dpl_cell_pad.tcl +26 -0
  110. librelane/scripts/openroad/common/grt.tcl +32 -0
  111. librelane/scripts/openroad/common/io.tcl +540 -0
  112. librelane/scripts/openroad/common/pdn_cfg.tcl +135 -0
  113. librelane/scripts/openroad/common/resizer.tcl +103 -0
  114. librelane/scripts/openroad/common/set_global_connections.tcl +78 -0
  115. librelane/scripts/openroad/common/set_layer_adjustments.tcl +31 -0
  116. librelane/scripts/openroad/common/set_power_nets.tcl +30 -0
  117. librelane/scripts/openroad/common/set_rc.tcl +75 -0
  118. librelane/scripts/openroad/common/set_routing_layers.tcl +30 -0
  119. librelane/scripts/openroad/cts.tcl +80 -0
  120. librelane/scripts/openroad/cut_rows.tcl +24 -0
  121. librelane/scripts/openroad/dpl.tcl +24 -0
  122. librelane/scripts/openroad/drt.tcl +37 -0
  123. librelane/scripts/openroad/fill.tcl +30 -0
  124. librelane/scripts/openroad/floorplan.tcl +145 -0
  125. librelane/scripts/openroad/gpl.tcl +88 -0
  126. librelane/scripts/openroad/grt.tcl +30 -0
  127. librelane/scripts/openroad/gui.tcl +37 -0
  128. librelane/scripts/openroad/insert_buffer.tcl +127 -0
  129. librelane/scripts/openroad/ioplacer.tcl +67 -0
  130. librelane/scripts/openroad/irdrop.tcl +51 -0
  131. librelane/scripts/openroad/pdn.tcl +52 -0
  132. librelane/scripts/openroad/rcx.tcl +32 -0
  133. librelane/scripts/openroad/repair_design.tcl +70 -0
  134. librelane/scripts/openroad/repair_design_postgrt.tcl +48 -0
  135. librelane/scripts/openroad/rsz_timing_postcts.tcl +68 -0
  136. librelane/scripts/openroad/rsz_timing_postgrt.tcl +70 -0
  137. librelane/scripts/openroad/sta/check_macro_instances.tcl +53 -0
  138. librelane/scripts/openroad/sta/corner.tcl +393 -0
  139. librelane/scripts/openroad/tapcell.tcl +25 -0
  140. librelane/scripts/openroad/write_views.tcl +27 -0
  141. librelane/scripts/pyosys/construct_abc_script.py +177 -0
  142. librelane/scripts/pyosys/json_header.py +84 -0
  143. librelane/scripts/pyosys/synthesize.py +493 -0
  144. librelane/scripts/pyosys/ys_common.py +153 -0
  145. librelane/scripts/tclsh/hello.tcl +1 -0
  146. librelane/state/__init__.py +24 -0
  147. librelane/state/__main__.py +61 -0
  148. librelane/state/design_format.py +195 -0
  149. librelane/state/state.py +359 -0
  150. librelane/steps/__init__.py +61 -0
  151. librelane/steps/__main__.py +510 -0
  152. librelane/steps/checker.py +637 -0
  153. librelane/steps/common_variables.py +340 -0
  154. librelane/steps/cvc_rv.py +169 -0
  155. librelane/steps/klayout.py +509 -0
  156. librelane/steps/magic.py +576 -0
  157. librelane/steps/misc.py +160 -0
  158. librelane/steps/netgen.py +253 -0
  159. librelane/steps/odb.py +1088 -0
  160. librelane/steps/openroad.py +2460 -0
  161. librelane/steps/openroad_alerts.py +102 -0
  162. librelane/steps/pyosys.py +640 -0
  163. librelane/steps/step.py +1571 -0
  164. librelane/steps/tclstep.py +288 -0
  165. librelane/steps/verilator.py +222 -0
  166. librelane/steps/yosys.py +371 -0
  167. librelane-2.4.0.dist-info/METADATA +169 -0
  168. librelane-2.4.0.dist-info/RECORD +170 -0
  169. librelane-2.4.0.dist-info/WHEEL +4 -0
  170. librelane-2.4.0.dist-info/entry_points.txt +9 -0
@@ -0,0 +1,63 @@
1
+ # Copyright 2020-2022 Efabless Corporation
2
+ # Copyright 2021 The American University in Cairo and the Cloud V Project
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ import os
16
+ import sys
17
+ import shlex
18
+ import argparse
19
+ from typing import Tuple
20
+
21
+ import pya # Must be run inside KLayout-- the library version of pya does not include "Application"
22
+
23
+
24
+ def open_design(input_lefs: Tuple[str, ...], lyt: str, lyp: str, lym: str, input: str):
25
+ try:
26
+ main_window = pya.Application.instance().main_window()
27
+
28
+ tech = pya.Technology()
29
+ tech.load(lyt)
30
+
31
+ layout_options = tech.load_layout_options
32
+ layout_options.keep_other_cells = True
33
+ layout_options.lefdef_config.macro_resolution_mode = 1
34
+ layout_options.lefdef_config.read_lef_with_def = False
35
+ layout_options.lefdef_config.lef_files = list(input_lefs)
36
+ layout_options.lefdef_config.map_file = lym
37
+
38
+ cell_view = main_window.load_layout(input, layout_options, 0)
39
+ layout_view = cell_view.view()
40
+ layout_view.load_layer_props(lyp)
41
+ except Exception as e:
42
+ print(e, file=sys.stderr)
43
+ pya.Application.instance().exit(1)
44
+
45
+
46
+ if __name__ == "__main__":
47
+ parser = argparse.ArgumentParser(description="Open design in KLayout")
48
+ parser.add_argument(
49
+ "-l",
50
+ "--input-lef",
51
+ action="append",
52
+ dest="input_lefs",
53
+ help="KLayout .lef files",
54
+ )
55
+ parser.add_argument("-T", "--lyt", required=True, help="KLayout .lyt file")
56
+ parser.add_argument("-P", "--lyp", required=True, help="KLayout .lyp file")
57
+ parser.add_argument(
58
+ "-M", "--lym", required=True, help="KLayout .map (LEF/DEF layer map) file"
59
+ )
60
+ parser.add_argument("input", help="KLayout cell name")
61
+
62
+ args = parser.parse_args(shlex.split(os.environ["KLAYOUT_ARGV"]))
63
+ open_design(args.input_lefs, args.lyt, args.lyp, args.lym, args.input)
@@ -0,0 +1,121 @@
1
+ #!/usr/bin/env python3
2
+ # Copyright (c) 2021-2022 Efabless Corporation
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ # Original Copyright Follows
17
+ #
18
+ # BSD 3-Clause License
19
+ #
20
+ # Copyright (c) 2018, The Regents of the University of California
21
+ # All rights reserved.
22
+ #
23
+ # Redistribution and use in source and binary forms, with or without
24
+ # modification, are permitted provided that the following conditions are met:
25
+ #
26
+ # * Redistributions of source code must retain the above copyright notice, this
27
+ # list of conditions and the following disclaimer.
28
+ #
29
+ # * Redistributions in binary form must reproduce the above copyright notice,
30
+ # this list of conditions and the following disclaimer in the documentation
31
+ # and/or other materials provided with the distribution.
32
+ #
33
+ # * Neither the name of the copyright holder nor the names of its
34
+ # contributors may be used to endorse or promote products derived from
35
+ # this software without specific prior written permission.
36
+ #
37
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
38
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
41
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
44
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
46
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47
+ from typing import Tuple
48
+
49
+ import pya
50
+ import click
51
+
52
+
53
+ @click.command()
54
+ @click.option("-o", "--output", required=True)
55
+ @click.option(
56
+ "-l",
57
+ "--input-lef",
58
+ "input_lefs",
59
+ multiple=True,
60
+ )
61
+ @click.option(
62
+ "-T",
63
+ "--lyt",
64
+ required=True,
65
+ help="KLayout .lyt file",
66
+ )
67
+ @click.option(
68
+ "-P",
69
+ "--lyp",
70
+ required=True,
71
+ help="KLayout .lyp file",
72
+ )
73
+ @click.option(
74
+ "-M",
75
+ "--lym",
76
+ required=True,
77
+ help="KLayout .map (LEF/DEF layer map) file",
78
+ )
79
+ @click.argument("input")
80
+ def render(
81
+ input_lefs: Tuple[str, ...],
82
+ output: str,
83
+ lyt: str,
84
+ lyp: str,
85
+ lym: str,
86
+ input: str,
87
+ ):
88
+ try:
89
+ gds = input.endswith(".gds")
90
+
91
+ # Load technology file
92
+ tech = pya.Technology()
93
+ tech.load(lyt)
94
+
95
+ layout_options = None
96
+ if not gds:
97
+ layout_options = tech.load_layout_options
98
+ layout_options.lefdef_config.map_file = lym
99
+ layout_options.lefdef_config.macro_resolution_mode = 1
100
+ layout_options.lefdef_config.read_lef_with_def = False
101
+ layout_options.lefdef_config.lef_files = list(input_lefs)
102
+
103
+ view = pya.LayoutView()
104
+ view.load_layer_props(lyp)
105
+
106
+ if gds:
107
+ view.load_layout(input)
108
+ else:
109
+ view.load_layout(input, layout_options, lyt)
110
+ view.max_hier()
111
+ pixels = view.get_pixels_with_options(1000, 1000)
112
+
113
+ with open(output, "wb") as f:
114
+ f.write(pixels.to_png_data())
115
+ except Exception as e:
116
+ print(e)
117
+ exit(1)
118
+
119
+
120
+ if __name__ == "__main__":
121
+ render()
@@ -0,0 +1,176 @@
1
+ #!/usr/bin/env python3
2
+ # Copyright (c) 2021-2022 Efabless Corporation
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ # Original Copyright Follows
17
+ #
18
+ # BSD 3-Clause License
19
+ #
20
+ # Copyright (c) 2018, The Regents of the University of California
21
+ # All rights reserved.
22
+ #
23
+ # Redistribution and use in source and binary forms, with or without
24
+ # modification, are permitted provided that the following conditions are met:
25
+ #
26
+ # * Redistributions of source code must retain the above copyright notice, this
27
+ # list of conditions and the following disclaimer.
28
+ #
29
+ # * Redistributions in binary form must reproduce the above copyright notice,
30
+ # this list of conditions and the following disclaimer in the documentation
31
+ # and/or other materials provided with the distribution.
32
+ #
33
+ # * Neither the name of the copyright holder nor the names of its
34
+ # contributors may be used to endorse or promote products derived from
35
+ # this software without specific prior written permission.
36
+ #
37
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
38
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
41
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
44
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
46
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47
+ import sys
48
+ from typing import Tuple, Optional
49
+
50
+ import pya
51
+ import click
52
+
53
+
54
+ @click.command()
55
+ @click.option("-o", "--output", required=True)
56
+ @click.option(
57
+ "-l",
58
+ "--input-lef",
59
+ "input_lefs",
60
+ multiple=True,
61
+ )
62
+ @click.option(
63
+ "-T",
64
+ "--lyt",
65
+ required=True,
66
+ help="KLayout .lyt file",
67
+ )
68
+ @click.option(
69
+ "-P",
70
+ "--lyp",
71
+ required=True,
72
+ help="KLayout .lyp file",
73
+ )
74
+ @click.option(
75
+ "-M",
76
+ "--lym",
77
+ required=True,
78
+ help="KLayout .map (LEF/DEF layer map) file",
79
+ )
80
+ @click.option("-w", "--with-gds-file", "input_gds_files", multiple=True, default=[])
81
+ @click.option("-s", "--seal-gds-file", "seal_gds", default=None)
82
+ @click.option(
83
+ "-t",
84
+ "--top",
85
+ "design_name",
86
+ required=True,
87
+ help="Name of the design/top module",
88
+ )
89
+ @click.argument(
90
+ "input",
91
+ type=click.Path(exists=True, file_okay=True, dir_okay=False),
92
+ )
93
+ def stream_out(
94
+ output: str,
95
+ input_lefs: Tuple[str, ...],
96
+ lyt: str,
97
+ lyp: str,
98
+ lym: str,
99
+ input_gds_files: Tuple[str, ...],
100
+ seal_gds: Optional[str],
101
+ design_name: str,
102
+ input: str,
103
+ ): # Load technology file
104
+ try:
105
+ tech = pya.Technology()
106
+ tech.load(lyt)
107
+ layout_options = tech.load_layout_options
108
+ layout_options.lefdef_config.read_lef_with_def = False
109
+ layout_options.lefdef_config.lef_files = list(input_lefs)
110
+ layout_options.lefdef_config.map_file = lym
111
+
112
+ # Load def file
113
+ main_layout = pya.Layout()
114
+ # main_layout.load_layer_props(props_file)
115
+ main_layout.read(input, layout_options)
116
+
117
+ # Clear cells
118
+ top_cell_index = main_layout.cell(design_name).cell_index()
119
+
120
+ print("[INFO] Clearing cells…")
121
+ for i in main_layout.each_cell():
122
+ if i.cell_index() != top_cell_index:
123
+ if not i.name.startswith("VIA"):
124
+ i.clear()
125
+
126
+ # Load in the gds to merge
127
+ print("[INFO] Merging GDS files…")
128
+ for gds in input_gds_files:
129
+ main_layout.read(gds)
130
+
131
+ # Copy the top level only to a new layout
132
+ print(f"[INFO] Copying top level cell '{design_name}'…")
133
+ top_only_layout = pya.Layout()
134
+ top_only_layout.dbu = main_layout.dbu
135
+ top = top_only_layout.create_cell(design_name)
136
+ top.copy_tree(main_layout.cell(design_name))
137
+
138
+ print("[INFO] Checking for missing GDS…")
139
+ missing_gds = False
140
+ for i in top_only_layout.each_cell():
141
+ if i.is_empty():
142
+ missing_gds = True
143
+ print(
144
+ f"[ERROR] LEF Cell '{i.name}' has no matching GDS cell.",
145
+ file=sys.stderr,
146
+ )
147
+
148
+ if missing_gds:
149
+ raise Exception("One or more cell GDS files are missing.")
150
+ else:
151
+ print("[INFO] All LEF cells have matching GDS cells.")
152
+
153
+ if seal_gds is not None:
154
+ top_cell = top_only_layout.top_cell()
155
+
156
+ print(f"[INFO] Reading seal GDS file '{seal_gds}'…")
157
+ top_only_layout.read(seal_gds)
158
+
159
+ for cell in top_only_layout.top_cells():
160
+ if cell != top_cell:
161
+ print(
162
+ f"[INFO] Merging '{cell.name}' as child of '{top_cell.name}'…"
163
+ )
164
+ top.insert(pya.CellInstArray(cell.cell_index(), pya.Trans()))
165
+
166
+ # Write out the GDS
167
+ print(f"[INFO] Writing out GDS '{output}'…")
168
+ top_only_layout.write(output)
169
+ print("[INFO] Done.")
170
+ except Exception as e:
171
+ print(e)
172
+ exit(1)
173
+
174
+
175
+ if __name__ == "__main__":
176
+ stream_out()
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env python3
2
+ # Copyright (c) 2023 Efabless Corporation
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ import json
16
+
17
+ from klayout.rdb import ReportDatabase
18
+ import click
19
+
20
+
21
+ @click.command()
22
+ @click.option("--xml-file")
23
+ @click.option("--json-file")
24
+ def cli(xml_file, json_file):
25
+ database = ReportDatabase("Database")
26
+ json_database = {}
27
+ database.load(xml_file)
28
+ total = 0
29
+ for category in database.each_category():
30
+ num_items = category.num_items()
31
+ category_name = category.name()
32
+ json_database[category_name] = num_items
33
+ total += num_items
34
+
35
+ json_database = dict(sorted(json_database.items(), key=lambda item: item[1]))
36
+ json_database["total"] = total
37
+
38
+ with open(json_file, "w", encoding="utf8") as f:
39
+ json.dump(json_database, f, indent=4)
40
+
41
+ print(f"%OL_METRIC_I klayout__drc_error__count {total}")
42
+
43
+
44
+ if __name__ == "__main__":
45
+ cli()
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/env ruby
2
+ # A general XOR script from: https://www.klayout.de/forum/discussion/100/xor-vs-diff-tool
3
+
4
+ # This script uses KLayout's Ruby-based DRC language to implement a generic
5
+ # XOR between two layouts. The names of the layouts are given in global variables
6
+ # $a and $b.
7
+
8
+ if !defined?(RBA)
9
+ require 'optparse'
10
+
11
+ options = {
12
+ :rpt_out => "/dev/null"
13
+ }
14
+ optparse = OptionParser.new do |opts|
15
+ opts.banner = "Usage: #{File.basename($0)} [options] <GDS A> <GDS B>"
16
+
17
+ opts.on("-o", "--output OUTPUT", "Klayout RDB (.xml) output file (required)") do |rdb_out|
18
+ options[:rdb_out] = rdb_out
19
+ end
20
+ opts.on("-i", "--ignore SEMICOLON_DELIMITED_LIST", "Ignore layer(s)") do |ignore|
21
+ options[:ignore] = ignore
22
+ end
23
+ opts.on("-t", "--top TOP_CELL", "Top cell name (required)") do |top_cell|
24
+ options[:top_cell] = top_cell
25
+ end
26
+ opts.on("-t", "--tile-size TILE_SIZE", "Tile size (in µm)") do |tile_size|
27
+ options[:tile_size] = tile_size.to_i
28
+ end
29
+ opts.on("-n", "--threads THREAD_COUNT", "Lower bound on the thread count used by this process (+ managing threads)") do |threads|
30
+ options[:threads] = threads.to_i
31
+ end
32
+ end
33
+ optparse.parse!
34
+
35
+ if [options[:rdb_out], options[:top_cell]].include?(nil)
36
+ puts optparse.help
37
+ exit 64
38
+ end
39
+
40
+ args = [
41
+ "klayout", "-b",
42
+ "-r", $0,
43
+ "-rd", "top_cell=#{options[:top_cell]}",
44
+ "-rd", "a=#{ARGV[0]}",
45
+ "-rd", "b=#{ARGV[1]}",
46
+ "-rd", "jobs=#{options[:threads]}",
47
+ "-rd", "rdb_out=#{File.absolute_path(options[:rdb_out])}",
48
+ "-rd", "ignore=#{options[:ignore]}",
49
+ "-rd", "tilesize=#{options[:tile_size]}",
50
+ ]
51
+ puts "Running: '#{args.join(" ")}'…"
52
+ exec *args
53
+
54
+ end
55
+
56
+ verbose
57
+
58
+ # Run XOR
59
+ if $jobs == ""
60
+ $jobs = "1"
61
+ end
62
+ $jobs = $jobs.to_i
63
+
64
+ info "Using #{$jobs} threads…"
65
+ threads($jobs)
66
+
67
+ # Tiling
68
+ if $tilesize == ""
69
+ $tilesize = "500"
70
+ end
71
+ $tilesize = $tilesize.to_i
72
+
73
+ info "Using a tile size of (#{$tilesize} µm)²…"
74
+ tiles($tilesize.um, $tilesize.um)
75
+
76
+ # Set up inputs
77
+ puts $a, $b
78
+ a = source($a, $top_cell)
79
+ b = source($b, $top_cell)
80
+
81
+ # Set up output
82
+ # target($gds_out, "XOR")
83
+ report("XOR #{$a} vs. #{$b}", $rdb_out)
84
+
85
+ def write_data(xor_data, layer_info)
86
+ xor_data.output(layer_info.to_s, "XOR data for layer #{layer_info.to_s}")
87
+ end
88
+
89
+ ## Collect all common layers
90
+ layers = {}
91
+ [ a.layout, b.layout ].each do |ly|
92
+ ly.layer_indices.each do |li|
93
+ i = ly.get_info(li)
94
+ layers[i.to_s] = i
95
+ end
96
+ end
97
+
98
+ ignore_list = $ignore.split(";")
99
+
100
+ ## Perform per-layer XOR
101
+ total_xor_differences = 0
102
+ layers.sort.uniq.each do |layer_name, layer_data|
103
+ if ignore_list.include? layer_name
104
+ warn "--- Skipping #{layer_name}… ---"
105
+ else
106
+ info "--- Running XOR for layer #{layer_name} ---"
107
+
108
+ layer_info = layers[layer_name]
109
+ xor_data = (a.input(layer_name, layer_data) ^ b.input(layer_name, layer_data))
110
+ total_xor_differences += xor_data.data.size
111
+ info "XOR differences: #{xor_data.data.size}"
112
+
113
+ write_data xor_data, layer_info
114
+ end
115
+ end
116
+
117
+ info "---"
118
+ info "Total XOR differences: #{total_xor_differences}"
119
+
120
+ puts "%OL_METRIC_I design__xor_difference__count #{total_xor_differences}"
@@ -0,0 +1 @@
1
+ Files here are categorized by the input format. `drc.tcl` and `extract_spice.tcl` accept both GDS and DEF depending on a flag.
@@ -0,0 +1,114 @@
1
+ # Copyright 2022 Efabless Corporation
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ proc read_pdk_gds {} {
17
+ set old_rescale [gds rescale]
18
+ set old_readonly [gds readonly]
19
+ gds rescale false
20
+ gds readonly true
21
+ set gds_files_in $::env(CELL_GDS)
22
+ foreach gds_file $gds_files_in {
23
+ puts "> gds read $gds_file"
24
+ gds read $gds_file
25
+ }
26
+ gds rescale $old_rescale
27
+ gds readonly $old_readonly
28
+ }
29
+
30
+ proc read_tech_lef {} {
31
+ puts "> lef read $::env(TECH_LEF)"
32
+ lef read $::env(TECH_LEF)
33
+ }
34
+
35
+ proc read_macro_lef {} {
36
+ if { [info exist ::env(MACRO_LEFS)] } {
37
+ foreach lef_file $::env(MACRO_LEFS) {
38
+ puts "> lef read $lef_file"
39
+ lef read $lef_file
40
+ }
41
+ }
42
+ }
43
+
44
+ proc read_extra_lef {} {
45
+ if { [info exist ::env(EXTRA_LEFS)] } {
46
+ foreach lef_file $::env(EXTRA_LEFS) {
47
+ puts "> lef read $lef_file"
48
+ lef read $lef_file
49
+ }
50
+ }
51
+ }
52
+
53
+ proc read_extra_gds {} {
54
+ set old_rescale [gds rescale]
55
+ set old_readonly [gds readonly]
56
+ gds rescale false
57
+ gds readonly true
58
+ if { [info exist ::env(EXTRA_GDS_FILES)] } {
59
+ set gds_files_in $::env(EXTRA_GDS_FILES)
60
+ foreach gds_file $gds_files_in {
61
+ puts "> gds read $gds_file"
62
+ gds read $gds_file
63
+ }
64
+ }
65
+ gds rescale $old_rescale
66
+ gds readonly $old_readonly
67
+ }
68
+
69
+ proc read_macro_gds_blackbox {} {
70
+ if { [info exists ::env(__MACRO_GDS)] } {
71
+ foreach macro $::env(__MACRO_GDS) {
72
+ set macro_name [lindex $macro 0]
73
+ set gds_file [lindex $macro 1]
74
+ set bbox [lindex $macro 2]
75
+ load $macro_name
76
+ property LEFview true
77
+ property GDS_FILE $gds_file
78
+ property GDS_START 0
79
+ property FIXED_BBOX "$bbox"
80
+ puts "[property]"
81
+ puts "> set GDS_FILE of $macro_name to $gds_file"
82
+ }
83
+ }
84
+ }
85
+
86
+ proc read_macro_gds {} {
87
+ if { [info exist ::env(MACRO_GDS_FILES)] } {
88
+ set gds_files_in $::env(MACRO_GDS_FILES)
89
+ foreach gds_file $gds_files_in {
90
+ puts "> gds read $gds_file"
91
+ gds read $gds_file
92
+ }
93
+ }
94
+ }
95
+
96
+ proc read_pdk_lef {} {
97
+ foreach lef_file $::env(CELL_LEFS) {
98
+ puts "> lef read $lef_file"
99
+ lef read $lef_file
100
+ }
101
+ }
102
+
103
+ proc read_def {} {
104
+ set def_read_args [list]
105
+ lappend def_read_args $::env(CURRENT_DEF)
106
+ if { $::env(MAGIC_DEF_NO_BLOCKAGES) } {
107
+ lappend def_read_args -noblockage
108
+ }
109
+ if { $::env(MAGIC_DEF_LABELS) } {
110
+ lappend def_read_args -labels
111
+ }
112
+ puts "> def read $def_read_args"
113
+ def read {*}$def_read_args
114
+ }
@@ -0,0 +1,35 @@
1
+ # Copyright 2020-2022 Efabless Corporation
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ source $::env(SCRIPTS_DIR)/magic/def/read.tcl
15
+
16
+ load $::env(DESIGN_NAME) -dereference
17
+
18
+ set extdir $::env(signoff_tmpfiles)/magic_antenna_ext
19
+ file mkdir $extdir
20
+ cd $extdir
21
+
22
+ select top cell
23
+ extract do local
24
+ extract no capacitance
25
+ extract no coupling
26
+ extract no resistance
27
+ extract no adjust
28
+ if { ! $::env(MAGIC_NO_EXT_UNIQUE) } {
29
+ extract unique
30
+ }
31
+ extract
32
+ feedback save $::env(_tmp_feedback_file)
33
+
34
+ antennacheck debug
35
+ antennacheck
@@ -0,0 +1,19 @@
1
+ # Copyright 2020-2022 Efabless Corporation
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ source $::env(SCRIPTS_DIR)/magic/def/read.tcl
16
+
17
+ save $::env(SAVE_MAG)
18
+
19
+ puts "[INFO] Done exporting $::env(SAVE_MAG)."