Skip to content

Commit 897fb9d

Browse files
author
htfab
committed
feat: add a simple fill generator
1 parent 7de8c6f commit 897fb9d

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

Diff for: .github/workflows/gds.yaml

+7-2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ jobs:
5757
run: |
5858
make
5959
60+
- name: Generate fill
61+
run: |
62+
pip install klayout
63+
scripts/add-fill.py
64+
6065
- name: Upload flow results
6166
uses: actions/upload-artifact@v4
6267
if: always()
@@ -123,7 +128,7 @@ jobs:
123128
124129
- name: Run DRC
125130
run: |
126-
klayout -b -r ./IHP-Open-PDK/ihp-sg13g2/libs.tech/klayout/tech/drc/sg13g2_minimal.lydrc -rd cell=tt_top -rd report_file=sg13g2_minimal.lyrdb ./results/ihp-sg13g2/tt-chip/base/6_final.gds
131+
klayout -b -r ./IHP-Open-PDK/ihp-sg13g2/libs.tech/klayout/tech/drc/sg13g2_minimal.lydrc -rd cell=tt_top -rd report_file=sg13g2_minimal.lyrdb ./results/ihp-sg13g2/tt-chip/base/6_final_fill.gds
127132
128133
- name: Upload DRC results
129134
uses: actions/upload-artifact@v4
@@ -163,7 +168,7 @@ jobs:
163168
164169
- name: Run DRC
165170
run: |
166-
klayout -b -r ./IHP-Open-PDK/ihp-sg13g2/libs.tech/klayout/tech/drc/sg13g2_maximal.lydrc -rd cell=tt_top -rd report_file=sg13g2_maximal.lyrdb ./results/ihp-sg13g2/tt-chip/base/6_final.gds
171+
klayout -b -r ./IHP-Open-PDK/ihp-sg13g2/libs.tech/klayout/tech/drc/sg13g2_maximal.lydrc -rd cell=tt_top -rd report_file=sg13g2_maximal.lyrdb ./results/ihp-sg13g2/tt-chip/base/6_final_fill.gds
167172
168173
- name: Upload DRC results
169174
uses: actions/upload-artifact@v4

Diff for: scripts/add-fill.py

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/usr/bin/env python3
2+
3+
# simple fill generator inspired by https://github.com/IHP-GmbH/IHP-Open-DesignLib/tree/main/U_Hawaii_EE628_Spring_2024
4+
5+
import pya
6+
7+
results_dir = "results/ihp-sg13g2/tt-chip/base"
8+
input_gds = f"{results_dir}/6_final.gds"
9+
output_gds = f"{results_dir}/6_final_fill.gds"
10+
11+
die_size = (2200, 2200)
12+
die_margin = 36
13+
fill_grid = 6
14+
fill_spacing = 6
15+
fill_groups = [
16+
[("Activ", (1, 0), 4),
17+
("GatPoly", (5, 0), 4),
18+
("NWell", (31, 0), 5)],
19+
[("Metal1", (8, 0), 4)],
20+
[("Metal2", (10, 0), 4)],
21+
[("Metal3", (30, 0), 3)],
22+
[("Metal4", (50, 0), 3)],
23+
[("Metal5", (67, 0), 2)],
24+
]
25+
26+
layout = pya.Layout()
27+
layout.read(input_gds)
28+
top = layout.top_cell()
29+
u = round(1/layout.dbu)
30+
31+
fill_box = pya.Box(die_margin*u, die_margin*u, (die_size[0]-die_margin)*u, (die_size[1]-die_margin)*u)
32+
shift_box = pya.Box(-fill_grid*u//2, -fill_grid*u//2, (fill_grid*u+1)//2, (fill_grid*u+1)//2)
33+
fill_margin = pya.Vector(fill_spacing*u, fill_spacing*u)
34+
fill_origin = pya.Point(0, 0)
35+
36+
for fill_layers in fill_groups:
37+
layer_list = [layer_name for layer_name, *_ in fill_layers]
38+
print(f"Generating fill for {' & '.join(layer_list)}...")
39+
cell_index = layout.add_cell(f"FILL_{layer_list[0]}")
40+
cell_obj = layout.cell(cell_index)
41+
fill_region = pya.Region(fill_box)
42+
for layer_name, (layer, datatype), size in fill_layers:
43+
layer_index = layout.layer(layer, datatype)
44+
cell_obj.shapes(layer_index).insert(pya.Box(-size*u//2, -size*u//2, (size*u+1)//2, (size*u+1)//2))
45+
exclude_region = pya.Region(top.begin_shapes_rec(layer_index))
46+
fill_region -= exclude_region
47+
top.fill_region(fill_region, cell_index, shift_box, fill_origin, fill_region, fill_margin, None)
48+
49+
layout.write(output_gds)
50+

0 commit comments

Comments
 (0)