lambdapdk 0.1.56__py3-none-any.whl → 0.2.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.
@@ -1,12 +1,9 @@
1
+ from pathlib import Path
1
2
 
2
- import siliconcompiler
3
- from lambdapdk import register_data_source
3
+ from lambdapdk import LambdaPDK
4
4
 
5
5
 
6
- ####################################################
7
- # PDK Setup
8
- ####################################################
9
- def setup():
6
+ class _GF180PDK(LambdaPDK):
10
7
  '''
11
8
  The 'gf180' Open Source PDK is a collaboration between Google and
12
9
  Global Foundries to provide a fully open source Process
@@ -32,60 +29,103 @@ def setup():
32
29
 
33
30
  * https://github.com/google/gf180mcu-pdk
34
31
  '''
32
+ def __init__(self, stackup, libtype):
33
+ super().__init__()
34
+ self.set_name(f"GF180_{stackup}_{libtype}")
35
+
36
+ self.set_foundry("globalfoundries")
37
+ self.set_node(180)
38
+ self.set_stackup(stackup)
39
+ self.set_wafersize(200)
40
+
41
+ pdk_path = Path("lambdapdk", "gf180", "base")
35
42
 
36
- foundry = 'globalfoundries'
37
- process = 'gf180'
38
-
39
- node = 180
40
-
41
- pdkdir = "lambdapdk/gf180/base/"
42
-
43
- pdk = siliconcompiler.PDK(process, package='lambdapdk')
44
- register_data_source(pdk)
45
-
46
- # process name
47
- pdk.set('pdk', process, 'foundry', foundry)
48
- pdk.set('pdk', process, 'node', node)
49
- pdk.set('pdk', process, 'wafersize', 200)
50
-
51
- for stackup in ("3LM_1TM_6K",
52
- "3LM_1TM_9K",
53
- "3LM_1TM_11K",
54
- "3LM_1TM_30K",
55
- "4LM_1TM_6K",
56
- "4LM_1TM_9K",
57
- "4LM_1TM_11K",
58
- "4LM_1TM_30K",
59
- "5LM_1TM_9K",
60
- "5LM_1TM_11K",
61
- "6LM_1TM_9K"):
62
- pdk.add('pdk', process, 'stackup', stackup)
63
- for libtype in ("7t", "9t"):
64
- # APR Setup
65
- for tool in ('openroad', 'klayout', 'magic'):
66
- pdk.set('pdk', process, 'aprtech', tool, stackup, libtype, 'lef',
67
- pdkdir + f'/apr/gf180mcu_{stackup}_{libtype}_tech.lef')
68
- if stackup in ('6LM_1TM_9K', '5LM_1TM_9K'):
69
- pdk.set('pdk', process, 'layermap', 'klayout', 'def', 'gds', stackup,
70
- pdkdir + f'/apr/gf180mcu_{stackup}_9t_edi2gds.layermap')
71
43
  max_layer = int(stackup[0])
72
44
 
