blob: edb795be44225d2f3f33d29b40d4d75a2a8da7b4 [file] [log] [blame] [edit]
OPENLANE_TAG ?= 2022.02.23_02.50.41
OPENLANE_IMAGE_NAME ?= efabless/openlane:$(OPENLANE_TAG)
export PDK ?= sky130A
blocks = $(shell cd $(CARAVEL_ROOT)/openlane && find * -maxdepth 0 -type d)
blocks := $(subst user_project_wrapper,,$(blocks))
ifneq ($(MCW_ROOT),$(CARAVEL_ROOT))
blocks += $(shell cd $(MCW_ROOT)/openlane && find * -maxdepth 0 -type d)
endif
ifneq ($(CUP_ROOT),$(CARAVEL_ROOT))
blocks += $(shell cd $(CUP_ROOT)/openlane && find * -maxdepth 0 -type d)
endif
# we don't have user_id_programming.def)
# mgmt_protect_hvl use hvl library which we don't handle yet
blocks := $(subst mgmt_protect_hvl,,$(blocks))
blocks := $(subst chip_io_alt,,$(blocks))
blocks := $(subst user_id_programming,,$(blocks))
rcx-blocks = $(blocks:%=rcx-%)
rcx-blocks-all = $(blocks:%=rcx-%-all)
rcx-blocks-nom = $(blocks:%=rcx-%-nom)
rcx-blocks-max = $(blocks:%=rcx-%-max)
rcx-blocks-min = $(blocks:%=rcx-%-min)
$(TIMING_ROOT)/tmp $(TIMING_ROOT)/logs:
mkdir -p $@
.PHONY: list-rcx
list-rcx:
@echo $(rcx-blocks-all)
.PHONY: list-rcx-nom
list-rcx-nom:
@echo $(rcx-blocks-nom)
.PHONY: list-sta
list-sta:
@echo $(sta-blocks)
.PHONY: rcx-all
rcx-all: $(rcx-blocks-all)
define docker_run_base
docker run \
--rm \
-e BLOCK=$1 \
-e CORNER_ENV_FILE=$(CORNER_ENV_FILE) \
-e SPEF_CORNER=$(SPEF_CORNER) \
-e MCW_ROOT=$(MCW_ROOT) \
-e CUP_ROOT=$(CUP_ROOT) \
-e TIMING_ROOT=$(TIMING_ROOT) \
-e CARAVEL_ROOT=$(CARAVEL_ROOT) \
-e PDK_REF_PATH=$(PDK_ROOT)/$(PDK)/libs.ref/ \
-e PDK_TECH_PATH=$(PDK_ROOT)/$(PDK)/libs.tech/ \
-v $(PDK_ROOT):$(PDK_ROOT) \
-v $(CUP_ROOT):$(CUP_ROOT) \
-v $(MCW_ROOT):$(MCW_ROOT) \
-v $(TIMING_ROOT):$(TIMING_ROOT) \
-v $(CARAVEL_ROOT):$(CARAVEL_ROOT) \
-u $(shell id -u $(USER)):$(shell id -g $(USER)) \
$(OPENLANE_IMAGE_NAME)
endef
sta-blocks = $(blocks:%=sta-%)
define docker_run_sta
$(call docker_run_base,$1) \
bash -c "set -eo pipefail && sta -exit $(TIMING_ROOT)/scripts/openroad/sta.tcl \
|& tee $(TIMING_ROOT)/logs/$*-sta.log"
@echo "logged to $(TIMING_ROOT)/logs/$*-sta.log"
endef
.PHONY: $(sta-blocks)
$(sta-blocks): export CORNER_ENV_FILE = $(TIMING_ROOT)/env/tt.tcl
$(sta-blocks): export SPEF_CORNER = nom
$(sta-blocks): sta-%:
$(call docker_run_sta,$*)
define docker_run_rcx
$(call docker_run_base,$1) \
bash -c "set -eo pipefail && openroad -exit $(TIMING_ROOT)/scripts/openroad/rcx.tcl \
|& tee $(TIMING_ROOT)/logs/$*-rcx-$(SPEF_CORNER).log"
@echo "logged to $(TIMING_ROOT)/logs/$*-rcx-$(SPEF_CORNER).log"
endef
.PHONY: $(rcx-blocks-all)
$(rcx-blocks-all): rcx-%-all: $(rcx-requirements) rcx-%-nom rcx-%-max rcx-%-min
.PHONY: $(rcx-blocks-nom)
$(rcx-blocks-nom): export SPEF_CORNER = nom
$(rcx-blocks-nom): export CORNER_ENV_FILE = $(TIMING_ROOT)/env/tt.tcl
$(rcx-blocks-nom): rcx-%-nom:
$(call docker_run_rcx,$*)
.PHONY: $(rcx-blocks-max)
$(rcx-blocks-max): export SPEF_CORNER = max
$(rcx-blocks-max): export CORNER_ENV_FILE = $(TIMING_ROOT)/env/tt.tcl
$(rcx-blocks-max): rcx-%-max:
$(call docker_run_rcx,$*)
.PHONY: $(rcx-blocks-min)
$(rcx-blocks-min): export SPEF_CORNER = min
$(rcx-blocks-min): export CORNER_ENV_FILE = $(TIMING_ROOT)/env/tt.tcl
$(rcx-blocks-min): rcx-%-min:
$(call docker_run_rcx,$*)
define docker_run_caravel_timing
$(call docker_run_base,caravel) \
bash -c "set -eo pipefail && sta -no_splash -exit $(TIMING_ROOT)/scripts/openroad/timing_top.tcl |& tee \
$(TIMING_ROOT)/logs/caravel-timing-$$(basename $(CORNER_ENV_FILE))-$(SPEF_CORNER).log"
@echo "logged to $(TIMING_ROOT)/logs/caravel-timing-$$(basename $(CORNER_ENV_FILE))-$(SPEF_CORNER).log"
endef
custom-blocks = $(blocks:%=custom-%)
define docker_run_custom
$(call docker_run_base,$1) \
bash -c "set -eo pipefail && sta -exit $(TIMING_ROOT)/scripts/openroad/custom.tcl \
|& tee $(TIMING_ROOT)/logs/$*-custom.log"
@echo "logged to $(TIMING_ROOT)/logs/$*-custom.log"
endef
.PHONY: list-custom
list-custom:
# $(custom-blocks)
.PHONY: $(custom-blocks)
$(custom-blocks): export SPEF_CORNER = nom
$(custom-blocks): export CORNER_ENV_FILE = $(TIMING_ROOT)/env/tt.tcl
$(custom-blocks): custom-%:
$(call docker_run_custom,$*)
caravel-timing-typ-targets = caravel-timing-typ-nom
caravel-timing-typ-targets += caravel-timing-typ-min
caravel-timing-typ-targets += caravel-timing-typ-max
caravel-timing-slow-targets = caravel-timing-slow-nom
caravel-timing-slow-targets += caravel-timing-slow-min
caravel-timing-slow-targets += caravel-timing-slow-max
caravel-timing-fast-targets = caravel-timing-fast-nom
caravel-timing-fast-targets += caravel-timing-fast-min
caravel-timing-fast-targets += caravel-timing-fast-max
caravel-timing-targets = $(caravel-timing-slow-targets)
caravel-timing-targets += $(caravel-timing-fast-targets)
caravel-timing-targets += $(caravel-timing-typ-targets)
.PHONY: caravel-timing-typ
$(caravel-timing-typ-targets): export CORNER_ENV_FILE = $(TIMING_ROOT)/env/tt.tcl
caravel-timing-typ: caravel-timing-typ-nom caravel-timing-typ-min caravel-timing-typ-max
.PHONY: caravel-timing-typ-nom
caravel-timing-typ-nom: export SPEF_CORNER = nom
.PHONY: caravel-timing-typ-min
caravel-timing-typ-min: export SPEF_CORNER = min
.PHONY: caravel-timing-typ-max
caravel-timing-typ-max: export SPEF_CORNER = max
.PHONY: caravel-timing-typ-max
.PHONY: caravel-timing-slow
$(caravel-timing-slow-targets): export CORNER_ENV_FILE = $(TIMING_ROOT)/env/ss.tcl
caravel-timing-slow: caravel-timing-slow-nom caravel-timing-slow-min caravel-timing-slow-max
.PHONY: caravel-timing-slow-nom
caravel-timing-slow-nom: export SPEF_CORNER = nom
.PHONY: caravel-timing-slow-min
caravel-timing-slow-min: export SPEF_CORNER = min
.PHONY: caravel-timing-slow-max
caravel-timing-slow-max: export SPEF_CORNER = max
.PHONY: caravel-timing-fast
$(caravel-timing-fast-targets): export CORNER_ENV_FILE = $(TIMING_ROOT)/env/ff.tcl
caravel-timing-fast: caravel-timing-fast-nom caravel-timing-fast-min caravel-timing-fast-max
.PHONY: caravel-timing-fast-nom
caravel-timing-fast-nom: export SPEF_CORNER = nom
.PHONY: caravel-timing-fast-min
caravel-timing-fast-min: export SPEF_CORNER = min
.PHONY: caravel-timing-fast-max
caravel-timing-fast-max: export SPEF_CORNER = max
$(caravel-timing-targets): $(TIMING_ROOT)/logs
$(call docker_run_caravel_timing)
# some useful dev double checking
#
rcx-requirements = $(CARAVEL_ROOT)/def/%.def
rcx-requirements += $(CARAVEL_ROOT)/lef/%.lef
rcx-requirements += $(CARAVEL_ROOT)/sdc/%.sdc
rcx-requirements += $(CARAVEL_ROOT)/verilog/gl/%.v
exceptions = $(MCW_ROOT)/lef/caravel.lef
exceptions += $(MCW_ROOT)/lef/caravan.lef
# lets ignore these for now
exceptions += $(MCW_ROOT)/sdc/user_analog_project_wrapper.sdc
exceptions += $(MCW_ROOT)/sdc/user_project_wrapper.sdc
exceptions += $(MCW_ROOT)/verilog/gl/user_analog_project_wrapper.v
exceptions += $(MCW_ROOT)/verilog/gl/user_project_wrapper.v
$(exceptions):
$(warning we don't need lefs for $@ but take note anyway)
$(CARAVEL_ROOT)/def/%.def: $(MCW_ROOT)/def/%.def ;
$(MCW_ROOT)/def/%.def: $(CUP_ROOT)/def/%.def ;
$(CUP_ROOT)/def/%.def:
$(error error if you are here it probably means that $@.def is missing from mcw and caravel)
$(CARAVEL_ROOT)/lef/%.lef: $(MCW_ROOT)/lef/%.lef ;
$(MCW_ROOT)/lef/%.lef: $(CUP_ROOT)/lef/%.lef ;
$(CUP_ROOT)/lef/%.lef:
$(error error if you are here it probably means that $@.lef is missing from mcw and caravel)
$(CARAVEL_ROOT)/sdc/%.sdc: $(MCW_ROOT)/sdc/%.sdc ;
$(MCW_ROOT)/sdc/%.sdc: $(CUP_ROOT)/sdc/%.sdc ;
$(CUP_ROOT)/sdc/%.sdc:
$(error error if you are here it probably means that $@.sdc is missing from mcw and caravel)
$(CARAVEL_ROOT)/verilog/gl/%.v: $(MCW_ROOT)/verilog/gl/%.v ;
$(MCW_ROOT)/verilog/gl/%.v: $(CUP_ROOT)/verilog/gl/%.v ;
$(CUP_ROOT)/verilog/gl/%.v:
$(error error if you are here it probably means that gl/$@.v is missing from mcw and caravel)
check_defined = \
$(strip $(foreach 1,$1, \
$(call __check_defined,$1,$(strip $(value 2)))))
__check_defined = \
$(if $(value $1),, \
$(error Undefined $1$(if $2, ($2))))
$(call check_defined, \
MCW_ROOT \
CUP_ROOT \
PDK_ROOT \
CARAVEL_ROOT \
)