Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
26 changes: 26 additions & 0 deletions flow/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,32 @@ $(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 from a cache shared by
# all designs in $(WORK_HOME)/objects/binary_libs, see
# scripts/write_binary_libs.tcl. Yosys reads the text libraries.
.PHONY: binary-libs
binary-libs:
$(UNSET_AND_MAKE) do-binary-libs

.PHONY: do-binary-libs
do-binary-libs:
@mkdir -p $(LOG_DIR)
$(RUN_CMD) --log $(abspath $(LOG_DIR)/write_binary_libs.tmp.log) --tee -- $(OPENROAD_CMD) $(SCRIPTS_DIR)/write_binary_libs.tcl
mv $(LOG_DIR)/write_binary_libs.tmp.log $(LOG_DIR)/write_binary_libs.log

# do-binary-libs renames its log into place only when it succeeds, so a
# failed conversion runs again.
$(LOG_DIR)/write_binary_libs.log: $(LIB_FILES) \
$(foreach corner,$(shell echo $(CORNERS) | tr '[:lower:]' '[:upper:]'),$($(corner)_LIB_FILES))
$(UNSET_AND_MAKE) do-binary-libs

# Order-only, so converting never reruns the flow.
$(RESULTS_DIR)/1_synth.odb: | $(LOG_DIR)/write_binary_libs.log

.PHONY: clean_binary_libs
clean_binary_libs:
rm -rf $(WORK_HOME)/objects/binary_libs

.PHONY: do-yosys
do-yosys: yosys-dependencies
$(SCRIPTS_DIR)/synth.sh $(SYNTH_SCRIPT) $(LOG_DIR)/1_2_yosys.log
Expand Down
4 changes: 2 additions & 2 deletions flow/scripts/read_liberty.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ 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
}
unset corner
} else {
## no corner
foreach libFile $::env(LIB_FILES) {
log_cmd read_liberty $libFile
log_cmd read_liberty [lib_file_to_read $libFile]
}
}

Expand Down
43 changes: 43 additions & 0 deletions flow/scripts/util.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -504,3 +504,46 @@ proc synth_verilog_files { } {
}
return $copies
}

# Entry of lib_file in the binary liberty (.blib) cache shared by all designs:
# objects/binary_libs/<platform>/<library>@<size>-<mtime>-<dirhash>.blib, so a
# changed library gets a new entry and same-named libraries from different
# directories don't collide. Libraries in the design's directory and those the
# flow generates are cached per run.
proc binary_lib_path { lib_file } {
set source [file normalize $lib_file]
set objects [file join $::env(WORK_HOME) objects]
set root [file join $objects binary_libs $::env(PLATFORM)]
set run_dirs [list $::env(DESIGN_DIR) $objects [file join $::env(WORK_HOME) results]]
foreach dir $run_dirs {
if { [string first "[file normalize $dir]/" $source] == 0 } {
set root [file join $::env(OBJECTS_DIR) binary_libs]
break
}
}
set name [file tail $source]
regsub {\.gz$} $name "" name
set name [file rootname $name]
set dir_hash [format %08x [zlib crc32 [file dirname $source] 0]]
return [file join $root "$name@[file size $source]-[file mtime $source]-$dir_hash.blib"]
}

# Whether this OpenROAD reads blib. An entry missing or written by another
# version is expected, so its error is not reported.
proc binary_lib_usable { blib } {
suppress_message STA 1900
suppress_message STA 1902
set usable [expr { ![catch { liberty_binary_info $blib }] }]
unsuppress_message STA 1900
unsuppress_message STA 1902
return $usable
}

# The cached .blib for lib_file, or lib_file when there is no usable .blib
proc lib_file_to_read { lib_file } {
set blib [binary_lib_path $lib_file]
if { [binary_lib_usable $blib] } {
return $blib
}
return $lib_file
}
40 changes: 40 additions & 0 deletions flow/scripts/write_binary_libs.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Fill the binary liberty (.blib) cache with the libraries the OpenROAD stages read
source $::env(SCRIPTS_DIR)/util.tcl

set lib_files {}
if { [env_var_exists_and_non_empty CORNERS] } {
foreach corner $::env(CORNERS) {
lappend lib_files {*}$::env([string toupper $corner]_LIB_FILES)
}
} else {
lappend lib_files {*}$::env(LIB_FILES)
}

set written 0
set cached 0
array set seen {}
foreach lib_file $lib_files {
set blib [binary_lib_path $lib_file]
if { [info exists seen($blib)] } {
continue
}
set seen($blib) 1
if { [binary_lib_usable $blib] } {
incr cached
continue
}
# Publish with a rename, so concurrent flows never read a partial file
set tmp "$blib.tmp.[info hostname].[pid]"
if {
[catch {
file mkdir [file dirname $blib]
log_cmd write_liberty_binary $lib_file $tmp
file rename -force $tmp $blib
} msg]
} {
file delete -force $tmp
error "Could not write $blib: $msg"
}
incr written
}
puts "Binary liberty files: $written written, $cached already cached"
8 changes: 5 additions & 3 deletions flow/util/genReport.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,13 +299,15 @@ def write_summary():
# check if design ran to completion without errors or warnings
d["log_errors"] = list()
d["log_warnings"] = list()
d["last_log"] = ""
d["last_log"] = max(
(name for name in files if name.endswith(".log")),
key=lambda name: os.path.getmtime(os.path.join(log_dir, name)),
default="",
)
for name_ in sorted(files):
temp_e, temp_w = parse_messages(os.path.join(log_dir, name_))
d["log_errors"] += temp_e
d["log_warnings"] += temp_w
if name_.endswith(".log"):
d["last_log"] = name_
d["finished"] = any(name in files for name in LAST_EXPECTED_LOG)

# check if metrics generation had issues
Expand Down
2 changes: 1 addition & 1 deletion tools/OpenROAD
Submodule OpenROAD updated 1019 files