Skip to content

Commit

Permalink
feat: GDS to glTF + S3 upload script
Browse files Browse the repository at this point in the history
  • Loading branch information
urish committed Jan 27, 2025
1 parent d7dbbd8 commit 2573d72
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 13 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "scripts/GDS2glTF"]
path = scripts/GDS2glTF
url = https://github.com/tinytapeout/GDS2glTF
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,18 @@ Where `<shuttle>` is the identifier of the shuttle (e.g. tt04).
You can also specify the scale of the render by passing the `--scale` argument. For example, to render the all the projects in shuttle tt04 at 2x scale, run:

```bash
python render.py tt04 --scale 2
python render_projects.py tt04 --scale 2
```

## Generating glTF files

To generate glTF files for the projects, run the following commands:

```bash
git submodule update --init --recursive
cd scripts
pip install -r requirements.txt -r GDS2glTF/requirements.txt
python render_gltf.py <shuttle>
```

## License
Expand Down
3 changes: 3 additions & 0 deletions scripts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
__pycache__/
.env

1 change: 1 addition & 0 deletions scripts/GDS2glTF
Submodule GDS2glTF added at 9706fe
1 change: 1 addition & 0 deletions scripts/gltf/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.gltf
100 changes: 100 additions & 0 deletions scripts/render_gltf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
"""
SPDX-License-Identifier: Apache-2.0
Copyright (C) 2025 Tiny Tapeout LTD
Author: Uri Shaked
Converts all shuttle GDS files to glTF format. Optionally uploads the results to S3.
To run this script, you need to have the following environment variables set:
* AWS_ACCESS_KEY_ID - AWS access key
* AWS_SECRET_ACCESS_KEY - AWS secret key
You can also set the following environment variables:
* S3_ENDPOINT_URL - S3 endpoint URL (default: s3.amazonaws.com)
* S3_BUCKET - S3 bucket name (default: tt-shuttle-assets)
You can set these environment variables in a .env file in the same directory as this script.
"""

import argparse
import json
import logging
import os
import urllib.parse
import urllib.request
from pathlib import Path

import boto3
from dotenv import load_dotenv

from GDS2glTF.gds2gltf import gds2gltf
from render_projects import download_gds

SCRIPT_DIR = Path(__file__).parent


def main(shuttle_id: str, upload_bucket=None):
project_list_url = f"https://index.tinytapeout.com/{shuttle_id}.json"
req = urllib.request.Request(
project_list_url, headers={"User-Agent": "Mozilla/5.0"}
)
with urllib.request.urlopen(req) as req:
project_list = json.load(req)["projects"]
logging.info(f"Found {len(project_list)} projects in shuttle {shuttle_id}")

pdk = "sg13g2" if shuttle_id.startswith("ttihp") else "sky130A"

for project in project_list:
macro = project["macro"]
gds_file = download_gds(shuttle_id, macro)

logging.info(f"Converting {macro}")
gltf_file = SCRIPT_DIR / "gltf" / shuttle_id / (macro + ".gds.gltf")
gltf_file.parent.mkdir(parents=True, exist_ok=True)

logging.info(f"Writing {gltf_file}")
gds2gltf(gds_file, gltf_file, pdk_name=pdk)

if upload_bucket:
logging.info("Uploading to S3...")
with open(gltf_file, "rb") as f:
upload_bucket.put_object(
Key=f"{shuttle_id}/{macro}/{macro}.gds.gltf",
Body=f,
)


if __name__ == "__main__":
load_dotenv()
logging.basicConfig(level=logging.INFO)

parser = argparse.ArgumentParser(description="Update shuttle index")
parser.add_argument("shuttle_id", type=str, help="Shuttle ID")
parser.add_argument(
"-u",
"--upload",
action="store_true",
help="Upload to S3/R2",
)
parser.add_argument(
"--s3-endpoint",
type=str,
help="S3 endpoint",
default=os.getenv("S3_ENDPOINT_URL", "s3.amazonaws.com"),
)
parser.add_argument(
"--s3-bucket",
type=str,
help="S3 bucket",
default=os.getenv("S3_BUCKET", "tt-shuttle-assets"),
)
args = parser.parse_args()

upload_bucket = None
if args.upload:
s3 = boto3.resource("s3", endpoint_url=args.s3_endpoint)
upload_bucket = s3.Bucket(args.s3_bucket)

main(args.shuttle_id, upload_bucket=upload_bucket)
27 changes: 15 additions & 12 deletions scripts/render_projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import urllib.request
from pathlib import Path

from klayout.db import Layout, SaveLayoutOptions
from klayout.lay import LayoutView

SCRIPT_DIR = Path(__file__).parent
Expand Down Expand Up @@ -50,7 +51,8 @@ def download_gds(shuttle_id: str, macro: str) -> Path:
sys.exit(1)

gds_url = shuttle["project_gds_url_template"].format(macro=macro)
if macro == "tt_um_chip_rom":
is_rom = macro == "tt_um_chip_rom"
if is_rom:
gds_url = shuttle["gds_url"]
logging.info(f"Downloading GDS file from {gds_url}")

Expand All @@ -64,6 +66,18 @@ def download_gds(shuttle_id: str, macro: str) -> Path:
else:
f.write(response.read())

if is_rom:
layout = Layout()
layout.read(target_path)
for cell in layout.each_cell():
if cell.name == "tt_um_chip_rom" or cell.name.endswith("_tt_um_chip_rom"):
rom_cell = cell
if not rom_cell:
raise Exception("ROM cell not found")
save_options = SaveLayoutOptions()
save_options.add_cell(rom_cell.cell_index())
layout.write(target_path, options=save_options)

return target_path


Expand All @@ -72,7 +86,6 @@ def render_gds(
output_path: str,
pdk: str,
scale: float = 1.0,
is_rom=False,
):
BOUNDARY_LAYER = TECHNOLOGIES[pdk]["boundary"]
hide_layers = TECHNOLOGIES[pdk]["hide_layers"]
Expand All @@ -82,15 +95,6 @@ def render_gds(
lv.max_hier()
lv.load_layer_props(SCRIPT_DIR / "lyp" / f"{pdk}.lyp")

if is_rom:
layout = lv.cellview(0).layout()
for cell in layout.each_cell():
if cell.name == "tt_um_chip_rom" or cell.name.endswith("_tt_um_chip_rom"):
rom_cell = cell
if not rom_cell:
raise Exception("ROM cell not found")
lv.cellview(0).set_cell_name(rom_cell.name)

lv.set_config("background-color", "#ffffff")
lv.set_config("grid-visible", "false")
lv.set_config("text-visible", "false")
Expand Down Expand Up @@ -142,7 +146,6 @@ def main(shuttle_id: str, scale: float = 1.0):
png_dir / "render.png",
pdk=pdk,
scale=scale,
is_rom=project["macro"] == "tt_um_chip_rom",
)


Expand Down
2 changes: 2 additions & 0 deletions scripts/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
klayout==0.29.11
pre-commit==3.4.0
python-dotenv==1.0.1
boto3==1.36.6

0 comments on commit 2573d72

Please sign in to comment.