prep-ic 0.1.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.
prep_ic/__init__.py ADDED
@@ -0,0 +1,43 @@
1
+ # SPDX-FileCopyrightText: 2026 Maximilian Golser and Simon Dorrer
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ """PREP-IC (Pinout, Ring and Early floorplan Planner for ICs): plan IC pad ring pinouts.
4
+
5
+ Scripting API (no Qt needed)::
6
+
7
+ import prep_ic as prep
8
+
9
+ project = prep.load("chip.json")
10
+ project.sides["L"].append("VDDA [p]")
11
+ project.settings.std.pitch = 90
12
+ layout = project.layout()
13
+ print(layout.die_width, layout.die_height, layout.warnings)
14
+ prep.export_csv(project, "pins.csv")
15
+ prep.export_svg(project, "ring.svg")
16
+ prep.save(project, "chip.json")
17
+
18
+ project.settings.pdk = "ihp-sg13g2" # see prep.pdk_names()
19
+ project.settings.package = "OP_QFN32_A4_FIT" # see prep.package_names()
20
+ prep.export_librelane(project, "flow/padring") # config part, pad_cfg.tcl, chip_top.sv, …
21
+ """
22
+
23
+ # defined before the imports: submodules import them
24
+ __version__ = "0.1.0"
25
+ APP_NAME = "PREP-IC"
26
+
27
+ from .formats.lef import read_lef
28
+ from .formats.librelane import export_librelane, librelane_files
29
+ from .formats.pinlist import export_csv
30
+ from .formats.project_file import load, save
31
+ from .formats.svg import export_svg, to_svg
32
+ from .model import (SIDE_NAMES, SIDES, TYPE_NAMES, TYPES, Floorplan, Layout, Macro, PadSettings, Pin,
33
+ Project, Settings, build_layout)
34
+ from .model.chip import (add_missing_pads, align_macros, analyse, auto_rotate, move_line, optimize_pad_order, place_line,
35
+ suggest_supply_pads, toggle_lock)
36
+ from .model.chip import add_missing_pads as generate_pads
37
+ from .model.pdk import get_package, get_pdk, package_names, pdk_names
38
+
39
+ __all__ = ["APP_NAME", "add_missing_pads", "align_macros", "analyse", "auto_rotate", "move_line",
40
+ "optimize_pad_order", "place_line", "suggest_supply_pads", "toggle_lock", "SIDES", "SIDE_NAMES", "TYPES", "TYPE_NAMES", "Floorplan", "Layout", "Macro", "PadSettings",
41
+ "Pin", "Project", "Settings", "build_layout", "export_csv", "export_librelane", "export_svg",
42
+ "generate_pads", "get_package", "get_pdk", "librelane_files", "load", "package_names", "pdk_names",
43
+ "read_lef", "save", "to_svg"]
prep_ic/__main__.py ADDED
@@ -0,0 +1,7 @@
1
+ # SPDX-FileCopyrightText: 2026 Maximilian Golser and Simon Dorrer
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ import sys
4
+
5
+ from .cli import main
6
+
7
+ sys.exit(main())
prep_ic/cli.py ADDED
@@ -0,0 +1,60 @@
1
+ # SPDX-FileCopyrightText: 2026 Maximilian Golser and Simon Dorrer
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ """Command line entry point. Without a subcommand the GUI starts.
4
+
5
+ prep-ic [PROJECT]
6
+ prep-ic export PROJECT [--csv FILE] [--svg FILE] [--librelane DIR]
7
+ """
8
+
9
+ import argparse
10
+ import sys
11
+
12
+ from . import APP_NAME, __version__, export_csv, export_librelane, export_svg, load
13
+
14
+
15
+ def _export(argv):
16
+ ap = argparse.ArgumentParser(prog="prep-ic export", description="Export a project without the GUI.")
17
+ ap.add_argument("project", help="project file (.json)")
18
+ ap.add_argument("--csv", metavar="FILE", help="write the pin list as CSV")
19
+ ap.add_argument("--svg", metavar="FILE", help="write the drawing as SVG")
20
+ ap.add_argument("--librelane", metavar="DIR",
21
+ help="write the LibreLane pad ring files (needs a PDK in the project)")
22
+ args = ap.parse_args(argv)
23
+ if not (args.csv or args.svg or args.librelane):
24
+ ap.error("nothing to export, give --csv, --svg and/or --librelane")
25
+ try:
26
+ project = load(args.project)
27
+ if args.csv:
28
+ export_csv(project, args.csv)
29
+ if args.svg:
30
+ export_svg(project, args.svg)
31
+ if args.librelane:
32
+ for path in export_librelane(project, args.librelane, source=args.project):
33
+ print(f"wrote {path}")
34
+ except (OSError, ValueError) as e:
35
+ print(f"error: {e}", file=sys.stderr)
36
+ return 1
37
+ for w in project.layout().warnings:
38
+ print(f"warning: {w}", file=sys.stderr)
39
+ return 0
40
+
41
+
42
+ def main(argv=None):
43
+ argv = sys.argv[1:] if argv is None else list(argv)
44
+ if argv and argv[0] == "export":
45
+ return _export(argv[1:])
46
+ ap = argparse.ArgumentParser(prog="prep-ic", description=f"{APP_NAME}: plan IC pad ring pinouts.",
47
+ epilog="Subcommand: 'prep-ic export -h' for exports without the GUI.")
48
+ ap.add_argument("project", nargs="?", help="project file (.json) to open")
49
+ ap.add_argument("--version", action="version", version=f"{APP_NAME} {__version__}")
50
+ args = ap.parse_args(argv)
51
+ try:
52
+ from .gui import run
53
+ except ImportError as e:
54
+ print(f"error: {e}", file=sys.stderr)
55
+ return 1
56
+ return run(args.project)
57
+
58
+
59
+ if __name__ == "__main__":
60
+ sys.exit(main())
@@ -0,0 +1,557 @@
1
+ {
2
+ "_source": "EUROPRACTICE package library EP_PACKAGES_08022018.gds (cell names); pin numbering counter-clockwise, seen from the top",
3
+ "packages": [
4
+ {
5
+ "name": "OP_QFN16_A4_FIT",
6
+ "label": "QFN16 (OP_QFN16_A4_FIT)",
7
+ "pins": 16,
8
+ "segments": [
9
+ [
10
+ "L",
11
+ 4
12
+ ],
13
+ [
14
+ "B",
15
+ 4
16
+ ],
17
+ [
18
+ "R",
19
+ 4
20
+ ],
21
+ [
22
+ "T",
23
+ 4
24
+ ]
25
+ ],
26
+ "pin1": "top of the left side"
27
+ },
28
+ {
29
+ "name": "OP_QFN24_A4_FIT",
30
+ "label": "QFN24 (OP_QFN24_A4_FIT)",
31
+ "pins": 24,
32
+ "segments": [
33
+ [
34
+ "L",
35
+ 6
36
+ ],
37
+ [
38
+ "B",
39
+ 6
40
+ ],
41
+ [
42
+ "R",
43
+ 6
44
+ ],
45
+ [
46
+ "T",
47
+ 6
48
+ ]
49
+ ],
50
+ "pin1": "top of the left side"
51
+ },
52
+ {
53
+ "name": "OP_QFN32_A4_FIT",
54
+ "label": "QFN32 (OP_QFN32_A4_FIT)",
55
+ "pins": 32,
56
+ "segments": [
57
+ [
58
+ "L",
59
+ 8
60
+ ],
61
+ [
62
+ "B",
63
+ 8
64
+ ],
65
+ [
66
+ "R",
67
+ 8
68
+ ],
69
+ [
70
+ "T",
71
+ 8
72
+ ]
73
+ ],
74
+ "pin1": "top of the left side"
75
+ },
76
+ {
77
+ "name": "OP_QFN40_6x6mm_A4_FIT",
78
+ "label": "QFN40 (OP_QFN40_6x6mm_A4_FIT)",
79
+ "pins": 40,
80
+ "segments": [
81
+ [
82
+ "L",
83
+ 10
84
+ ],
85
+ [
86
+ "B",
87
+ 10
88
+ ],
89
+ [
90
+ "R",
91
+ 10
92
+ ],
93
+ [
94
+ "T",
95
+ 10
96
+ ]
97
+ ],
98
+ "pin1": "top of the left side"
99
+ },
100
+ {
101
+ "name": "OP_QFN48_A4_FIT",
102
+ "label": "QFN48 (OP_QFN48_A4_FIT)",
103
+ "pins": 48,
104
+ "segments": [
105
+ [
106
+ "L",
107
+ 12
108
+ ],
109
+ [
110
+ "B",
111
+ 12
112
+ ],
113
+ [
114
+ "R",
115
+ 12
116
+ ],
117
+ [
118
+ "T",
119
+ 12
120
+ ]
121
+ ],
122
+ "pin1": "top of the left side"
123
+ },
124
+ {
125
+ "name": "OP_QFN56_A4_FIT",
126
+ "label": "QFN56 (OP_QFN56_A4_FIT)",
127
+ "pins": 56,
128
+ "segments": [
129
+ [
130
+ "L",
131
+ 14
132
+ ],
133
+ [
134
+ "B",
135
+ 14
136
+ ],
137
+ [
138
+ "R",
139
+ 14
140
+ ],
141
+ [
142
+ "T",
143
+ 14
144
+ ]
145
+ ],
146
+ "pin1": "top of the left side"
147
+ },
148
+ {
149
+ "name": "OP_QFN64_9x9mm_A4_FIT",
150
+ "label": "QFN64 (OP_QFN64_9x9mm_A4_FIT)",
151
+ "pins": 64,
152
+ "segments": [
153
+ [
154
+ "L",
155
+ 16
156
+ ],
157
+ [
158
+ "B",
159
+ 16
160
+ ],
161
+ [
162
+ "R",
163
+ 16
164
+ ],
165
+ [
166
+ "T",
167
+ 16
168
+ ]
169
+ ],
170
+ "pin1": "top of the left side"
171
+ },
172
+ {
173
+ "name": "OP_QFN80_12x12mm_A4",
174
+ "label": "QFN80 (OP_QFN80_12x12mm_A4)",
175
+ "pins": 80,
176
+ "segments": [
177
+ [
178
+ "L",
179
+ 20
180
+ ],
181
+ [
182
+ "B",
183
+ 20
184
+ ],
185
+ [
186
+ "R",
187
+ 20
188
+ ],
189
+ [
190
+ "T",
191
+ 20
192
+ ]
193
+ ],
194
+ "pin1": "top of the left side"
195
+ },
196
+ {
197
+ "name": "OP_QFN88_10x10mm_A4",
198
+ "label": "QFN88 (OP_QFN88_10x10mm_A4)",
199
+ "pins": 88,
200
+ "segments": [
201
+ [
202
+ "L",
203
+ 22
204
+ ],
205
+ [
206
+ "B",
207
+ 22
208
+ ],
209
+ [
210
+ "R",
211
+ 22
212
+ ],
213
+ [
214
+ "T",
215
+ 22
216
+ ]
217
+ ],
218
+ "pin1": "top of the left side"
219
+ },
220
+ {
221
+ "name": "OP_QFN100_12x12mm_A4",
222
+ "label": "QFN100 (OP_QFN100_12x12mm_A4)",
223
+ "pins": 100,
224
+ "segments": [
225
+ [
226
+ "L",
227
+ 25
228
+ ],
229
+ [
230
+ "B",
231
+ 25
232
+ ],
233
+ [
234
+ "R",
235
+ 25
236
+ ],
237
+ [
238
+ "T",
239
+ 25
240
+ ]
241
+ ],
242
+ "pin1": "top of the left side"
243
+ },
244
+ {
245
+ "name": "JLCC44_A4",
246
+ "label": "JLCC44 (JLCC44_A4)",
247
+ "pins": 44,
248
+ "segments": [
249
+ [
250
+ "T",
251
+ 6
252
+ ],
253
+ [
254
+ "L",
255
+ 11
256
+ ],
257
+ [
258
+ "B",
259
+ 11
260
+ ],
261
+ [
262
+ "R",
263
+ 11
264
+ ],
265
+ [
266
+ "T",
267
+ 5
268
+ ]
269
+ ],
270
+ "pin1": "centre of the top side"
271
+ },
272
+ {
273
+ "name": "JLCC68L_A4",
274
+ "label": "JLCC68 (JLCC68L_A4)",
275
+ "pins": 68,
276
+ "segments": [
277
+ [
278
+ "T",
279
+ 9
280
+ ],
281
+ [
282
+ "L",
283
+ 17
284
+ ],
285
+ [
286
+ "B",
287
+ 17
288
+ ],
289
+ [
290
+ "R",
291
+ 17
292
+ ],
293
+ [
294
+ "T",
295
+ 8
296
+ ]
297
+ ],
298
+ "pin1": "centre of the top side"
299
+ },
300
+ {
301
+ "name": "JLCC84_A4",
302
+ "label": "JLCC84 (JLCC84_A4)",
303
+ "pins": 84,
304
+ "segments": [
305
+ [
306
+ "T",
307
+ 11
308
+ ],
309
+ [
310
+ "L",
311
+ 21
312
+ ],
313
+ [
314
+ "B",
315
+ 21
316
+ ],
317
+ [
318
+ "R",
319
+ 21
320
+ ],
321
+ [
322
+ "T",
323
+ 10
324
+ ]
325
+ ],
326
+ "pin1": "centre of the top side"
327
+ },
328
+ {
329
+ "name": "CLCC44_A4",
330
+ "label": "CLCC44 (CLCC44_A4)",
331
+ "pins": 44,
332
+ "segments": [
333
+ [
334
+ "T",
335
+ 6
336
+ ],
337
+ [
338
+ "L",
339
+ 11
340
+ ],
341
+ [
342
+ "B",
343
+ 11
344
+ ],
345
+ [
346
+ "R",
347
+ 11
348
+ ],
349
+ [
350
+ "T",
351
+ 5
352
+ ]
353
+ ],
354
+ "pin1": "centre of the top side"
355
+ },
356
+ {
357
+ "name": "CLCC68L_A4",
358
+ "label": "CLCC68 (CLCC68L_A4)",
359
+ "pins": 68,
360
+ "segments": [
361
+ [
362
+ "T",
363
+ 9
364
+ ],
365
+ [
366
+ "L",
367
+ 17
368
+ ],
369
+ [
370
+ "B",
371
+ 17
372
+ ],
373
+ [
374
+ "R",
375
+ 17
376
+ ],
377
+ [
378
+ "T",
379
+ 8
380
+ ]
381
+ ],
382
+ "pin1": "centre of the top side"
383
+ },
384
+ {
385
+ "name": "CLCC84_A4",
386
+ "label": "CLCC84 (CLCC84_A4)",
387
+ "pins": 84,
388
+ "segments": [
389
+ [
390
+ "T",
391
+ 11
392
+ ],
393
+ [
394
+ "L",
395
+ 21
396
+ ],
397
+ [
398
+ "B",
399
+ 21
400
+ ],
401
+ [
402
+ "R",
403
+ 21
404
+ ],
405
+ [
406
+ "T",
407
+ 10
408
+ ]
409
+ ],
410
+ "pin1": "centre of the top side"
411
+ },
412
+ {
413
+ "name": "OP_SOIC16_A4",
414
+ "label": "SOIC16 (OP_SOIC16_A4)",
415
+ "pins": 16,
416
+ "segments": [
417
+ [
418
+ "L",
419
+ 8
420
+ ],
421
+ [
422
+ "R",
423
+ 8
424
+ ]
425
+ ],
426
+ "pin1": "top of the left side"
427
+ },
428
+ {
429
+ "name": "OP_SOIC20_A4",
430
+ "label": "SOIC20 (OP_SOIC20_A4)",
431
+ "pins": 20,
432
+ "segments": [
433
+ [
434
+ "L",
435
+ 10
436
+ ],
437
+ [
438
+ "R",
439
+ 10
440
+ ]
441
+ ],
442
+ "pin1": "top of the left side"
443
+ },
444
+ {
445
+ "name": "OP_SOIC24_A4",
446
+ "label": "SOIC24 (OP_SOIC24_A4)",
447
+ "pins": 24,
448
+ "segments": [
449
+ [
450
+ "L",
451
+ 12
452
+ ],
453
+ [
454
+ "R",
455
+ 12
456
+ ]
457
+ ],
458
+ "pin1": "top of the left side"
459
+ },
460
+ {
461
+ "name": "OP_SOIC28_A4",
462
+ "label": "SOIC28 (OP_SOIC28_A4)",
463
+ "pins": 28,
464
+ "segments": [
465
+ [
466
+ "L",
467
+ 14
468
+ ],
469
+ [
470
+ "R",
471
+ 14
472
+ ]
473
+ ],
474
+ "pin1": "top of the left side"
475
+ },
476
+ {
477
+ "name": "DIL16_A4",
478
+ "label": "DIL16 (DIL16_A4)",
479
+ "pins": 16,
480
+ "segments": [
481
+ [
482
+ "L",
483
+ 8
484
+ ],
485
+ [
486
+ "R",
487
+ 8
488
+ ]
489
+ ],
490
+ "pin1": "top of the left side"
491
+ },
492
+ {
493
+ "name": "DIL24_A4",
494
+ "label": "DIL24 (DIL24_A4)",
495
+ "pins": 24,
496
+ "segments": [
497
+ [
498
+ "L",
499
+ 12
500
+ ],
501
+ [
502
+ "R",
503
+ 12
504
+ ]
505
+ ],
506
+ "pin1": "top of the left side"
507
+ },
508
+ {
509
+ "name": "DIL28_A4_cav7800",
510
+ "label": "DIL28 (DIL28_A4_cav7800)",
511
+ "pins": 28,
512
+ "segments": [
513
+ [
514
+ "L",
515
+ 14
516
+ ],
517
+ [
518
+ "R",
519
+ 14
520
+ ]
521
+ ],
522
+ "pin1": "top of the left side"
523
+ },
524
+ {
525
+ "name": "DIL40L_A4",
526
+ "label": "DIL40L (DIL40L_A4)",
527
+ "pins": 40,
528
+ "segments": [
529
+ [
530
+ "L",
531
+ 20
532
+ ],
533
+ [
534
+ "R",
535
+ 20
536
+ ]
537
+ ],
538
+ "pin1": "top of the left side"
539
+ },
540
+ {
541
+ "name": "DIL48L_A4",
542
+ "label": "DIL48L (DIL48L_A4)",
543
+ "pins": 48,
544
+ "segments": [
545
+ [
546
+ "L",
547
+ 24
548
+ ],
549
+ [
550
+ "R",
551
+ 24
552
+ ]
553
+ ],
554
+ "pin1": "top of the left side"
555
+ }
556
+ ]
557
+ }