Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/github-actions-cron-util-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ on:
- cron: "0 8 * * SUN"
push:
paths:
- 'flow/util/genElapsedTime.py'
- 'flow/test/test_genElapsedTime.py'
- 'flow/util/*.py'
- 'flow/test/test_*.py'
pull_request:
paths:
- 'flow/util/genElapsedTime.py'
- 'flow/test/test_genElapsedTime.py'
- 'flow/util/*.py'
- 'flow/test/test_*.py'
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

Expand Down
39 changes: 27 additions & 12 deletions flow/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -195,21 +195,25 @@ $(OBJECTS_DIR)/klayout.lyt: $(KLAYOUT_TECH_FILE) $(OBJECTS_DIR)/klayout_tech.lef

.PHONY: do-klayout
do-klayout:
ifeq ($(KLAYOUT_ENV_VAR_IN_PATH),valid)
SC_LEF_RELATIVE_PATH="$(shell realpath --relative-to=$(RESULTS_DIR) $(SC_LEF))"; \
OTHER_LEFS_RELATIVE_PATHS=$$(echo "$(foreach file, $(OBJECTS_DIR)/klayout_tech.lef $(ADDITIONAL_LEFS),<lef-files>$$(realpath --relative-to=$(RESULTS_DIR) $(file))</lef-files>)"); \
sed 's,<lef-files>.*</lef-files>,<lef-files>'"$$SC_LEF_RELATIVE_PATH"'</lef-files>'"$$OTHER_LEFS_RELATIVE_PATHS"',g' $(KLAYOUT_TECH_FILE) > $(OBJECTS_DIR)/klayout.lyt
else
sed 's,<lef-files>.*</lef-files>,$(foreach file, $(OBJECTS_DIR)/klayout_tech.lef $(SC_LEF) $(ADDITIONAL_LEFS),<lef-files>$(shell realpath --relative-to=$(RESULTS_DIR) $(file))</lef-files>),g' $(KLAYOUT_TECH_FILE) > $(OBJECTS_DIR)/klayout.lyt
endif
sed -i 's,<map-file>.*</map-file>,$(foreach file, $(FLOW_HOME)/platforms/$(PLATFORM)/*map,<map-file>$(shell realpath $(file))</map-file>),g' $(OBJECTS_DIR)/klayout.lyt
@mkdir -p $(dir $(OBJECTS_DIR)/klayout.lyt)
$(PYTHON_EXE) $(UTILS_DIR)/generate_klayout_tech.py \
--template $(KLAYOUT_TECH_FILE) \
--output $(OBJECTS_DIR)/klayout.lyt \
--lef-files $(OBJECTS_DIR)/klayout_tech.lef $(SC_LEF) $(ADDITIONAL_LEFS) \
--reference-dir $(RESULTS_DIR) \
--map-files $(wildcard $(FLOW_HOME)/platforms/$(PLATFORM)/*map)

$(OBJECTS_DIR)/klayout_wrap.lyt: $(KLAYOUT_TECH_FILE) $(OBJECTS_DIR)/klayout_tech.lef
$(UNSET_AND_MAKE) do-klayout_wrap

.PHONY: do-klayout_wrap
do-klayout_wrap:
sed 's,<lef-files>.*</lef-files>,$(foreach file, $(OBJECTS_DIR)/klayout_tech.lef $(WRAP_LEFS),<lef-files>$(shell realpath --relative-to=$(OBJECTS_DIR)/def $(file))</lef-files>),g' $(KLAYOUT_TECH_FILE) > $(OBJECTS_DIR)/klayout_wrap.lyt
@mkdir -p $(dir $(OBJECTS_DIR)/klayout_wrap.lyt)
$(PYTHON_EXE) $(UTILS_DIR)/generate_klayout_tech.py \
--template $(KLAYOUT_TECH_FILE) \
--output $(OBJECTS_DIR)/klayout_wrap.lyt \
--lef-files $(OBJECTS_DIR)/klayout_tech.lef $(WRAP_LEFS) \
--reference-dir $(OBJECTS_DIR)/def

$(WRAPPED_LEFS):
mkdir -p $(OBJECTS_DIR)/lef $(OBJECTS_DIR)/def
Expand Down Expand Up @@ -627,7 +631,7 @@ final: finish

.PHONY: do-finish
do-finish:
$(UNSET_AND_MAKE) do-6_1_fill do-6_1_fill.sdc do-6_final.sdc do-6_report do-gds elapsed
$(UNSET_AND_MAKE) do-6_1_fill do-6_1_fill.sdc do-6_final.sdc do-6_report elapsed

.PHONY: generate_abstract
generate_abstract: $(RESULTS_DIR)/6_final.gds $(RESULTS_DIR)/6_final.def $(RESULTS_DIR)/6_final.v $(RESULTS_DIR)/6_final.sdc
Expand All @@ -643,6 +647,17 @@ do-generate_abstract:
clean_abstract:
rm -f $(RESULTS_DIR)/$(DESIGN_NAME).lib $(RESULTS_DIR)/$(DESIGN_NAME).lef

.PHONY: check-klayout
check-klayout:
@if [ -z "$(KLAYOUT_CMD)" ]; then \
echo "Error: KLayout not found. Install KLayout or set KLAYOUT_CMD."; \
echo "Hint: KLayout is needed for GDS/DRC/LVS targets."; \
exit 1; \
fi

.PHONY: gds
gds: $(GDS_FINAL_FILE)

# Merge wrapped macros using Klayout
#-------------------------------------------------------------------------------
$(WRAPPED_GDSOAS): $(OBJECTS_DIR)/klayout_wrap.lyt $(WRAPPED_LEFS)
Expand All @@ -658,7 +673,7 @@ $(WRAPPED_GDSOAS): $(OBJECTS_DIR)/klayout_wrap.lyt $(WRAPPED_LEFS)

# Merge GDS using Klayout
#-------------------------------------------------------------------------------
$(GDS_MERGED_FILE): $(RESULTS_DIR)/6_final.def $(OBJECTS_DIR)/klayout.lyt $(GDSOAS_FILES) $(WRAPPED_GDSOAS) $(SEAL_GDSOAS)
$(GDS_MERGED_FILE): check-klayout $(RESULTS_DIR)/6_final.def $(OBJECTS_DIR)/klayout.lyt $(GDSOAS_FILES) $(WRAPPED_GDSOAS) $(SEAL_GDSOAS)
$(UNSET_AND_MAKE) do-gds-merged

.PHONY: do-gds-merged
Expand Down Expand Up @@ -768,7 +783,7 @@ nuke: clean_test clean_issues
# DEF/GDS/OAS viewer shortcuts
#-------------------------------------------------------------------------------
.PHONY: $(foreach file,$(RESULTS_DEF) $(RESULTS_GDS) $(RESULTS_OAS),klayout_$(file))
$(foreach file,$(RESULTS_DEF) $(RESULTS_GDS) $(RESULTS_OAS),klayout_$(file)): klayout_%: $(OBJECTS_DIR)/klayout.lyt
$(foreach file,$(RESULTS_DEF) $(RESULTS_GDS) $(RESULTS_OAS),klayout_$(file)): klayout_%: check-klayout $(OBJECTS_DIR)/klayout.lyt
$(SCRIPTS_DIR)/klayout.sh -nn $(OBJECTS_DIR)/klayout.lyt $(RESULTS_DIR)/$*

$(eval $(call OPEN_GUI_SHORTCUT,synth,1_synth.odb))
Expand Down
74 changes: 74 additions & 0 deletions flow/docs/KLayoutOptionalDependency.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# KLayout as an Optional Dependency

KLayout is only required for GDS/OAS stream generation, DRC, and LVS
verification. All other ORFS functionality — synthesis, floorplanning,
placement, CTS, routing, timing reports, and abstract generation — works
without KLayout installed.

## Makefile Targets

| Target | Requires KLayout | Description |
|---|---|---|
| `make finish` | Yes | Complete flow including GDS generation |
| `make gds` | Yes | Generate GDS/OAS from finished design |
| `make drc` | Yes | Run DRC checks (requires GDS) |
| `make lvs` | Yes | Run LVS checks (requires GDS) |
| `make gallery` | Yes | Generate layout screenshots |
| `make klayout_<file>` | Yes | Open result in KLayout viewer |
| `make generate_abstract` | No | Generate LEF/LIB abstracts |

A `check-klayout` guard produces a clear error message when KLayout is
missing and a KLayout-dependent target is invoked:

```
Error: KLayout not found. Install KLayout or set KLAYOUT_CMD.
Hint: KLayout is needed for GDS/DRC/LVS targets.
```

## bazel-orfs Integration

bazel-orfs uses the `do-` prefixed targets which bypass Make's dependency
management. The relevant targets follow the standard pattern:

- `do-finish` / `do-final` — runs the finish stage without GDS
Comment thread
maliberty marked this conversation as resolved.
Outdated
- `do-gds` — runs GDS generation (requires KLayout)

An `orfs_gds()` Bazel rule can call `do-gds` independently from
`orfs_flow()`, making KLayout an optional toolchain dependency configured
in `MODULE.bazel`.

## KLayout Tech File Generation

The `do-klayout` and `do-klayout_wrap` targets generate `.lyt` technology
files by substituting LEF and map file paths into platform templates.
This is implemented in `util/generate_klayout_tech.py` using stdlib XML
processing — no KLayout dependency required.

## Testing Without KLayout

Unit tests for all KLayout-related Python scripts use `unittest.mock` to
mock the `pya` API:

```
cd flow/test
python -m unittest test_generate_klayout_tech test_def2stream test_convertDrc
```

These tests cover:
- `.lyt` tech file generation (`test_generate_klayout_tech.py`)
- DEF-to-GDS merging logic (`test_def2stream.py`)
- DRC report conversion (`test_convertDrc.py`)

## Future: OpenROAD `write_gds` and KLayout Coexistence

OpenROAD has an unfinished `write_gds` command. When it is eventually
completed, it would eliminate the KLayout dependency for GDS generation
in many cases. However, KLayout support will live alongside `write_gds`
until there is confidence that `write_gds` is robust and fully covers
all current use cases.

Even then, non-public or future PDKs may have requirements that benefit
from KLayout's mature GDS handling. Whether KLayout support stays in
ORFS indefinitely remains to be seen. Once `write_gds` works robustly
for all of today's use cases, extending it to cover future ones may
turn out to be straightforward.
Comment thread
oharboe marked this conversation as resolved.
Outdated
Loading