73
- pdk.set('pdk', process, 'minlayer', stackup, 'Metal1')
74
- pdk.set('pdk', process, 'maxlayer', stackup, f'Metal{max_layer}')
45
+ with self.active_dataroot("lambdapdk"):
46
+ # APR Setup
47
+ with self.active_fileset("views.lef"):
48
+ self.add_file(pdk_path / "apr" / f"gf180mcu_{stackup}_{libtype}_tech.lef")
49
+ for tool in ('openroad', 'klayout', 'magic'):
50
+ self.add_aprtechfileset(tool)
51
+
52
+ self.set_aprroutinglayers(min="metal2", max="metal7")
53
+
54
+ if stackup in ('6LM_1TM_9K', '5LM_1TM_9K'):
55
+ with self.active_fileset("layermap"):
56
+ self.add_file(pdk_path / "apr" / f"gf180mcu_{stackup}_9t_edi2gds.layermap",
57
+ filetype="layermap")
58
+ self.add_layermapfileset("klayout", "def", "gds")
59
+
60
+ with self.active_fileset("models.spice"):
61
+ self.add_file(pdk_path / "spice" / "xyce" / "design.xyce", filetype="xyce")
62
+ self.add_file(pdk_path / "spice" / "xyce" / "sm141064.xyce", filetype="xyce")
63
+ self.add_file(pdk_path / "spice" / "xyce" / "smbb000149.xyce", filetype="xyce")
64
+ self.add_devmodelfileset("xyce", "spice")
65
+
66
+ self.set_aprroutinglayers(min="Metal1", max=f"Metal{max_layer}")
67
+
68
+ # Klayout setup
69
+ with self.active_dataroot("lambdapdk"), self.active_fileset("klayout.techmap"):
70
+ self.add_file(pdk_path / "setup" / "klayout" / "tech" / "gf180mcu.lyt",
71
+ filetype="layermap")
72
+ self.add_file(pdk_path / "setup" / "klayout" / "tech" / "gf180mcu.lyp",
73
+ filetype="display")
74
+ self.add_layermapfileset("klayout", "def", "klayout")
75
+ self.add_displayfileset("klayout")
76
+
77
+ # KLayout DRC
78
+ metal_level, _, metal_top = stackup.split('_')
79
+ drcs = {
80
+ "drc": pdk_path / "setup" / "klayout" / "drc" / "gf180mcu.drc",
81
+ "drc_feol": pdk_path / "setup" / "klayout" / "drc" / "gf180mcu.drc",
82
+ "drc_beol": pdk_path / "setup" / "klayout" / "drc" / "gf180mcu.drc",
83
+ "antenna": pdk_path / "setup" / "klayout" / "drc" / "gf180mcu_antenna.drc",
84
+ "density": pdk_path / "setup" / "klayout" / "drc" / "gf180mcu_density.drc"
85
+ }
86
+ for drc, runset in drcs.items():
87
+ with self.active_dataroot("lambdapdk"), self.active_fileset(f"klayout.drc.{drc}"):
88
+ self.add_file(runset, filetype="drc")
89
+ self.add_runsetfileset("drc", "klayout", drc)
90
+
91
+ self.add_klayout_drcparam(drc, "input=<input>")
92
+ self.add_klayout_drcparam(drc, "topcell=<topcell>")
93
+ self.add_klayout_drcparam(drc, "thr=<threads>")
94
+ self.add_klayout_drcparam(drc, "run_mode=flat")
95
+ self.add_klayout_drcparam(drc, "offgrid=true")
96
+
97
+ if drc in ("drc", "drc_feol", "drc_beol"):
98
+ feol = "true"
99
+ beol = "true"
100
+ if drc == "drc_feol":
101
+ beol = "false"
102
+ if drc == "drc_beol":
103
+ feol = "false"
104
+
105
+ self.add_klayout_drcparam(drc, f"feol={feol}")
106
+ self.add_klayout_drcparam(drc, f"beol={beol}")
107
+
108
+ self.add_klayout_drcparam(drc, f"metal_top={metal_top}")
109
+ self.add_klayout_drcparam(drc, f"metal_level={metal_level}")
110
+ if max_layer == 3:
111
+ self.add_klayout_drcparam(drc, "mim_option=A")
112
+ elif max_layer == 4 or max_layer == 5:
113
+ self.add_klayout_drcparam(drc, "mim_option=B")
75
114
 
76
- # Layer map and display file
77
- pdk.set('pdk', process, 'layermap', 'klayout', 'def', 'klayout', stackup,
78
- pdkdir + '/setup/klayout/tech/gf180mcu.lyt')
79
- pdk.set('pdk', process, 'display', 'klayout', stackup,
80
- pdkdir + '/setup/klayout/tech/gf180mcu.lyp')
115
+ self.add_klayout_hidelayers('Dualgate')
116
+ self.add_klayout_hidelayers('V5_XTOR')
117
+ self.add_klayout_hidelayers('PR_bndry')
81
118
 
