Skip to content

Commit

Permalink
fix: workaround for the sky130 poly density issue
Browse files Browse the repository at this point in the history
Replace 50% of the decap_12 cells with newfill_12 cells across all Wokwi designs.
  • Loading branch information
urish committed Nov 6, 2024
1 parent b63fab8 commit 8c72b8a
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/gds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ jobs:
pdk_version: ${{ env.SKY130_PDK_VERSION }}
pdk_root: ${{ env.PDK_ROOT }}

# Patch Wokwi designs to work around the poly density issue
- name: Patch Wokwi designs
working-directory: projects
run: |
for project in tt_um_wokwi_*; do
python ../sky130_density_fix/replace_decap.py --design $project --user-gds $project/$project.gds --replacement-gds ../sky130_density_fix/sky130_ef_sc_hd__newfill_12.gds
done
# run OpenLane to build the GDS
- name: Harden Chip ROM
run: nix-shell $GITHUB_WORKSPACE/openlane2/shell.nix --run "python -m openlane tt/rom/config.json"
Expand Down
1 change: 1 addition & 0 deletions sky130_density_fix/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sky130_ef_sc_hd__newfill_12.gds retrieved from https://github.com/RTimothyEdwards/open_pdks/blob/320597ea84b2816eb2fcc4fbe10c3874f19c92fc/sky130/custom/sky130_fd_sc_hd/gds/sky130_ef_sc_hd__newfill_12.gds
87 changes: 87 additions & 0 deletions sky130_density_fix/replace_decap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# SPDX-License-Identifier: Apache-2.0
# Authors: David Lindley, Uri Shaked

import argparse
from random import random, seed

import klayout.db as pya

# We want reproducible results:
seed(a=0)

parser = argparse.ArgumentParser(
description="Replaces a given portion of a decap_12 cells with newfill_12 cells."
)

parser.add_argument("--probability", "-p", type=float, default=0.5, help="")

parser.add_argument("--design-name", "-n", required=True)

parser.add_argument("--from-cell-name", "-f", default="sky130_ef_sc_hd__decap_12")
parser.add_argument("--to-cell-name", "-t", default="sky130_ef_sc_hd__newfill_12")

parser.add_argument("--user-gds", "-i", required=True)
parser.add_argument("--replacement-gds", "-r", required=True)

parser.add_argument("--output-gds", "-o", required=False)


args = parser.parse_args()

probability = args.probability

design_name = args.design_name

from_cell_name = args.from_cell_name
to_cell_name = args.to_cell_name

user_gds = args.user_gds
replacement_gds = args.replacement_gds
output_gds = args.output_gds or user_gds

replacement_layout = pya.Layout()
replacement_layout.read(replacement_gds)

user_layout = pya.Layout()
user_layout.read(user_gds)

top_cell = user_layout.cell(design_name)
replacement_cell = user_layout.create_cell(to_cell_name)
replacement_cell.copy_tree(replacement_layout.cell(to_cell_name))


def cell_dimensions_equal(cell1, cell2):
return (
cell1.bbox().width() == cell2.bbox().width()
and cell1.bbox().height() == cell2.bbox().height()
)


print("Top-cell name:", top_cell.name)
print("From-cell prefix:", from_cell_name)
print("Replacement-cell name:", replacement_cell.name)
matches = 0
replacements = 0

for inst in top_cell.each_inst():
assert inst is not None

# Make sure we haven't already processed this gds
assert inst.cell.name != to_cell_name

# For cells that have no hierarchy beneath (standard cells in this case)
if inst.cell.hierarchy_levels() == 0 and inst.cell.name == from_cell_name:
assert cell_dimensions_equal(inst.cell, replacement_cell)
matches += 1

if random() < probability:
continue

inst.cell = replacement_cell
replacements += 1

print(f"Replaced {replacements} cells out of {matches} matches.")
print(f"Writing to {output_gds}...")

user_layout.write(output_gds)
print("Done.")
Binary file not shown.

0 comments on commit 8c72b8a

Please sign in to comment.