diff --git a/flow/Makefile b/flow/Makefile index 759e13578d..525b0e2888 100644 --- a/flow/Makefile +++ b/flow/Makefile @@ -292,6 +292,26 @@ $(RESULTS_DIR)/1_1_yosys_canonicalize.rtlil: $(RESULTS_DIR)/memories.json $(OBJECTS_DIR)/klayout.lyt: $(RESULTS_DIR)/memories.json endif +# OpenROAD stages read binary liberty (.blib) files, written before 1_synth. +# Yosys reads the text libraries. +export BINARY_LIBS_DIR = $(OBJECTS_DIR)/lib +BINARY_LIBS_STAMP = $(BINARY_LIBS_DIR)/binary_libs.stamp +# Generated corner libraries (BLOCKS abstracts) have no make rule. +BINARY_LIBS_CORNER_SOURCES := $(foreach corner,$(CORNERS),$($(shell echo $(corner) | tr a-z A-Z)_LIB_FILES)) +BINARY_LIBS_SOURCES := $(LIB_FILES) $(wildcard $(BINARY_LIBS_CORNER_SOURCES)) + +$(BINARY_LIBS_STAMP): $(BINARY_LIBS_SOURCES) $(SCRIPTS_DIR)/write_binary_libs.tcl $(wildcard $(OPENROAD_EXE)) + $(UNSET_AND_MAKE) do-binary-libs + +.PHONY: do-binary-libs +do-binary-libs: + mkdir -p $(BINARY_LIBS_DIR) $(LOG_DIR) + $(RUN_CMD) --log $(abspath $(LOG_DIR)/write_binary_libs.log) --tee -- $(OPENROAD_CMD) $(SCRIPTS_DIR)/write_binary_libs.tcl + touch $(BINARY_LIBS_STAMP) + +# Order-only here and below, so regenerating the .blib files does not rerun the flow. +$(RESULTS_DIR)/1_synth.odb: | $(BINARY_LIBS_STAMP) + .PHONY: do-yosys do-yosys: yosys-dependencies $(SCRIPTS_DIR)/synth.sh $(SYNTH_SCRIPT) $(LOG_DIR)/1_2_yosys.log @@ -355,6 +375,7 @@ endef define OPEN_GUI .PHONY: open_$(1) gui_$(1) web_$(1) +open_$(1) gui_$(1) web_$(1): | $(BINARY_LIBS_STAMP) open_$(1): $(2)=$(RESULTS_DIR)/$(1) $(OPENROAD_NO_EXIT_CMD) $(SCRIPTS_DIR)/open.tcl gui_$(1): @@ -403,7 +424,7 @@ $(eval $(call OPEN_GUI_SHORTCUT,$(1),$(1).odb)) endif .PHONY: do-$(1) -do-$(1): $(DO_STEP_DEPS_$(1)) $(OBJECTS_DIR)/copyright.txt +do-$(1): $(DO_STEP_DEPS_$(1)) $(OBJECTS_DIR)/copyright.txt | $(BINARY_LIBS_STAMP) $(SCRIPTS_DIR)/flow.sh $(1) $(3) endef @@ -912,7 +933,7 @@ klayout: $(SCRIPTS_DIR)/klayout.sh .phony: run -run: +run: | $(BINARY_LIBS_STAMP) @mkdir -p $(RESULTS_DIR) $(LOG_DIR) $(REPORTS_DIR) $(OBJECTS_DIR) $(RUN_CMD) --log $(abspath $(LOG_DIR)/$(RUN_LOG_NAME_STEM).log) --tee -- $(OPENROAD_CMD) -no_splash $(if $(filter %.py,$(RUN_SCRIPT)),-python) $(RUN_SCRIPT) diff --git a/flow/scripts/read_liberty.tcl b/flow/scripts/read_liberty.tcl index 1c013611dd..60816842ff 100644 --- a/flow/scripts/read_liberty.tcl +++ b/flow/scripts/read_liberty.tcl @@ -5,7 +5,7 @@ if { [env_var_exists_and_non_empty CORNERS] } { foreach corner $::env(CORNERS) { set LIBKEY "[string toupper $corner]_LIB_FILES" foreach libFile $::env($LIBKEY) { - log_cmd read_liberty -corner $corner $libFile + log_cmd read_liberty -corner $corner [lib_file_to_read $libFile] } unset LIBKEY } @@ -13,7 +13,7 @@ if { [env_var_exists_and_non_empty CORNERS] } { } else { ## no corner foreach libFile $::env(LIB_FILES) { - log_cmd read_liberty $libFile + log_cmd read_liberty [lib_file_to_read $libFile] } } diff --git a/flow/scripts/util.tcl b/flow/scripts/util.tcl index 49ab5fd80f..43bb43c20e 100644 --- a/flow/scripts/util.tcl +++ b/flow/scripts/util.tcl @@ -431,3 +431,27 @@ proc source_step_tcl { hook_type step_name } { set env_var "${hook_type}_${step_name}_TCL" source_env_var_if_exists $env_var } + +# Binary liberty (.blib) files written by write_binary_libs.tcl +proc binary_lib_dir { } { + if { [env_var_exists_and_non_empty BINARY_LIBS_DIR] } { + return $::env(BINARY_LIBS_DIR) + } + return [file join $::env(OBJECTS_DIR) lib] +} + +proc binary_lib_path { lib_file } { + set name [file tail $lib_file] + regsub {\.gz$} $name "" name + return [file join [binary_lib_dir] "[file rootname $name].blib"] +} + +# Falls back to the text library when its .blib was not generated +proc lib_file_to_read { lib_file } { + set blib [binary_lib_path $lib_file] + if { [file exists $blib] } { + return $blib + } + utl::warn FLW 25 "$blib not found, reading $lib_file." + return $lib_file +} diff --git a/flow/scripts/write_binary_libs.tcl b/flow/scripts/write_binary_libs.tcl new file mode 100644 index 0000000000..7f5946c11a --- /dev/null +++ b/flow/scripts/write_binary_libs.tcl @@ -0,0 +1,31 @@ +# Write binary liberty (.blib) files for the OpenROAD stages +source $::env(SCRIPTS_DIR)/util.tcl + +set lib_files {} +if { [env_var_exists_and_non_empty CORNERS] } { + foreach corner $::env(CORNERS) { + set LIBKEY "[string toupper $corner]_LIB_FILES" + lappend lib_files {*}$::env($LIBKEY) + } +} else { + lappend lib_files {*}$::env(LIB_FILES) +} + +set blib_dir [binary_lib_dir] +file mkdir $blib_dir + +# .blib files are named after the library, so names must be unique +array set blib_sources {} +foreach lib_file [lsort -unique $lib_files] { + set blib [binary_lib_path $lib_file] + if { [info exists blib_sources($blib)] } { + # The same library spelled differently, e.g. foo.lib and ./foo.lib + if { [file normalize $blib_sources($blib)] eq [file normalize $lib_file] } { + continue + } + error "Liberty files $blib_sources($blib) and $lib_file both map to $blib" + } + set blib_sources($blib) $lib_file + log_cmd write_liberty_binary $lib_file $blib +} +puts "Wrote [array size blib_sources] binary liberty files to $blib_dir" diff --git a/tools/OpenROAD b/tools/OpenROAD index 91e5f5ff2f..0c01bfb0a9 160000 --- a/tools/OpenROAD +++ b/tools/OpenROAD @@ -1 +1 @@ -Subproject commit 91e5f5ff2f198fd130e8915c8ad4408b56987fa4 +Subproject commit 0c01bfb0a95bc08ab1075938d4e6a895d4833f17