82
- # Device models
83
- pdk.add('pdk', process, 'devmodel', 'xyce', 'spice', stackup,
84
- pdkdir + '/spice/xyce/design.xyce')
85
- pdk.add('pdk', process, 'devmodel', 'xyce', 'spice', stackup,
86
- pdkdir + '/spice/xyce/sm141064.xyce')
87
- pdk.add('pdk', process, 'devmodel', 'xyce', 'spice', stackup,
88
- pdkdir + '/spice/xyce/smbb000149.xyce')
119
+ # OpenROAD setup
120
+ if max_layer == 3:
121
+ self.set_openroad_rclayers(signal="Metal2", clock="Metal2")
122
+ self.add_openroad_pinlayers(vertical="Metal2", horizontal="Metal3")
123
+ elif max_layer == 4:
124
+ self.set_openroad_rclayers(signal="Metal2", clock="Metal3")
125
+ self.add_openroad_pinlayers(vertical="Metal4", horizontal="Metal3")
126
+ elif max_layer >= 5:
127
+ self.set_openroad_rclayers(signal="Metal3", clock="Metal4")
128
+ self.add_openroad_pinlayers(vertical="Metal4", horizontal="Metal3")
89
129
 
90
130
  # Openroad global routing grid derating
91
131
  openroad_layer_adjustments = {
@@ -98,89 +138,134 @@ def setup():
98
138
  'MetalTop': 1.0
99
139
  }
100
140
  for layer, adj in openroad_layer_adjustments.items():
101
- pdk.set('pdk', process, 'var', 'openroad', f'{layer}_adjustment', stackup, str(adj))
102
- if layer == pdk.get('pdk', process, 'maxlayer', stackup):
141
+ self.set_openroad_globalroutingderating(layer, adj)
142
+ if layer == f"Metal{max_layer}":
103
143
  break
104
144
 
105
- if max_layer == 3:
106
- pdk.set('pdk', process, 'var', 'openroad', 'rclayer_signal', stackup, 'Metal2')
107
- pdk.set('pdk', process, 'var', 'openroad', 'rclayer_clock', stackup, 'Metal2')
145
+ # PEX
146
+ with self.active_dataroot("lambdapdk"):
147
+ for corner in ["bst", "typ", "wst"]:
148
+ if stackup in ('3LM_1TM_6K', '3LM_1TM_9K', '3LM_1TM_11K', '3LM_1TM_30K',
149
+ '4LM_1TM_6K'):
150
+ continue
108
151
 
109
- pdk.set('pdk', process, 'var', 'openroad', 'pin_layer_vertical', stackup, 'Metal2')
110
- pdk.set('pdk', process, 'var', 'openroad', 'pin_layer_horizontal', stackup, 'Metal3')
111
- elif max_layer == 4:
112
- pdk.set('pdk', process, 'var', 'openroad', 'rclayer_signal', stackup, 'Metal2')
113
- pdk.set('pdk', process, 'var', 'openroad', 'rclayer_clock', stackup, 'Metal3')
152
+ base_name = f'gf180mcu_1p{stackup.replace("L", "").lower()}_sp_smim_OPTB_{corner}'
114
153
 
115
- pdk.set('pdk', process, 'var', 'openroad', 'pin_layer_vertical', stackup, 'Metal4')
116
- pdk.set('pdk', process, 'var', 'openroad', 'pin_layer_horizontal', stackup, 'Metal3')
117
- elif max_layer >= 5:
118
- pdk.set('pdk', process, 'var', 'openroad', 'rclayer_signal', stackup, 'Metal3')
119
- pdk.set('pdk', process, 'var', 'openroad', 'rclayer_clock', stackup, 'Metal4')
154
+ with self.active_fileset(f"openroad.pex.{corner}"):
155
+ self.add_file(pdk_path / "pex" / "openroad" / f"{base_name}.tcl",
156
+ filetype="tcl")
157
+ self.add_file(pdk_path / "pex" / "openroad" / f"{base_name}.rules",
158
+ filetype="openrcx")
120
159
 
121
- pdk.set('pdk', process, 'var', 'openroad', 'pin_layer_vertical', stackup, 'Metal4')
122
- pdk.set('pdk', process, 'var', 'openroad', 'pin_layer_horizontal', stackup, 'Metal3')
160
+ self.add_pexmodelfileset("openroad", corner)
161
+ self.add_pexmodelfileset("openroad-openrcx", corner)
123
162
 
