Skip to content

Commit

Permalink
Merge pull request hdl#257 from mithro/cell-foreach
Browse files Browse the repository at this point in the history
Refactoring standard cell libraries options and test all of them
  • Loading branch information
mithro authored Dec 22, 2023
2 parents d40ce30 + f62c811 commit 08884ef
Show file tree
Hide file tree
Showing 19 changed files with 960 additions and 322 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
bazel-*/
bazel-*
MODULE.bazel
MODULE.bazel.lock
8 changes: 7 additions & 1 deletion dependency_support/com_google_skywater_pdk/build_defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,19 @@ def _skywater_cell_library_impl(ctx):
open_road_configuration = ctx.attr.openroad_configuration[OpenRoadPdkInfo]

cell_lef_files = [lef_file for lef_file in ctx.files.srcs if lef_file.extension == "lef"]
if not cell_lef_files:
fail("No cell lef files found in " + str(ctx.files.srcs))
platform_gds_files = [gds_file for gds_file in ctx.files.srcs if gds_file.extension == "gds"]
if not platform_gds_files:
fail("No gds files found in " + str(ctx.files.srcs))

tech_lef = None
if ctx.attr.tech_lef:
tech_lef = ctx.file.tech_lef

default_corner = corners.get(ctx.attr.default_corner, None)
default_corner = corners.get(ctx.attr.default_corner)
if not default_corner:
fail("Did not find the default corner provided:" + str(ctx.attr.default_corner))
default_lib_depset = []
if default_corner:
default_lib_depset = [default_corner.liberty]
Expand Down
48 changes: 25 additions & 23 deletions dependency_support/com_google_skywater_pdk/cell_libraries.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ CELL_LIBRARIES = {
"commit": "7ec511f1a4689e174c63b3964d1ba8da9a3565e5", # v0.2.1, 2020-12-09
"shallow_since": "1606239275 -0800",
"library_type": "ip_library",
"corners": {},
},
"sky130_fd_pr": {
"commit": "f62031a1be9aefe902d6d54cddd6f59b57627436", # v0.20.1, 2020-12-09
"shallow_since": "1605038979 -0800",
"library_type": "ip_library",
"corners": {},
},
"sky130_fd_sc_hd": {
"commit": "ac7fb61f06e6470b94e8afdf7c25268f62fbd7b1", # v0.0.2, 2020-12-04
Expand Down Expand Up @@ -123,20 +125,20 @@ CELL_LIBRARIES = {
"ff_n40C_5v50": ["basic", "ccsnoise"],
"ff_n40C_5v50_lowhv1v65_lv1v95": ["basic"],
"ff_n40C_5v50_lv1v95": ["basic", "ccsnoise"],
"hvff_lvss_100C_5v50_lowhv1v65_lv1v60": ["basic"],
"hvff_lvss_100C_5v50_lv1v40": ["basic"],
"hvff_lvss_100C_5v50_lv1v60": ["basic"],
"hvff_lvss_n40C_5v50_lowhv1v65_lv1v60": ["basic"],
"hvff_lvss_n40C_5v50_lv1v35": ["basic"],
"hvff_lvss_n40C_5v50_lv1v60": ["basic"],
"hvss_lvff_100C_1v65": ["basic"],
"hvss_lvff_100C_1v95": ["basic"],
"hvss_lvff_100C_1v95_lowhv1v65": ["basic"],
"hvss_lvff_100C_5v50_lowhv1v65_lv1v95": ["basic"],
"hvss_lvff_n40C_1v65": ["basic"],
"hvss_lvff_n40C_1v95": ["basic"],
"hvss_lvff_n40C_1v95_lowhv1v65": ["basic"],
"hvss_lvff_n40C_5v50_lowhv1v65_lv1v95": ["basic"],
#"hvff_lvss_100C_5v50_lowhv1v65_lv1v60": ["basic"],
#"hvff_lvss_100C_5v50_lv1v40": ["basic"],
#"hvff_lvss_100C_5v50_lv1v60": ["basic"],
#"hvff_lvss_n40C_5v50_lowhv1v65_lv1v60": ["basic"],
#"hvff_lvss_n40C_5v50_lv1v35": ["basic"],
#"hvff_lvss_n40C_5v50_lv1v60": ["basic"],
#"hvss_lvff_100C_1v65": ["basic"],
#"hvss_lvff_100C_1v95": ["basic"],
#"hvss_lvff_100C_1v95_lowhv1v65": ["basic"],
#"hvss_lvff_100C_5v50_lowhv1v65_lv1v95": ["basic"],
#"hvss_lvff_n40C_1v65": ["basic"],
#"hvss_lvff_n40C_1v95": ["basic"],
#"hvss_lvff_n40C_1v95_lowhv1v65": ["basic"],
#"hvss_lvff_n40C_5v50_lowhv1v65_lv1v95": ["basic"],
"ss_100C_1v65": ["basic"],
"ss_100C_1v65_lv1v40": ["basic"],
"ss_100C_1v65_lv1v60": ["basic"],
Expand All @@ -150,7 +152,7 @@ CELL_LIBRARIES = {
"ss_150C_1v65_lv1v60": ["basic"],
"ss_150C_3v00_lowhv1v65_lv1v60": ["basic"],
"ss_n40C_1v32": ["basic"],
"ss_n40C_1v32_lv1v28": ["basic"],
#"ss_n40C_1v32_lv1v28": ["basic"],
"ss_n40C_1v49": ["basic"],
"ss_n40C_1v49_lv1v44": ["basic"],
"ss_n40C_1v65": ["basic", "ccsnoise"],
Expand All @@ -159,13 +161,13 @@ CELL_LIBRARIES = {
"ss_n40C_1v65_lv1v60": ["basic", "ccsnoise"],
"ss_n40C_1v95": ["basic"],
"ss_n40C_5v50_lowhv1v65_lv1v60": ["basic"],
"tt_025C_2v64_lv1v80": ["basic"],
"tt_025C_2v97_lv1v80": ["basic"],
#"tt_025C_2v64_lv1v80": ["basic"],
#"tt_025C_2v97_lv1v80": ["basic"],
"tt_025C_3v30": ["basic"],
"tt_025C_3v30_lv1v80": ["basic"],
#"tt_025C_3v30_lv1v80": ["basic"],
"tt_100C_3v30": ["basic"],
"tt_100C_3v30_lv1v80": ["basic"],
"tt_150C_3v30_lv1v80": ["basic"],
#"tt_100C_3v30_lv1v80": ["basic"],
#"tt_150C_3v30_lv1v80": ["basic"],
},
"default_corner": "ss_100C_1v95",
},
Expand Down Expand Up @@ -195,11 +197,11 @@ CELL_LIBRARIES = {
"shallow_since": "1604476021 -0800",
"corners": {
"ff_085C_1v95": ["basic"],
"ff_100C_1v65_dest1v76_destvpb1v76_ka1v76": ["basic"],
#"ff_100C_1v65_dest1v76_destvpb1v76_ka1v76": ["basic"],
"ff_100C_1v95": ["basic"],
"ff_150C_1v95": ["basic"],
"ff_n40C_1v56": ["basic"],
"ff_n40C_1v65_dest1v76_destvpb1v76_ka1v76": ["basic"],
#"ff_n40C_1v65_dest1v76_destvpb1v76_ka1v76": ["basic"],
"ff_n40C_1v76": ["basic"],
"ff_n40C_1v95": ["basic", "ccsnoise"],
"ss_100C_1v40": ["basic"],
Expand All @@ -225,7 +227,7 @@ CELL_LIBRARIES = {
"ff_100C_1v95": ["basic", "leakage"],
"ff_150C_1v95": ["basic"],
"ff_n40C_1v56": ["basic"],
"ff_n40C_1v65_ka1v76": ["basic"],
#"ff_n40C_1v65_ka1v76": ["basic"],
"ff_n40C_1v76": ["basic"],
"ff_n40C_1v95": ["basic", "ccsnoise", "leakage"],
"ss_100C_1v60": ["basic"],
Expand Down
150 changes: 150 additions & 0 deletions dependency_support/com_google_skywater_pdk/cells_info.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Standard cell options for SkyWater 130nm PDK."""

load("@rules_hdl//dependency_support/com_google_skywater_pdk:cell_libraries.bzl", "CELL_LIBRARIES")
load("@rules_hdl//pdk:build_defs.bzl", "StandardCellOptionsInfo", "check_for_each_cells_args", "temp_normalize", "voltage_normalize")

SKY130_OPTIONS = StandardCellOptionsInfo(
libraries = [
"sc_hd",
#"sc_hdll",
#"sc_hs",
#"sc_ms",
#"sc_ls",
#"sc_lp",
#"sc_hvl",
],
vts = [],
corners = list(sorted({
cname.split("_")[0]: None
for libname in CELL_LIBRARIES
for cname in CELL_LIBRARIES[libname]["corners"]
}.keys())),
volts = list(sorted({
voltage_normalize(cname.split("_")[2]): None
for libname in CELL_LIBRARIES
for cname in CELL_LIBRARIES[libname]["corners"]
}.keys())),
temps = list(sorted({
temp_normalize(cname.split("_")[1]): None
for libname in CELL_LIBRARIES
for cname in CELL_LIBRARIES[libname]["corners"]
}.keys())),
)

def sky130_cell_normalize(libname, corner_def):
"""Normalize a corner name.
Args:
libname: Name of the standard cell library (like `sc_hd`).
corner_def: Skywater corner definitions (like `ff_100C_1v65`).
Returns:
The normalize name like `sky130-sc_hd-ff-0v123_m40c`
"""
bits = corner_def.split("_")
corner, temp, voltage = bits[:3]
v_extra = ''
if len(bits) > 3:
v_extra += '_'
if bits[3].startswith('lowhv'):
v_extra += voltage_normalize(bits.pop(3)[6:])+'t'
if len(bits) > 3 and bits[3].startswith('lv'):
v_extra += 't'+voltage_normalize(bits.pop(3)[3:])
if len(bits) > 3:
fail("Found extra bits in corner definition {} (from '{}')".format(bits[3:], corner_def))

temp = temp_normalize(temp)
voltage = voltage_normalize(voltage)

return "sky130-{n}-{c}-{v}_{t}".format(
n = libname,
c = corner,
v = voltage+v_extra,
t = temp,
)

def for_each_sky130_cells(libname, include_vts = None, include_corners = None, include_volts = None, include_temps = None):
"""Generate a list of each standard cell library name.
Args:
libname: Libaray name like 'sc_hd'.
include_vts: Unused for sky130.
include_corners: 'all' or list of corners ('ff', 'tt', 'ss') to include in the output.
include_volts: 'all' or list of voltages (in '0p55v' form) to include in the output.
include_temps: 'all' or list of temperatures (in 'm40c' or '125c' form) to include in the output.
Returns:
A list of tuples containing a unique name for the cell library
(suitable for usage in rule names) and the bazel target for the cell
library.
Example:
```
[
("sky130-sc_hd-ff-0p605_125c", "@com_google_skywater_pdk_sky130_fd_sc_hd//:sky130-sc_hd-ff-0p605_125c"),
("sky130-sc_hd-ff-0p605_m40c", "@com_google_skywater_pdk_sky130_fd_sc_hd//:sky130-sc_hd-ff-0p605_m40c"),
....
]
```
Use this to create bazel rules for every standard cell version like shown below;
```
load("@rules_hdl//dependency_support/com_google_skywater_pdk:build_info.bzl", "for_each_sky130_cells")
[
extract_lef_and_liberty(
name = cell_name + "-data",
standard_cell = cell_target,
)
for cell_name, cell_target in for_each_sky130_cells('sc_hd', include_corners=['25c'])
]
```
"""
kwargs = {
"libname": libname,
"include_vts": include_vts,
"include_corners": include_corners,
"include_volts": include_volts,
"include_temps": include_temps,
}
check_for_each_cells_args(kwargs, SKY130_OPTIONS)

# Iterate over all the options, skipping values not found in the include_XXX arguments.
corners = {}
for corner_def in CELL_LIBRARIES["sky130_fd_" + libname]["corners"]:
corner, temp, voltage = corner_def.split("_", 3)

temp = temp_normalize(temp)

if "_" in voltage:
voltage = voltage.split("_")[0]
voltage = voltage_normalize(voltage)

if corner not in kwargs["include_corners"]:
continue

if voltage not in kwargs["include_volts"]:
continue

if temp not in kwargs["include_temps"]:
continue

cell_name = sky130_cell_normalize(libname, corner_def)
cell_target = "@com_google_skywater_pdk_sky130_fd_{l}//:{c}".format(l = libname, c = cell_name)
corners[cell_name] = cell_target

return list(sorted(corners.items()))
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ def com_google_skywater_pdk():

for library_name in CELL_LIBRARIES:
library = CELL_LIBRARIES[library_name]
if library.get('library_type', None) == 'ip_library':
continue
workspace_name = "com_google_skywater_pdk_" + library_name
maybe(
new_git_repository,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
cell library workspace to set things up."""

load("@rules_hdl//dependency_support/com_google_skywater_pdk:build_defs.bzl", "skywater_cell_library", "skywater_corner")
load("@rules_hdl//dependency_support/com_google_skywater_pdk:cells_info.bzl", "sky130_cell_normalize")
load(":cell_libraries.bzl", "CELL_LIBRARIES")

def declare_cell_library(workspace_name, name):
Expand All @@ -32,13 +33,21 @@ def declare_cell_library(workspace_name, name):
)
library = CELL_LIBRARIES[name]
corners = library.get("corners", {})
all_corners = []
for corner in corners:
target_name = sky130_cell_normalize(name, corner).replace("sky130_fd_", "")
corner_name = "corner-" + target_name
all_corners.append(corner_name)

# boolean values indicating ccsnoise and leakage information in this
# corner.
ccsnoise = "ccsnoise" in corners[corner]
leakage = "leakage" in corners[corner]

# Create the corner configuration
skywater_corner(
name = "{}".format(corner),
name = corner_name,
corner = corner,
visibility = ["//visibility:private"],
srcs = native.glob([
"cells/**/*.lib.json",
Expand All @@ -49,6 +58,37 @@ def declare_cell_library(workspace_name, name):
with_leakage = leakage,
standard_cell_root = "external/{}".format(workspace_name),
)

# Library with only just a single corner.
skywater_cell_library(
name = target_name,
srcs = native.glob(
include = [
"cells/**/*.lef",
"cells/**/*.gds",
],
# There are two types of lefs in the PDK. One for magic a layout
# tool that requires some different properties set in the LEF that
# are not always suitable for the downstream tools like OpenROAD
# and yosys. We're basically just choosing that we want the normal
# lefs instead of the magic ones.
#
# Currently this repo doesn't integrate magic into the flow. At
# some point it will, and we'll need to somehow have both lefs, or
# fix the lefs upstream. Just know that you may at some point in the
# future need to modify this.
exclude = [
"cells/**/*.magic.lef",
],
),
process_corners = [":" + corner_name],
default_corner = corner,
visibility = ["//visibility:public"],
openroad_configuration = library.get("open_road_configuration", None),
tech_lef = "tech/{}.tlef".format(name) if library.get("library_type", None) != "ip_library" else None,
)

# Multi-corner library
skywater_cell_library(
name = name,
srcs = native.glob(
Expand All @@ -70,7 +110,7 @@ def declare_cell_library(workspace_name, name):
"cells/**/*.magic.lef",
],
),
process_corners = [":{}".format(corner) for corner in corners],
process_corners = [":{}".format(corner) for corner in all_corners],
default_corner = library.get("default_corner", ""),
visibility = ["//visibility:public"],
openroad_configuration = library.get("open_road_configuration", None),
Expand Down
Loading

0 comments on commit 08884ef

Please sign in to comment.