From 5b960fbac1e5c5a71f358f9ef886d6363cb89bbc Mon Sep 17 00:00:00 2001 From: Mike Inouye Date: Mon, 10 Mar 2025 22:51:58 +0000 Subject: [PATCH] Synthesis flow cleanup and improvements. Signed-off-by: Mike Inouye --- place_and_route/private/benchmark.bzl | 12 ++--- synthesis/synth.tcl | 64 +++++++++++++++------------ 2 files changed, 43 insertions(+), 33 deletions(-) diff --git a/place_and_route/private/benchmark.bzl b/place_and_route/private/benchmark.bzl index 958468b4..b2fea03e 100644 --- a/place_and_route/private/benchmark.bzl +++ b/place_and_route/private/benchmark.bzl @@ -34,14 +34,16 @@ def benchmark(ctx, open_road_info): open_road_commands = [ est_parasitic_cmd, + "report_units", + "report_design_area", + "report_cell_usage", + "report_wns -digits 3", + "report_tns -digits 3", + "report_timing_histogram -num_bins 25", "set_power_activity -input -activity {} -duty 0.5".format(ctx.attr.power_switching_activity), - "report_power", - "report_wns", - "report_tns", + "report_power -digits 3", "report_checks -path_delay min_max -format full_clock_expanded -fields {input_pin slew capacitance} -digits 3", "report_check_types -max_slew -max_capacitance -max_fanout -violators", - "report_design_area", - "report_cell_usage", "report_clock_min_period", "report_clock_properties", ] diff --git a/synthesis/synth.tcl b/synthesis/synth.tcl index 54463121..f21f95bf 100644 --- a/synthesis/synth.tcl +++ b/synthesis/synth.tcl @@ -15,14 +15,18 @@ yosys -import set all_liberties [split $::env(ADDITIONAL_LIBERTIES) ","] lappend all_liberties $::env(LIBERTY) -# create liberty blackbox so cells can be manually created. +set all_lib_cmd "-liberty " +append all_lib_cmd [join $all_liberties " -liberty "] + +# Use Yosys to generate stdcell blackboxes and re-read them. +# This enables parsing of macros and hand-placed stdcells. foreach lib $all_liberties { read_liberty -lib -overwrite $lib } write_verilog -blackboxes $::env(STANDARD_CELL_BLACK_BOX) -# read design +# Read design. set srcs_flist_path $::env(FLIST) set srcs_flist_file [open $srcs_flist_path "r"] set srcs_flist_data [read $srcs_flist_file] @@ -40,7 +44,7 @@ foreach src $srcs { } } -# read UHDM designs +# Read UHDM designs. set srcs_uhdm_flist_path $::env(UHDM_FLIST) set srcs_uhdm_flist_file [open $srcs_uhdm_flist_path "r"] set srcs_uhdm_flist_data [read $srcs_uhdm_flist_file] @@ -53,16 +57,15 @@ foreach src $srcs { read_uhdm $src } -# generic synthesis +# Generic synthesis. set top $::env(TOP) hierarchy -check -top $top -# Move proc_mux at the end of `yosys proc` to avoid inferred latches. -# See https://github.com/YosysHQ/yosys/issues/3456 -# Ideally the bug would be solved in UHDM/Yosys. -yosys proc -nomux -yosys proc_mux +yosys proc yosys flatten +# Print arithm stats +yosys arith_stats + # Remove $print cells. These cells represent Verilog $display() tasks. # Some place and route tools cannot handle these in the output Verilog, # so remove them here. @@ -92,45 +95,49 @@ if {[info exists ::env(ADDER_MAPPING)] && [file isfile $::env(ADDER_MAPPING)]} { opt -fast -purge } -# mapping to liberty +# Map $DFF cells. Although dfflibmap now supports multiple liberty files, +# we intentionally only use pass the main liberty file here for runtime. +# Yosysand abc do not have ability to intelligently select the ideal FF type +# based on timing (it always selects the first it gets). set liberty $::env(LIBERTY) dfflibmap -liberty $liberty opt +set clk_cmd "" if { [info exists ::env(CLOCK_PERIOD) ] } { - abc -liberty $liberty -dff -script $::env(ABC_SCRIPT) -constr $::env(CONSTR) -g aig -D $::env(CLOCK_PERIOD) {*}$::env(DONT_USE_ARGS) -} else { - abc -liberty $liberty -dff -script $::env(ABC_SCRIPT) -constr $::env(CONSTR) -g aig {*}$::env(DONT_USE_ARGS) + set clk_cmd " -D $::env(CLOCK_PERIOD) " } +abc {*}$all_lib_cmd -dff -script $::env(ABC_SCRIPT) -constr $::env(CONSTR) \ + -g aig {*}$clk_cmd {*}$::env(DONT_USE_ARGS) setundef -zero splitnets opt_clean -purge -if {[info exists ::env(TIEHI_CELL_AND_PORT)] && [info exists ::env(TIELO_CELL_AND_PORT)]} { - hilomap \ - -hicell {*}[split $::env(TIEHI_CELL_AND_PORT) "/"] \ - -locell {*}[split $::env(TIELO_CELL_AND_PORT) "/"] -} elseif { [info exists ::env(TIEHI_CELL_AND_PORT)] } { - hilomap \ - -hicell {*}$::env(TIEHI_CELL_AND_PORT) -} elseif { [info exists ::env(TIELO_CELL_AND_PORT)] } { - hilomap \ - -locell {*}$::env(TIELO_CELL_AND_PORT) +set hicell "" +if {[info exists ::env(TIEHI_CELL_AND_PORT)]} { + set hicell " -hicell " + append hicell {*}[split $::env(TIEHI_CELL_AND_PORT) "/"] +} +set locell "" +if {[info exists ::env(TIELO_CELL_AND_PORT)]} { + set locell " -locell " + append locell {*}[split $::env(TIELO_CELL_AND_PORT) "/"] } +hilomap {*}$hicell {*}$locell # Remove internal only aliases for public nets and then give created instances # useful names. At this stage it is anything generated by the techmapping # passes. yosys opt_clean -purge -# write synthesized design +# Write synthesized design. set output $::env(OUTPUT) write_verilog $output -# ====== print stats / info ====== -stat -liberty $liberty +# Print stats / info. +stat {*}$all_lib_cmd if { [info exists ::env(STATS_JSON) ] } { tee -q -o $::env(STATS_JSON) stat -liberty $liberty -json yosys log Structured stats: $::env(STATS_JSON) @@ -141,5 +148,6 @@ ltp -noff $top yosys log -n "Flop count: " yosys select -count t:*__df* t:DF* t:*_DFF* t:*_SDFF* t:*_ADFF* t:*dff -set base_liberty [file tail $liberty] -yosys log Liberty: $base_liberty +foreach lib $all_liberties { + yosys log "Liberty: $lib" +}