124
- # PEX
125
- for corner in ["bst", "typ", "wst"]:
126
- if stackup in ('3LM_1TM_6K', '3LM_1TM_9K', '3LM_1TM_11K', '3LM_1TM_30K', '4LM_1TM_6K'):
127
- continue
128
- base_name = f'gf180mcu_1p{stackup.replace("L", "").lower()}_sp_smim_OPTB_{corner}'
129
- pdk.set('pdk', process, 'pexmodel', 'openroad', stackup, corner,
130
- pdkdir + '/pex/openroad/' + base_name + '.tcl')
131
- pdk.set('pdk', process, 'pexmodel', 'openroad-openrcx', stackup, corner,
132
- pdkdir + '/pex/openroad/' + base_name + '.rules')
133
-
134
- # DRC
135
- metal_level, _, metal_top = stackup.split('_')
136
- drcs = {
137
- "drc": pdkdir + '/setup/klayout/drc/gf180mcu.drc',
138
- "drc_feol": pdkdir + '/setup/klayout/drc/gf180mcu.drc',
139
- "drc_beol": pdkdir + '/setup/klayout/drc/gf180mcu.drc',
140
- "antenna": pdkdir + '/setup/klayout/drc/gf180mcu_antenna.drc',
141
- "density": pdkdir + '/setup/klayout/drc/gf180mcu_density.drc'
142
- }
143
- for drc, runset in drcs.items():
144
- pdk.set('pdk', process, 'drc', 'runset', 'klayout', stackup, drc, runset)
145
-
146
- key = f'drc_params:{drc}'
147
- pdk.add('pdk', process, 'var', 'klayout', stackup, key, 'input=<input>')
148
- pdk.add('pdk', process, 'var', 'klayout', stackup, key, 'topcell=<topcell>')
149
- pdk.add('pdk', process, 'var', 'klayout', stackup, key, 'report=<report>')
150
- pdk.add('pdk', process, 'var', 'klayout', stackup, key, 'thr=<threads>')
151
- pdk.add('pdk', process, 'var', 'klayout', stackup, key, 'run_mode=flat')
152
- pdk.add('pdk', process, 'var', 'klayout', stackup, key, 'offgrid=true')
153
-
154
- if drc in ('drc', 'drc_feol', 'drc_beol'):
155
- feol = 'true'
156
- beol = 'true'
157
- if drc == 'drc_feol':
158
- beol = 'false'
159
- if drc == 'drc_beol':
160
- feol = 'false'
161
- pdk.add('pdk', process, 'var', 'klayout', stackup, key,
162
- f'feol={feol}')
163
- pdk.add('pdk', process, 'var', 'klayout', stackup, key,
164
- f'beol={beol}')
165
-
166
- pdk.add('pdk', process, 'var', 'klayout', stackup, key,
167
- f'metal_top={metal_top}')
168
- pdk.add('pdk', process, 'var', 'klayout', stackup, key,
169
- f'metal_level={metal_level}')
170
- if max_layer == 3:
171
- pdk.add('pdk', process, 'var', 'klayout', stackup, key, 'mim_option=A')
172
- elif max_layer == 4 or max_layer == 5:
173
- pdk.add('pdk', process, 'var', 'klayout', stackup, key, 'mim_option=B')
174
163
 
