blob: 148b384ecef65d28a25333522702adb65578a7dd [file] [log] [blame]
OPENLANE_TAG ?= 2022.02.23_02.50.41
OPENLANE_IMAGE_NAME ?= efabless/openlane:$(OPENLANE_TAG)
export PDK ?= sky130A
export RCX_CORNER ?= nom
export LIB_CORNER ?= t
export ALLOW_MISSING_SPEF ?= 1
export PDK_REF_PATH = $(PDK_ROOT)/$(PDK)/libs.ref/
export PDK_TECH_PATH = $(PDK_ROOT)/$(PDK)/libs.tech/
export PROJECT_ROOT ?= $(CARAVEL_ROOT)
logs-dir = $(PROJECT_ROOT)/logs
logs = $(logs-dir)/rcx $(logs-dir)/sdf $(logs-dir)/top $(logs-dir)/sta
$(logs):
mkdir -p $@
SPEF_OVERWRITE ?= ""
define docker_run_base
docker run \
--rm \
-e PROJECT_ROOT=$(PROJECT_ROOT) \
-e BLOCK=$1 \
-e PDK=$(PDK) \
-e LIB_CORNER=$(LIB_CORNER) \
-e RCX_CORNER=$(RCX_CORNER) \
-e MCW_ROOT=$(MCW_ROOT) \
-e SPEF_OVERWRITE=$(SPEF_OVERWRITE) \
-e CUP_ROOT=$(CUP_ROOT) \
-e CARAVEL_ROOT=$(CARAVEL_ROOT) \
-e TIMING_ROOT=$(TIMING_ROOT) \
-e PDK_REF_PATH=$(PDK_ROOT)/$(PDK)/libs.ref/ \
-e PDK_TECH_PATH=$(PDK_ROOT)/$(PDK)/libs.tech/ \
-e ALLOW_MISSING_SPEF=$(ALLOW_MISSING_SPEF) \
-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) \
-v $(HOME):$(HOME) \
-u $(shell id -u $(USER)):$(shell id -g $(USER)) \
$(OPENLANE_IMAGE_NAME)
endef
define docker_run_sta
$(call docker_run_base,$1) \
bash -c "set -eo pipefail && sta -exit $(TIMING_ROOT)/scripts/openroad/sta-$*.tcl \
|& tee $(logs-dir)/sta/$*-$(RCX_CORNER)-$(LIB_CORNER).log"
@echo "logged to $(logs-dir)/sta/$*-$(RCX_CORNER)-$(LIB_CORNER).log"
endef
define docker_run_sdf
$(call docker_run_base,$1) \
bash -c "set -eo pipefail && openroad -exit $(TIMING_ROOT)/scripts/openroad/sdf.tcl \
|& tee $(logs-dir)/sdf/$*-$(RCX_CORNER)-$(LIB_CORNER).log"
@echo "logged to $(logs-dir)/sdf/$*-$(RCX_CORNER)-$(LIB_CORNER).log"
endef
define docker_run_rcx
$(call docker_run_base,$1) \
bash -c "set -eo pipefail && openroad -exit $(TIMING_ROOT)/scripts/openroad/rcx.tcl \
|& tee $(logs-dir)/rcx/$*-$(RCX_CORNER)-$(LIB_CORNER).log"
@echo "logged to $(logs-dir)/rcx/$*-$(RCX_CORNER)-$(LIB_CORNER).log"
endef
blocks = $(shell cd $(CARAVEL_ROOT)/openlane && find * -maxdepth 0 -type d)
blocks := $(subst user_project_wrapper,,$(blocks))
ifneq ($(CARAVEL_ROOT),$(MCW_ROOT))
blocks += $(shell cd $(MCW_ROOT)/openlane && find * -maxdepth 0 -type d)
endif
ifneq ($(CARAVEL_ROOT),$(CUP_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))
blocks := $(subst user_analog_project_wrapper,,$(blocks))
blocks := $(subst caravan,,$(blocks))
defs = $(shell cd $(CARAVEL_ROOT)/def && find *.def -maxdepth 0 -type f ! -name 'user_project_wrapper.def')
ifneq ($(CARAVEL_ROOT),$(MCW_ROOT))
defs += $(shell cd $(MCW_ROOT)/def && find *.def -maxdepth 0 -type f)
endif
ifneq ($(CARAVEL_ROOT),$(CUP_ROOT))
defs += $(shell cd $(CUP_ROOT)/def && find *.def -maxdepth 0 -type f)
endif
rcx-blocks = $(defs:%.def=rcx-%)
rcx-blocks-nom = $(blocks:%=rcx-%-nom)
rcx-blocks-max = $(blocks:%=rcx-%-max)
rcx-blocks-min = $(blocks:%=rcx-%-min)
rcx-blocks-t = $(blocks:%=rcx-%-t)
rcx-blocks-f = $(blocks:%=rcx-%-f)
rcx-blocks-s = $(blocks:%=rcx-%-s)
sdf-blocks = $(blocks:%=sdf-%)
sdf-blocks-t = $(blocks:%=sdf-%-t)
sdf-blocks-f = $(blocks:%=sdf-%-f)
sdf-blocks-s = $(blocks:%=sdf-%-s)
sdf-blocks-nom = $(blocks:%=sdf-%-nom)
sdf-blocks-min = $(blocks:%=sdf-%-min)
sdf-blocks-max = $(blocks:%=sdf-%-max)
$(sdf-blocks): sdf-%:
$(MAKE) -f timing.mk sdf-$*-nom
$(MAKE) -f timing.mk sdf-$*-min
$(MAKE) -f timing.mk sdf-$*-max
$(sdf-blocks-nom): export RCX_CORNER = nom
$(sdf-blocks-min): export RCX_CORNER = min
$(sdf-blocks-max): export RCX_CORNER = max
$(sdf-blocks-nom): sdf-%-nom: sdf-%-t sdf-%-f sdf-%-s
$(sdf-blocks-min): sdf-%-min: sdf-%-t sdf-%-f sdf-%-s
$(sdf-blocks-max): sdf-%-max: sdf-%-t sdf-%-f sdf-%-s
$(sdf-blocks-t): export LIB_CORNER = t
$(sdf-blocks-s): export LIB_CORNER = s
$(sdf-blocks-f): export LIB_CORNER = f
$(sdf-blocks-t): sdf-%-t:
$(call docker_run_sdf,$*)
$(sdf-blocks-s): sdf-%-s:
$(call docker_run_sdf,$*)
$(sdf-blocks-f): sdf-%-f:
$(call docker_run_sdf,$*)
sta-blocks = $(blocks:%=sta-%)
sta-blocks-t = $(blocks:%=sta-%-t)
sta-blocks-f = $(blocks:%=sta-%-f)
sta-blocks-s = $(blocks:%=sta-%-s)
sta-blocks-nom = $(blocks:%=sta-%-nom)
sta-blocks-min = $(blocks:%=sta-%-min)
sta-blocks-max = $(blocks:%=sta-%-max)
$(sta-blocks): sta-%:
$(MAKE) -f timing.mk sta-$*-nom
$(MAKE) -f timing.mk sta-$*-min
$(MAKE) -f timing.mk sta-$*-max
$(sta-blocks-nom): export RCX_CORNER = nom
$(sta-blocks-min): export RCX_CORNER = min
$(sta-blocks-max): export RCX_CORNER = max
$(sta-blocks-nom): sta-%-nom: sta-%-t sta-%-f sta-%-s
$(sta-blocks-min): sta-%-min: sta-%-t sta-%-f sta-%-s
$(sta-blocks-max): sta-%-max: sta-%-t sta-%-f sta-%-s
$(sta-blocks-t): export LIB_CORNER = t
$(sta-blocks-s): export LIB_CORNER = s
$(sta-blocks-f): export LIB_CORNER = f
$(sta-blocks-t): sta-%-t: $(logs-dir)/sta
$(call docker_run_sta,$*)
$(sta-blocks-s): sta-%-s:
$(call docker_run_sta,$*)
$(sta-blocks-f): sta-%-f:
$(call docker_run_sta,$*)
$(rcx-blocks): rcx-%: $(rcx-requirements)
$(MAKE) -f timing.mk rcx-$*-nom &
$(MAKE) -f timing.mk rcx-$*-min &
$(MAKE) -f timing.mk rcx-$*-max
$(rcx-blocks-nom): export RCX_CORNER = nom
$(rcx-blocks-min): export RCX_CORNER = min
$(rcx-blocks-max): export RCX_CORNER = max
$(rcx-blocks-nom): rcx-%-nom: rcx-%-t
$(rcx-blocks-min): rcx-%-min: rcx-%-t
$(rcx-blocks-max): rcx-%-max: rcx-%-t
$(rcx-blocks-t): export LIB_CORNER = t
$(rcx-blocks-s): export LIB_CORNER = s
$(rcx-blocks-f): export LIB_CORNER = f
$(rcx-blocks-t): rcx-%-t: $(logs-dir)/rcx
$(call docker_run_rcx,$*)
$(rcx-blocks-s): rcx-%-s:
$(call docker_run_rcx,$*)
$(rcx-blocks-f): rcx-%-f:
$(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 \
$(logs-dir)/top/caravel-timing-$$(basename $(LIB_CORNER))-$(RCX_CORNER).log"
@echo "logged to $(logs-dir)/top/caravel-timing-$$(basename $(LIB_CORNER))-$(RCX_CORNER).log"
endef
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 LIB_CORNER = t
caravel-timing-typ: caravel-timing-typ-nom caravel-timing-typ-min caravel-timing-typ-max
.PHONY: caravel-timing-typ-nom
.PHONY: caravel-timing-typ-min
.PHONY: caravel-timing-typ-max
caravel-timing-typ-nom: export RCX_CORNER = nom
caravel-timing-typ-min: export RCX_CORNER = min
caravel-timing-typ-max: export RCX_CORNER = max
.PHONY: caravel-timing-slow
$(caravel-timing-slow-targets): export LIB_CORNER = s
caravel-timing-slow: caravel-timing-slow-nom caravel-timing-slow-min caravel-timing-slow-max
.PHONY: caravel-timing-slow-nom
.PHONY: caravel-timing-slow-min
.PHONY: caravel-timing-slow-max
caravel-timing-slow-nom: export RCX_CORNER = nom
caravel-timing-slow-min: export RCX_CORNER = min
caravel-timing-slow-max: export RCX_CORNER = max
.PHONY: caravel-timing-fast
$(caravel-timing-fast-targets): export LIB_CORNER = f
caravel-timing-fast: caravel-timing-fast-nom caravel-timing-fast-min caravel-timing-fast-max
.PHONY: caravel-timing-fast-nom
.PHONY: caravel-timing-fast-min
.PHONY: caravel-timing-fast-max
caravel-timing-fast-nom: export RCX_CORNER = nom
caravel-timing-fast-min: export RCX_CORNER = min
caravel-timing-fast-max: export RCX_CORNER = max
$(caravel-timing-targets): $(logs-dir)/top
$(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
.PHONY: list-rcx
.PHONY: list-sdf
.PHONY: rcx-all
list-rcx:
@blocks="$(rcx-blocks)";\
for block in $${blocks}; do echo "$$block"; done
list-sdf:
@echo $(sdf-blocks)
list-sta:
@echo $(sta-blocks)
rcx-all: $(rcx-blocks)
$(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 mising 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 mising 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 mising 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 mising 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 \
TIMING_ROOT \
)