feat(logo): IHP shuttle support

This commit is contained in:
Uri Shaked
2025-08-19 23:14:09 +03:00
parent d69a0eac0c
commit 58807a2145
7 changed files with 101 additions and 56 deletions
+1
View File
@@ -11,3 +11,4 @@ class Config(TypedDict):
top_level_macro: str top_level_macro: str
powered_netlists: bool powered_netlists: bool
no_power_gating: bool no_power_gating: bool
pdk: str
+4 -1
View File
@@ -306,7 +306,7 @@ if __name__ == "__main__":
docs = Docs(config, projects.projects) docs = Docs(config, projects.projects)
shuttle = ShuttleConfig(config, projects.projects, modules_yaml_name) shuttle = ShuttleConfig(config, projects.projects, modules_yaml_name)
rom = ROMFile(config) rom = ROMFile(config)
logo = LogoGenerator("tt", config) logo = LogoGenerator("tt", pdk=config["pdk"], config=config)
if args.list: if args.list:
shuttle.list() shuttle.list()
@@ -317,7 +317,10 @@ if __name__ == "__main__":
if args.update_shuttle: if args.update_shuttle:
shuttle.configure_mux() shuttle.configure_mux()
rom.write_rom() rom.write_rom()
logo.gen_logo("top", "tt/logo/tt_logo_top.gds")
logo.gen_lef("top", "tt/logo/tt_logo_top.lef")
logo.gen_logo("bottom", "tt/logo/tt_logo_bottom.gds") logo.gen_logo("bottom", "tt/logo/tt_logo_bottom.gds")
logo.gen_lef("bottom", "tt/logo/tt_logo_bottom.lef")
if not args.test: if not args.test:
docs.build_index() docs.build_index()
+94 -23
View File
@@ -1,6 +1,8 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import argparse
import sys import sys
from typing import Dict, TypedDict
import gdstk import gdstk
from git.repo import Repo from git.repo import Repo
@@ -9,9 +11,42 @@ from PIL import Image, ImageDraw, ImageFont
from config import Config from config import Config
class TechDef(TypedDict):
PRBOUNDARY_LAYER: int
PRBOUNDARY_DATATYPE: int
LOGO_LAYER: int
LOGO_DATATYPE: int
OBS_LAYER_NAME: str
PIXEL_SIZE: float
tech: Dict[str, TechDef] = {
"sky130": {
"PRBOUNDARY_LAYER": 235, # prBoundary
"PRBOUNDARY_DATATYPE": 4, # .boundary
"LOGO_LAYER": 71, # Metal4
"LOGO_DATATYPE": 20, # .drawing
"OBS_LAYER_NAME": "met4",
"PIXEL_SIZE": 0.5, # um
},
"ihp-sg13g2": {
"PRBOUNDARY_LAYER": 189, # prBoundary
"PRBOUNDARY_DATATYPE": 4, # .boundary
"LOGO_LAYER": 67, # Metal5
"LOGO_DATATYPE": 0, # .drawing
"OBS_LAYER_NAME": "Metal5",
"PIXEL_SIZE": 0.25, # um
},
}
LOGO_WIDTH = 200
LOGO_HEIGHT = 200
class LogoGenerator: class LogoGenerator:
def __init__(self, tt_dir, config: Config | None = None): def __init__(self, tt_dir, pdk: str, config: Config | None = None):
self.tt_dir = tt_dir self.tt_dir = tt_dir
self.pdk = pdk
self.config = config self.config = config
def gen_logo(self, variant: str, gds_file: str, shuttle=None, commit=None): def gen_logo(self, variant: str, gds_file: str, shuttle=None, commit=None):
@@ -29,7 +64,7 @@ class LogoGenerator:
if commit is None: if commit is None:
commit = Repo(".").commit().hexsha commit = Repo(".").commit().hexsha
img = Image.new("L", (200, 200), (0,)) img = Image.new("L", (LOGO_WIDTH, LOGO_HEIGHT), (0,))
draw = ImageDraw.Draw(img) draw = ImageDraw.Draw(img)
font_file = f"{self.tt_dir}/logo/font/UbuntuSansMono.ttf" font_file = f"{self.tt_dir}/logo/font/UbuntuSansMono.ttf"
@@ -45,17 +80,19 @@ class LogoGenerator:
shuttle = shuttle[:-1].upper() + shuttle[-1] shuttle = shuttle[:-1].upper() + shuttle[-1]
shuttle_font_size = 44 shuttle_font_size = 44
shuttle_y_offset = 10 shuttle_y_offset = 10
draw.text((2, shuttle_y_offset), shuttle, fill=255, font=font(shuttle_font_size)) draw.text(
(2, shuttle_y_offset), shuttle, fill=255, font=font(shuttle_font_size)
)
draw.text((2, 68), commit[:8], fill=255, font=font(44)) draw.text((2, 68), commit[:8], fill=255, font=font(44))
draw.text((2, 107), commit[8:18], fill=255, font=font(35)) draw.text((2, 107), commit[8:18], fill=255, font=font(35))
draw.text((1, 137), commit[18:29], fill=255, font=font(32)) draw.text((1, 137), commit[18:29], fill=255, font=font(32))
draw.text((1, 165), commit[29:], fill=255, font=font(32)) draw.text((1, 165), commit[29:], fill=255, font=font(32))
PRBOUNDARY_LAYER = 235 PRBOUNDARY_LAYER = tech[self.pdk]["PRBOUNDARY_LAYER"]
PRBOUNDARY_DATATYPE = 4 PRBOUNDARY_DATATYPE = tech[self.pdk]["PRBOUNDARY_DATATYPE"]
MET4_LAYER = 71 MET4_LAYER = tech[self.pdk]["LOGO_LAYER"]
DRAWING_DATATYPE = 20 DRAWING_DATATYPE = tech[self.pdk]["LOGO_DATATYPE"]
PIXEL_SIZE = 0.5 # um PIXEL_SIZE = tech[self.pdk]["PIXEL_SIZE"]
lib = gdstk.Library() lib = gdstk.Library()
cell = lib.new_cell(f"tt_logo_{variant}") cell = lib.new_cell(f"tt_logo_{variant}")
@@ -82,22 +119,56 @@ class LogoGenerator:
lib.write_gds(gds_file) lib.write_gds(gds_file)
def gen_lef(self, variant: str, lef_file: str):
assert variant in ("top", "bottom")
width = tech[self.pdk]["PIXEL_SIZE"] * LOGO_WIDTH
height = tech[self.pdk]["PIXEL_SIZE"] * LOGO_HEIGHT
lef_lines = [
f"VERSION 5.7 ;",
f" NOWIREEXTENSIONATPIN ON ;",
f' DIVIDERCHAR "/" ;',
f' BUSBITCHARS "[]" ;',
f"MACRO tt_logo_{variant}",
f" CLASS BLOCK ;",
f" FOREIGN tt_logo_{variant} ;",
f" ORIGIN 0.000 0.000 ;",
f" SIZE {width:.3f} BY {height:.3f} ;",
f" OBS",
f' LAYER {tech[self.pdk]["OBS_LAYER_NAME"]} ;',
f" RECT 0.000 0.000 {width:.3f} {height:.3f} ;",
f" END",
f"END tt_logo_{variant}",
f"END LIBRARY",
]
with open(lef_file, "w") as f:
f.write("\n".join(lef_lines) + "\n")
if __name__ == "__main__": if __name__ == "__main__":
try: parser = argparse.ArgumentParser(description="TT logo generator")
if sys.argv[1] == "--top": parser.add_argument(
LogoGenerator(".").gen_logo("top", "logo/tt_logo_top.gds") "--pdk", type=str, default="sky130", choices=["sky130", "ihp-sg13g2"]
)
parser.add_argument("--top", action="store_true")
parser.add_argument("--bottom", action="store_true")
parser.add_argument("--shuttle", type=str, default="tt10")
parser.add_argument(
"--commit", type=str, default="0123456789abcdef0123456789abcdef01234567"
)
args = parser.parse_args()
elif sys.argv[1] == "--bottom": generator = LogoGenerator(".", pdk=args.pdk)
shuttle = sys.argv[2] # e.g. "tt10" if args.top:
commit = sys.argv[3] # e.g. "0123456789abcdef0123456789abcdef01234567" generator.gen_logo("top", "logo/tt_logo_top.gds")
LogoGenerator(".").gen_logo( generator.gen_lef("top", "logo/tt_logo_top.lef")
"bottom", "logo/tt_logo_bottom.gds", shuttle, commit if args.bottom:
) shuttle = args.shuttle
commit = args.commit
except IndexError: generator.gen_logo("bottom", "logo/tt_logo_bottom.gds", shuttle, commit)
print( generator.gen_lef("bottom", "logo/tt_logo_bottom.lef")
f"Usage:\n {sys.argv[0]} --top\n {sys.argv[0]} --bottom <shuttle> <commit>", if not args.top and not args.bottom:
file=sys.stderr, print(f"Need to specify --top or --bottom", file=sys.stderr)
) parser.print_help()
sys.exit(1)
+2
View File
@@ -0,0 +1,2 @@
tt_logo_*.gds
tt_logo_*.lef
-16
View File
@@ -1,16 +0,0 @@
VERSION 5.7 ;
NOWIREEXTENSIONATPIN ON ;
DIVIDERCHAR "/" ;
BUSBITCHARS "[]" ;
MACRO tt_logo_bottom
CLASS BLOCK ;
FOREIGN tt_logo_bottom ;
ORIGIN 0.000 0.000 ;
SIZE 100.000 BY 100.000 ;
OBS
LAYER met4 ;
RECT 0.000 0.000 100.000 100.000 ;
END
END tt_logo_bottom
END LIBRARY
Binary file not shown.
-16
View File
@@ -1,16 +0,0 @@
VERSION 5.7 ;
NOWIREEXTENSIONATPIN ON ;
DIVIDERCHAR "/" ;
BUSBITCHARS "[]" ;
MACRO tt_logo_top
CLASS BLOCK ;
FOREIGN tt_logo_top ;
ORIGIN 0.000 0.000 ;
SIZE 100.000 BY 100.000 ;
OBS
LAYER met4 ;
RECT 0.000 0.000 100.000 100.000 ;
END
END tt_logo_top
END LIBRARY