175
- pdk.add('pdk', process, 'var', 'klayout', 'hide_layers', stackup, 'Dualgate')
176
- pdk.add('pdk', process, 'var', 'klayout', 'hide_layers', stackup, 'V5_XTOR')
177
- pdk.add('pdk', process, 'var', 'klayout', 'hide_layers', stackup, 'PR_bndry')
164
+ class GF180_3LM_1TM_6K_7t(_GF180PDK):
165
+ def __init__(self):
166
+ super().__init__("3LM_1TM_6K", "7t")
167
+
168
+
169
+ class GF180_3LM_1TM_6K_9t(_GF180PDK):
170
+ def __init__(self):
171
+ super().__init__("3LM_1TM_6K", "9t")
172
+
173
+
174
+ class GF180_3LM_1TM_9K_7t(_GF180PDK):
175
+ def __init__(self):
176
+ super().__init__("3LM_1TM_9K", "7t")
177
+
178
+
179
+ class GF180_3LM_1TM_9K_9t(_GF180PDK):
180
+ def __init__(self):
181
+ super().__init__("3LM_1TM_9K", "9t")
182
+
183
+
184
+ class GF180_3LM_1TM_11K_7t(_GF180PDK):
185
+ def __init__(self):
186
+ super().__init__("3LM_1TM_11K", "7t")
187
+
188
+
189
+ class GF180_3LM_1TM_11K_9t(_GF180PDK):
190
+ def __init__(self):
191
+ super().__init__("3LM_1TM_11K", "9t")
192
+
193
+
194
+ class GF180_3LM_1TM_30K_7t(_GF180PDK):
195
+ def __init__(self):
196
+ super().__init__("3LM_1TM_30K", "7t")
197
+
198
+
199
+ class GF180_3LM_1TM_30K_9t(_GF180PDK):
200
+ def __init__(self):
201
+ super().__init__("3LM_1TM_30K", "9t")
202
+
203
+
204
+ class GF180_4LM_1TM_6K_7t(_GF180PDK):
205
+ def __init__(self):
206
+ super().__init__("4LM_1TM_6K", "7t")
207
+
208
+
209
+ class GF180_4LM_1TM_6K_9t(_GF180PDK):
210
+ def __init__(self):
211
+ super().__init__("4LM_1TM_6K", "9t")
212
+
213
+
214
+ class GF180_4LM_1TM_9K_7t(_GF180PDK):
215
+ def __init__(self):
216
+ super().__init__("4LM_1TM_9K", "7t")
217
+
218
+
219
+ class GF180_4LM_1TM_9K_9t(_GF180PDK):
220
+ def __init__(self):
221
+ super().__init__("4LM_1TM_9K", "9t")
222
+
223
+
224
+ class GF180_4LM_1TM_11K_7t(_GF180PDK):
225
+ def __init__(self):
226
+ super().__init__("4LM_1TM_11K", "7t")
227
+
228
+
229
+ class GF180_4LM_1TM_11K_9t(_GF180PDK):
230
+ def __init__(self):
231
+ super().__init__("4LM_1TM_11K", "9t")
232
+
233
+
234
+ class GF180_4LM_1TM_30K_7t(_GF180PDK):
235
+ def __init__(self):
236
+ super().__init__("4LM_1TM_30K", "7t")
237
+
238
+
239
+ class GF180_4LM_1TM_30K_9t(_GF180PDK):
240
+ def __init__(self):
241
+ super().__init__("4LM_1TM_30K", "9t")
242
+
243
+
244
+ class GF180_5LM_1TM_9K_7t(_GF180PDK):
245
+ def __init__(self):
246
+ super().__init__("5LM_1TM_9K", "7t")
247
+
248
+
249
+ class GF180_5LM_1TM_9K_9t(_GF180PDK):
250
+ def __init__(self):
251
+ super().__init__("5LM_1TM_9K", "9t")
252
+
253
+
254
+ class GF180_5LM_1TM_11K_7t(_GF180PDK):
255
+ def __init__(self):
256
+ super().__init__("5LM_1TM_11K", "7t")
257
+
258
+
259
+ class GF180_5LM_1TM_11K_9t(_GF180PDK):
260
+ def __init__(self):
261
+ super().__init__("5LM_1TM_11K", "9t")
262
+
178
263
 
179
- return pdk
264
+ class GF180_6LM_1TM_9K_7t(_GF180PDK):
265
+ def __init__(self):
266
+ super().__init__("6LM_1TM_9K", "7t")
180
267
 
181
268
 
182
- #########################
183
- if __name__ == "__main__":
184
- pdk = setup()
185
- pdk.write_manifest(f'{pdk.top()}.json')
186
- pdk.check_filepaths()
269
+ class GF180_6LM_1TM_9K_9t(_GF180PDK):
270
+ def __init__(self):
271
+ super().__init__("6LM_1TM_9K", "9t")