config update
diff --git a/openlane/Makefile b/openlane/Makefile index 735e66f..865f452 100644 --- a/openlane/Makefile +++ b/openlane/Makefile
@@ -18,7 +18,7 @@ CONFIG = $(foreach block,$(BLOCKS), ./$(block)/config.tcl) CLEAN = $(foreach block,$(BLOCKS), clean-$(block)) -OPENLANE_TAG = mpw6 +OPENLANE_TAG = mpw5 OPENLANE_IMAGE_NAME = riscduino/openlane:$(OPENLANE_TAG) OPENLANE_BASIC_COMMAND = "cd $(PWD)/../openlane && flow.tcl -design ./$* -save_path .. -save -tag $* -overwrite" OPENLANE_INTERACTIVE_COMMAND = "cd $(PWD)/../openlane && flow.tcl -design ./$* -save_path .. -save -tag $* -overwrite -it -file ./$*/interactive.tcl"
diff --git a/openlane/user_project_wrapper/config.tcl b/openlane/user_project_wrapper/config.tcl index 65abbfa..4598f8a 100644 --- a/openlane/user_project_wrapper/config.tcl +++ b/openlane/user_project_wrapper/config.tcl
@@ -146,72 +146,50 @@ set ::env(FP_PDN_POWER_STRAPS) "vccd1 vssd1 1, vccd2 vssd2 0, vdda1 vssa1 0, vdda2 vssa2 0" -set ::env(FP_PDN_MACRO_HOOKS) " \ - u_intercon vccd1 vssd1,\ - u_pinmux vccd1 vssd1,\ - u_qspi_master vccd1 vssd1,\ - u_riscv_top vccd1 vssd1,\ - u_tsram0_2kb vccd1 vssd1,\ - u_icache_2kb vccd1 vssd1,\ - u_dcache_2kb vccd1 vssd1,\ - u_sram0_2kb vccd1 vssd1,\ - u_sram1_2kb vccd1 vssd1,\ - u_sram2_2kb vccd1 vssd1,\ - u_sram3_2kb vccd1 vssd1,\ - u_uart_i2c_usb_spi vccd1 vssd1,\ - u_wb_host vccd1 vssd1,\ - u_riscv_top.i_core_top_0 vccd1 vssd1, \ - u_riscv_top.i_core_top_1 vccd1 vssd1, \ - u_riscv_top.u_intf vccd1 vssd1 \ - " +#set ::env(FP_PDN_MACRO_HOOKS) " \ +# u_intercon vccd1 vssd1,\ +# u_pinmux vccd1 vssd1,\ +# u_qspi_master vccd1 vssd1,\ +# u_riscv_top vccd1 vssd1,\ +# u_tsram0_2kb vccd1 vssd1,\ +# u_icache_2kb vccd1 vssd1,\ +# u_dcache_2kb vccd1 vssd1,\ +# u_sram0_2kb vccd1 vssd1,\ +# u_sram1_2kb vccd1 vssd1,\ +# u_sram2_2kb vccd1 vssd1,\ +# u_sram3_2kb vccd1 vssd1,\ +# u_uart_i2c_usb_spi vccd1 vssd1,\ +# u_wb_host vccd1 vssd1,\ +# u_riscv_top.i_core_top_0 vccd1 vssd1, \ +# u_riscv_top.u_intf vccd1 vssd1 \ +# " # The following is because there are no std cells in the example wrapper project. set ::env(SYNTH_TOP_LEVEL) 0 set ::env(PL_RANDOM_GLB_PLACEMENT) 1 - set ::env(PL_RESIZER_DESIGN_OPTIMIZATIONS) 0 set ::env(PL_RESIZER_TIMING_OPTIMIZATIONS) 0 set ::env(PL_RESIZER_BUFFER_INPUT_PORTS) 0 set ::env(PL_RESIZER_BUFFER_OUTPUT_PORTS) 0 - set ::env(FP_PDN_ENABLE_RAILS) 0 - set ::env(DIODE_INSERTION_STRATEGY) 0 set ::env(FILL_INSERTION) 0 set ::env(TAP_DECAP_INSERTION) 0 set ::env(CLOCK_TREE_SYNTH) 0 - -set ::env(QUIT_ON_LVS_ERROR) "0" +set ::env(QUIT_ON_LVS_ERROR) "1" set ::env(QUIT_ON_MAGIC_DRC) "0" set ::env(QUIT_ON_NEGATIVE_WNS) "0" set ::env(QUIT_ON_SLEW_VIOLATIONS) "0" set ::env(QUIT_ON_TIMING_VIOLATIONS) "0" - set ::env(FP_PDN_IRDROP) "0" set ::env(FP_PDN_HORIZONTAL_HALO) "10" set ::env(FP_PDN_VERTICAL_HALO) "10" - -# - -set ::env(FP_PDN_CORE_RING_HOFFSET) {12.45} -set ::env(FP_PDN_CORE_RING_HSPACING) {1.7} -set ::env(FP_PDN_CORE_RING_HWIDTH) {3.1} - -set ::env(FP_PDN_CORE_RING_VOFFSET) {12.45} -set ::env(FP_PDN_CORE_RING_VSPACING) {1.7} -set ::env(FP_PDN_CORE_RING_VWIDTH) {3.1} - - set ::env(FP_PDN_VOFFSET) "5" set ::env(FP_PDN_VPITCH) "80" set ::env(FP_PDN_VSPACING) "15.5" set ::env(FP_PDN_VWIDTH) "3.1" - set ::env(FP_PDN_HOFFSET) "10" set ::env(FP_PDN_HPITCH) "90" set ::env(FP_PDN_HSPACING) "10" set ::env(FP_PDN_HWIDTH) "3.1" - - -
diff --git a/openlane/user_project_wrapper/interactive.tcl b/openlane/user_project_wrapper/interactive.tcl index 07190b7..ccfa729 100644 --- a/openlane/user_project_wrapper/interactive.tcl +++ b/openlane/user_project_wrapper/interactive.tcl
@@ -15,149 +15,100 @@ # See the License for the specific language governing permissions and # limitations under the License. # SPDX-License-Identifier: Apache-2.0 - package require openlane; - proc run_placement_step {args} { - if { ! [ info exists ::env(PLACEMENT_CURRENT_DEF) ] } { - set ::env(PLACEMENT_CURRENT_DEF) $::env(CURRENT_DEF) - } else { - set ::env(CURRENT_DEF) $::env(PLACEMENT_CURRENT_DEF) - } - - run_placement + if { ! [ info exists ::env(PLACEMENT_CURRENT_DEF) ] } { + set ::env(PLACEMENT_CURRENT_DEF) $::env(CURRENT_DEF) + } else { + set ::env(CURRENT_DEF) $::env(PLACEMENT_CURRENT_DEF) + } + run_placement } - proc run_cts_step {args} { - if { ! [ info exists ::env(CTS_CURRENT_DEF) ] } { - set ::env(CTS_CURRENT_DEF) $::env(CURRENT_DEF) - } else { - set ::env(CURRENT_DEF) $::env(CTS_CURRENT_DEF) - } - - run_cts - run_resizer_timing + if { ! [ info exists ::env(CTS_CURRENT_DEF) ] } { + set ::env(CTS_CURRENT_DEF) $::env(CURRENT_DEF) + } else { + set ::env(CURRENT_DEF) $::env(CTS_CURRENT_DEF) + } + run_cts + run_resizer_timing } - proc run_routing_step {args} { - if { ! [ info exists ::env(ROUTING_CURRENT_DEF) ] } { - set ::env(ROUTING_CURRENT_DEF) $::env(CURRENT_DEF) - } else { - set ::env(CURRENT_DEF) $::env(ROUTING_CURRENT_DEF) - } - run_routing + if { ! [ info exists ::env(ROUTING_CURRENT_DEF) ] } { + set ::env(ROUTING_CURRENT_DEF) $::env(CURRENT_DEF) + } else { + set ::env(CURRENT_DEF) $::env(ROUTING_CURRENT_DEF) + } + run_routing } - -proc run_parasitics_sta_step {args} { - if { ! [ info exists ::env(PARSITICS_CURRENT_DEF) ] } { - set ::env(PARSITICS_CURRENT_DEF) $::env(CURRENT_DEF) - } else { - set ::env(CURRENT_DEF) $::env(PARSITICS_CURRENT_DEF) - } - - if { $::env(RUN_SPEF_EXTRACTION) } { - run_parasitics_sta - } -} - proc run_diode_insertion_2_5_step {args} { - if { ! [ info exists ::env(DIODE_INSERTION_CURRENT_DEF) ] } { - set ::env(DIODE_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF) - } else { - set ::env(CURRENT_DEF) $::env(DIODE_INSERTION_CURRENT_DEF) - } + if { ! [ info exists ::env(DIODE_INSERTION_CURRENT_DEF) ] } { + set ::env(DIODE_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF) + } else { + set ::env(CURRENT_DEF) $::env(DIODE_INSERTION_CURRENT_DEF) + } if { ($::env(DIODE_INSERTION_STRATEGY) == 2) || ($::env(DIODE_INSERTION_STRATEGY) == 5) } { run_antenna_check heal_antenna_violators; # modifies the routed DEF } - } - proc run_lvs_step {{ lvs_enabled 1 }} { - if { ! [ info exists ::env(LVS_CURRENT_DEF) ] } { - set ::env(LVS_CURRENT_DEF) $::env(CURRENT_DEF) - } else { - set ::env(CURRENT_DEF) $::env(LVS_CURRENT_DEF) - } - - if { $lvs_enabled && $::env(RUN_LVS) } { - run_magic_spice_export; + if { ! [ info exists ::env(LVS_CURRENT_DEF) ] } { + set ::env(LVS_CURRENT_DEF) $::env(CURRENT_DEF) + } else { + set ::env(CURRENT_DEF) $::env(LVS_CURRENT_DEF) + } + if { $lvs_enabled } { + run_magic_spice_export run_lvs; # requires run_magic_spice_export } - } - proc run_drc_step {{ drc_enabled 1 }} { - if { ! [ info exists ::env(DRC_CURRENT_DEF) ] } { - set ::env(DRC_CURRENT_DEF) $::env(CURRENT_DEF) - } else { - set ::env(CURRENT_DEF) $::env(DRC_CURRENT_DEF) - } + if { ! [ info exists ::env(DRC_CURRENT_DEF) ] } { + set ::env(DRC_CURRENT_DEF) $::env(CURRENT_DEF) + } else { + set ::env(CURRENT_DEF) $::env(DRC_CURRENT_DEF) + } if { $drc_enabled } { - if { $::env(RUN_MAGIC_DRC) } { - run_magic_drc - } - if {$::env(RUN_KLAYOUT_DRC)} { - run_klayout_drc - } + run_magic_drc + run_klayout_drc } } - proc run_antenna_check_step {{ antenna_check_enabled 1 }} { - if { ! [ info exists ::env(ANTENNA_CHECK_CURRENT_DEF) ] } { - set ::env(ANTENNA_CHECK_CURRENT_DEF) $::env(CURRENT_DEF) - } else { - set ::env(CURRENT_DEF) $::env(ANTENNA_CHECK_CURRENT_DEF) - } + if { ! [ info exists ::env(ANTENNA_CHECK_CURRENT_DEF) ] } { + set ::env(ANTENNA_CHECK_CURRENT_DEF) $::env(CURRENT_DEF) + } else { + set ::env(CURRENT_DEF) $::env(ANTENNA_CHECK_CURRENT_DEF) + } if { $antenna_check_enabled } { run_antenna_check } } - proc run_eco_step {args} { if { $::env(ECO_ENABLE) == 1 } { - run_eco_flow - } + run_eco + } } - -proc run_magic_step {args} { - if {$::env(RUN_MAGIC)} { - run_magic - } -} - -proc run_klayout_step {args} { - if {$::env(RUN_KLAYOUT)} { - run_klayout - } - if {$::env(RUN_KLAYOUT_XOR)} { - run_klayout_gds_xor - } -} - proc save_final_views {args} { set options { {-save_path optional} } set flags {} parse_key_args "save_final_views" args arg_values $options flags_map $flags - set arg_list [list] - # If they don't exist, save_views will simply not copy them - lappend arg_list -lef_path $::env(signoff_results)/$::env(DESIGN_NAME).lef - lappend arg_list -gds_path $::env(signoff_results)/$::env(DESIGN_NAME).gds - lappend arg_list -mag_path $::env(signoff_results)/$::env(DESIGN_NAME).mag - lappend arg_list -maglef_path $::env(signoff_results)/$::env(DESIGN_NAME).lef.mag - lappend arg_list -spice_path $::env(signoff_results)/$::env(DESIGN_NAME).spice - + lappend arg_list -lef_path $::env(finishing_results)/$::env(DESIGN_NAME).lef + lappend arg_list -gds_path $::env(finishing_results)/$::env(DESIGN_NAME).gds + lappend arg_list -mag_path $::env(finishing_results)/$::env(DESIGN_NAME).mag + lappend arg_list -maglef_path $::env(finishing_results)/$::env(DESIGN_NAME).lef.mag + lappend arg_list -spice_path $::env(finishing_results)/$::env(DESIGN_NAME).spice + # Guaranteed to have default values lappend arg_list -def_path $::env(CURRENT_DEF) lappend arg_list -verilog_path $::env(CURRENT_NETLIST) - # Not guaranteed to have default values - if { [info exists ::env(CURRENT_SPEF)] } { - lappend arg_list -spef_path $::env(CURRENT_SPEF) + if { [info exists ::env(SPEF_TYPICAL)] } { + lappend arg_list -spef_path $::env(SPEF_TYPICAL) } if { [info exists ::env(CURRENT_SDF)] } { lappend arg_list -sdf_path $::env(CURRENT_SDF) @@ -165,17 +116,13 @@ if { [info exists ::env(CURRENT_SDC)] } { lappend arg_list -sdc_path $::env(CURRENT_SDC) } - # Add the path if it exists... if { [info exists arg_values(-save_path) ] } { lappend arg_list -save_path $arg_values(-save_path) } - # Aaand fire! save_views {*}$arg_list - } - proc run_post_run_hooks {} { if { [file exists $::env(DESIGN_DIR)/hooks/post_run.py]} { puts_info "Running post run hook" @@ -185,72 +132,24 @@ puts_info "hooks/post_run.py not found, skipping" } } - proc gen_pdn {args} { - increment_index - TIMER::timer_start puts_info "Generating PDN..." - - set ::env(SAVE_DEF) [index_file $::env(floorplan_tmpfiles)/pdn.def] - set ::env(PGA_RPT_FILE) [index_file $::env(floorplan_tmpfiles)/pdn.pga.rpt] - + TIMER::timer_start + + set ::env(SAVE_DEF) [index_file $::env(floorplan_tmpfiles).def] + set ::env(PGA_RPT_FILE) [index_file $::env(floorplan_tmpfiles).pga.rpt] run_openroad_script $::env(SCRIPTS_DIR)/openroad/pdn.tcl \ |& -indexed_log [index_file $::env(floorplan_logs)/pdn.log] - - TIMER::timer_stop exec echo "[TIMER::get_runtime]" | python3 $::env(SCRIPTS_DIR)/write_runtime.py "pdn generation - openroad" - quit_on_unconnected_pdn_nodes - set_def $::env(SAVE_DEF) } - proc run_power_grid_generation {args} { - if { [info exists ::env(VDD_NETS)] || [info exists ::env(GND_NETS)] } { - # they both must exist and be equal in length - # current assumption: they cannot have a common ground - if { ! [info exists ::env(VDD_NETS)] || ! [info exists ::env(GND_NETS)] } { - puts_err "VDD_NETS and GND_NETS must *both* either be defined or undefined" - return -code error - } - # standard cell power and ground nets are assumed to be the first net - set ::env(VDD_PIN) [lindex $::env(VDD_NETS) 0] - set ::env(GND_PIN) [lindex $::env(GND_NETS) 0] - } elseif { [info exists ::env(SYNTH_USE_PG_PINS_DEFINES)] } { - set ::env(VDD_NETS) [list] - set ::env(GND_NETS) [list] - # get the pins that are in $synthesis_tmpfiles.pg_define.v - # that are not in $synthesis_results.v - # - set full_pins {*}[extract_pins_from_yosys_netlist $::env(synthesis_tmpfiles)/pg_define.v] - puts_info $full_pins - - set non_pg_pins {*}[extract_pins_from_yosys_netlist $::env(synthesis_results)/$::env(DESIGN_NAME).v] - puts_info $non_pg_pins - - # assumes the pins are ordered correctly (e.g., vdd1, vss1, vcc1, vss1, ...) - foreach {vdd gnd} $full_pins { - if { $vdd ne "" && $vdd ni $non_pg_pins } { - lappend ::env(VDD_NETS) $vdd - } - if { $gnd ne "" && $gnd ni $non_pg_pins } { - lappend ::env(GND_NETS) $gnd - } - } - } else { - set ::env(VDD_NETS) $::env(VDD_PIN) - set ::env(GND_NETS) $::env(GND_PIN) + if {[info exists ::env(FP_PDN_POWER_STRAPS)]} { + set power_domains [split $::env(FP_PDN_POWER_STRAPS) ","] } - - puts_info "Power planning with power {$::env(VDD_NETS)} and ground {$::env(GND_NETS)}..." - - if { [llength $::env(VDD_NETS)] != [llength $::env(GND_NETS)] } { - puts_err "VDD_NETS and GND_NETS must be of equal lengths" - return -code error - } - - # check internal macros' power connection definitions + # internal macros power connections if {[info exists ::env(FP_PDN_MACRO_HOOKS)]} { set macro_hooks [dict create] set pdn_hooks [split $::env(FP_PDN_MACRO_HOOKS) ","] @@ -260,20 +159,66 @@ set ground_net [lindex $pdn_hook 2] dict append macro_hooks $instance_name [subst {$power_net $ground_net}] } - + set power_net_indx [lsearch $::env(VDD_NETS) $power_net] set ground_net_indx [lsearch $::env(GND_NETS) $ground_net] - # make sure that the specified power domains exist. if { $power_net_indx == -1 || $ground_net_indx == -1 || $power_net_indx != $ground_net_indx } { puts_err "Can't find $power_net and $ground_net domain. \ - Make sure that both exist in $::env(VDD_NETS) and $::env(GND_NETS)." - } + Make sure that both exist in $::env(VDD_NETS) and $::env(GND_NETS)." + } } - - gen_pdn + + # generate multiple power grids per pair of (VDD,GND) + # offseted by WIDTH + SPACING + foreach domain $power_domains { + set ::env(VDD_NET) [lindex $domain 0] + set ::env(GND_NET) [lindex $domain 1] + set ::env(_WITH_STRAPS) [lindex $domain 2] + puts_info "Connecting Power: $::env(VDD_NET) & $::env(GND_NET) to All internal macros." + # internal macros power connections + set ::env(FP_PDN_MACROS) "" + if { $::env(FP_PDN_ENABLE_MACROS_GRID) == 1 } { + # if macros connections to power are explicitly set + # default behavoir macro pins will be connected to the first power domain + if { [info exists ::env(FP_PDN_MACRO_HOOKS)] } { + set ::env(FP_PDN_ENABLE_MACROS_GRID) 0 + foreach {instance_name hooks} $macro_hooks { + set power [lindex $hooks 0] + set ground [lindex $hooks 1] + if { $power == $::env(VDD_NET) && $ground == $::env(GND_NET) } { + set ::env(FP_PDN_ENABLE_MACROS_GRID) 1 + set ::env(FP_PDN_IRDROP) "0" + puts_info "Connecting $instance_name to $power and $ground nets." + lappend ::env(FP_PDN_MACROS) $instance_name + } + } + } + } else { + puts_warn "All internal macros will not be connected to power $::env(VDD_NET) & $::env(GND_NET)." + } + + gen_pdn + set ::env(FP_PDN_ENABLE_RAILS) 0 + set ::env(FP_PDN_ENABLE_MACROS_GRID) 0 + set ::env(FP_PDN_IRDROP) "0" + # allow failure until open_pdks is up to date... + catch {set ::env(FP_PDN_VOFFSET) [expr $::env(FP_PDN_VOFFSET)+$::env(FP_PDN_VWIDTH)+$::env(FP_PDN_VSPACING)]} + catch {set ::env(FP_PDN_HOFFSET) [expr $::env(FP_PDN_HOFFSET)+$::env(FP_PDN_HWIDTH)+$::env(FP_PDN_HSPACING)]} + catch {set ::env(FP_PDN_CORE_RING_VOFFSET) \ + [expr $::env(FP_PDN_CORE_RING_VOFFSET)\ + +2*($::env(FP_PDN_CORE_RING_VWIDTH)\ + +max($::env(FP_PDN_CORE_RING_VSPACING), $::env(FP_PDN_CORE_RING_HSPACING)))]} + catch {set ::env(FP_PDN_CORE_RING_HOFFSET) [expr $::env(FP_PDN_CORE_RING_HOFFSET)\ + +2*($::env(FP_PDN_CORE_RING_HWIDTH)+\ + max($::env(FP_PDN_CORE_RING_VSPACING), $::env(FP_PDN_CORE_RING_HSPACING)))]} + puts "FP_PDN_VOFFSET: $::env(FP_PDN_VOFFSET)" + puts "FP_PDN_HOFFSET: $::env(FP_PDN_HOFFSET)" + puts "FP_PDN_CORE_RING_VOFFSET: $::env(FP_PDN_CORE_RING_VOFFSET)" + puts "FP_PDN_CORE_RING_HOFFSET: $::env(FP_PDN_CORE_RING_HOFFSET)" + } + set ::env(FP_PDN_ENABLE_RAILS) 1 } - proc run_floorplan {args} { puts_info "Running Floorplanning..." # |----------------------------------------------------| @@ -282,7 +227,6 @@ # # intial fp init_floorplan - # check for deprecated io variables if { [info exists ::env(FP_IO_HMETAL)]} { set ::env(FP_IO_HLAYER) [lindex $::env(TECH_METAL_LAYERS) [expr {$::env(FP_IO_HMETAL) - 1}]] @@ -290,15 +234,12 @@ puts_warn "We recommend you update your configuration as follows:" puts_warn "\tset ::env(FP_IO_HLAYER) {$::env(FP_IO_HLAYER)}" } - if { [info exists ::env(FP_IO_VMETAL)]} { set ::env(FP_IO_VLAYER) [lindex $::env(TECH_METAL_LAYERS) [expr {$::env(FP_IO_VMETAL) - 1}]] puts_warn "You're using FP_IO_VMETAL in your configuration, which is a deprecated variable that will be removed in the future." puts_warn "We recommend you update your configuration as follows:" puts_warn "\tset ::env(FP_IO_VLAYER) {$::env(FP_IO_VLAYER)}" } - - # place io if { [info exists ::env(FP_PIN_ORDER_CFG)] } { place_io_ol @@ -313,9 +254,7 @@ place_io } } - apply_def_template - if { [info exist ::env(EXTRA_LEFS)] } { if { [info exist ::env(MACRO_PLACEMENT_CFG)] } { file copy -force $::env(MACRO_PLACEMENT_CFG) $::env(placement_tmpfiles)/macro_placement.cfg @@ -325,15 +264,10 @@ basic_macro_placement } } - tap_decap_or - scrot_klayout -layout $::env(CURRENT_DEF) $::env(floorplan_logs)/screenshot.log - run_power_grid_generation } - - proc run_flow {args} { set options { {-design required} @@ -346,11 +280,6 @@ parse_key_args "run_non_interactive_mode" args arg_values $options flags_map $flags -no_consume prep {*}$args # signal trap SIGINT save_state; - - if { [info exists flags_map(-gui)] } { - or_gui - return - } if { [info exists arg_values(-override_env)] } { set env_overrides [split $arg_values(-override_env) ','] foreach override $env_overrides { @@ -360,67 +289,56 @@ set ::env(${key}) $value } } - set LVS_ENABLED 1 set DRC_ENABLED 0 set ANTENNACHECK_ENABLED 1 - - set steps [dict create \ - "synthesis" "run_synthesis" \ - "floorplan" "run_floorplan" \ - "placement" "run_placement_step" \ - "cts" "run_cts_step" \ - "routing" "run_routing_step" \ - "parasitics_sta" "run_parasitics_sta_step" \ - "eco" "run_eco_step" \ - "diode_insertion" "run_diode_insertion_2_5_step" \ - "gds_magic" "run_magic_step" \ - "gds_klayout" "run_klayout_step" \ - "lvs" "run_lvs_step $LVS_ENABLED " \ - "drc" "run_drc_step $DRC_ENABLED " \ - "antenna_check" "run_antenna_check_step $ANTENNACHECK_ENABLED " \ - "cvc" "run_lef_cvc" - ] - + set steps [dict create \ + "synthesis" {run_synthesis "" } \ + "floorplan" {run_floorplan ""} \ + "placement" {run_placement_step ""} \ + "cts" {run_cts_step ""} \ + "routing" {run_routing_step ""}\ + "eco" {run_eco_step ""} \ + "diode_insertion" {run_diode_insertion_2_5_step ""} \ + "gds_magic" {run_magic ""} \ + "gds_drc_klayout" {run_klayout ""} \ + "gds_xor_klayout" {run_klayout_gds_xor ""} \ + "lvs" "run_lvs_step $LVS_ENABLED" \ + "drc" "run_drc_step $DRC_ENABLED" \ + "antenna_check" "run_antenna_check_step $ANTENNACHECK_ENABLED" \ + "cvc" {run_lef_cvc} + ] set_if_unset arg_values(-to) "cvc"; - if { [info exists ::env(CURRENT_STEP) ] } { puts "\[INFO\]:Picking up where last execution left off" puts [format "\[INFO\]:Current stage is %s " $::env(CURRENT_STEP)] } else { set ::env(CURRENT_STEP) "synthesis"; } - set_if_unset arg_values(-from) $::env(CURRENT_STEP); set exe 0; dict for {step_name step_exe} $steps { if { [ string equal $arg_values(-from) $step_name ] } { set exe 1; } - if { $exe } { # For when it fails set ::env(CURRENT_STEP) $step_name [lindex $step_exe 0] [lindex $step_exe 1] ; } - if { [ string equal $arg_values(-to) $step_name ] } { set exe 0: break; } - } - # for when it resumes set steps_as_list [dict keys $steps] set next_idx [expr [lsearch $steps_as_list $::env(CURRENT_STEP)] + 1] set ::env(CURRENT_STEP) [lindex $steps_as_list $next_idx] - # Saves to <RUN_DIR>/results/final if { $::env(SAVE_FINAL_VIEWS) == "1" } { save_final_views } - # Saves to design directory or custom if { [info exists flags_map(-save) ] } { if { ! [info exists arg_values(-save_path)] } { @@ -448,9 +366,6 @@ } puts_success "Flow complete." - show_warnings "Note that the following warnings have been generated:" - } - run_flow {*}$argv
diff --git a/openlane/user_project_wrapper/pdn_cfg.tcl b/openlane/user_project_wrapper/pdn_cfg.tcl index 1bd5f1e..552a90e 100644 --- a/openlane/user_project_wrapper/pdn_cfg.tcl +++ b/openlane/user_project_wrapper/pdn_cfg.tcl
@@ -1,165 +1,82 @@ # Power nets - if { ! [info exists ::env(VDD_NET)] } { set ::env(VDD_NET) $::env(VDD_PIN) } - if { ! [info exists ::env(GND_NET)] } { set ::env(GND_NET) $::env(GND_PIN) } - +set ::power_nets $::env(VDD_NET) +set ::ground_nets $::env(GND_NET) if { [info exists ::env(FP_PDN_ENABLE_GLOBAL_CONNECTIONS)] } { if { $::env(FP_PDN_ENABLE_GLOBAL_CONNECTIONS) == 1 } { foreach power_pin $::env(STD_CELL_POWER_PINS) { - add_global_connection \ - -net $::env(VDD_NET) \ - -inst_pattern .* \ - -pin_pattern $power_pin \ - -power + add_global_connection -net $::env(VDD_NET) -inst_pattern .* -pin_pattern $power_pin -power } foreach ground_pin $::env(STD_CELL_GROUND_PINS) { - add_global_connection \ - -net $::env(GND_NET) \ - -inst_pattern .* \ - -pin_pattern $ground_pin \ - -ground + add_global_connection -net $::env(GND_NET) -inst_pattern .* -pin_pattern $ground_pin -ground } } } - -if { $::env(FP_PDN_ENABLE_MACROS_GRID) == 1 && - [info exists ::env(FP_PDN_MACRO_HOOKS)]} { - set pdn_hooks [split $::env(FP_PDN_MACRO_HOOKS) ","] - foreach pdn_hook $pdn_hooks { - set instance_name [lindex $pdn_hook 0] - set power_net [lindex $pdn_hook 1] - set ground_net [lindex $pdn_hook 2] - # This assumes the power pin and the power net have the same name. - # The macro hooks only give an instance name and not power pin names. - - add_global_connection \ - -net $power_net \ - -inst_pattern $instance_name \ - -pin_pattern $power_net \ - -power - - add_global_connection \ - -net $ground_net \ - -inst_pattern $instance_name \ - -pin_pattern $ground_net \ - -ground - } -} - -set secondary [] - -foreach vdd $::env(VDD_NETS) gnd $::env(GND_NETS) { - if { $vdd != $::env(VDD_NET)} { - lappend secondary $vdd - - set db_net [[ord::get_db_block] findNet $vdd] - if {$db_net == "NULL"} { - set net [odb::dbNet_create [ord::get_db_block] $vdd] - $net setSpecial - $net setSigType "POWER" - } - } - - if { $gnd != $::env(GND_NET)} { - lappend secondary $gnd - - set db_net [[ord::get_db_block] findNet $gnd] - if {$db_net == "NULL"} { - set net [odb::dbNet_create [ord::get_db_block] $gnd] - $net setSpecial - $net setSigType "GROUND" - } - } -} - -set_voltage_domain -name CORE -power $::env(VDD_NET) -ground $::env(GND_NET) \ - -secondary_power $secondary - -# Assesses whether the design is the core of the chip or not based on the +set_voltage_domain -name CORE -power $::env(VDD_NET) -ground $::env(GND_NET) +# Assesses whether the deisgn is the core of the chip or not based on the # value of $::env(DESIGN_IS_CORE) and uses the appropriate stdcell section if { $::env(DESIGN_IS_CORE) == 1 } { # Used if the design is the core of the chip - define_pdn_grid \ - -name stdcell_grid \ - -starts_with POWER \ - -voltage_domain CORE \ - -pins "$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)" - - add_pdn_stripe \ - -grid stdcell_grid \ - -layer $::env(FP_PDN_LOWER_LAYER) \ - -width $::env(FP_PDN_VWIDTH) \ - -pitch $::env(FP_PDN_VPITCH) \ - -offset $::env(FP_PDN_VOFFSET) \ - -nets "$::env(VDD_NET) $::env(GND_NET)" \ - -starts_with POWER -extend_to_core_ring - - add_pdn_stripe \ - -grid stdcell_grid \ - -layer $::env(FP_PDN_UPPER_LAYER) \ - -width $::env(FP_PDN_HWIDTH) \ - -pitch $::env(FP_PDN_HPITCH) \ - -offset $::env(FP_PDN_HOFFSET) \ - -nets "$::env(VDD_NET) $::env(GND_NET)" \ - -starts_with POWER -extend_to_core_ring - - add_pdn_connect \ - -grid stdcell_grid \ - -layers "$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)" + define_pdn_grid -name stdcell_grid -starts_with POWER -voltage_domain CORE -pins [subst {$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)}] + if { $::env(_WITH_STRAPS) } { + add_pdn_stripe -grid stdcell_grid -layer $::env(FP_PDN_LOWER_LAYER) -width $::env(FP_PDN_VWIDTH) -pitch $::env(FP_PDN_VPITCH) -offset $::env(FP_PDN_VOFFSET) -starts_with POWER + add_pdn_stripe -grid stdcell_grid -layer $::env(FP_PDN_UPPER_LAYER) -width $::env(FP_PDN_HWIDTH) -pitch $::env(FP_PDN_HPITCH) -offset $::env(FP_PDN_HOFFSET) -starts_with POWER + } + add_pdn_connect -grid stdcell_grid -layers [subst {$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)}] } else { # Used if the design is a macro in the core - define_pdn_grid \ - -name stdcell_grid \ - -starts_with POWER \ - -voltage_domain CORE \ - -pins $::env(FP_PDN_LOWER_LAYER) - - add_pdn_stripe \ - -grid stdcell_grid \ - -layer $::env(FP_PDN_LOWER_LAYER) \ - -width $::env(FP_PDN_VWIDTH) \ - -pitch $::env(FP_PDN_VPITCH) \ - -offset $::env(FP_PDN_VOFFSET) \ - -starts_with POWER + define_pdn_grid -name stdcell_grid -starts_with POWER -voltage_domain CORE -pins $::env(FP_PDN_LOWER_LAYER) + add_pdn_stripe -grid stdcell_grid -layer $::env(FP_PDN_LOWER_LAYER) -width $::env(FP_PDN_VWIDTH) -pitch $::env(FP_PDN_VPITCH) -offset $::env(FP_PDN_VOFFSET) -starts_with POWER } - # Adds the standard cell rails if enabled. if { $::env(FP_PDN_ENABLE_RAILS) == 1 } { - add_pdn_stripe \ - -grid stdcell_grid \ - -layer $::env(FP_PDN_RAILS_LAYER) \ - -width $::env(FP_PDN_RAIL_WIDTH) \ - -followpins \ - -starts_with POWER - - add_pdn_connect \ - -grid stdcell_grid \ - -layers "$::env(FP_PDN_RAILS_LAYER) $::env(FP_PDN_LOWER_LAYER)" + add_pdn_stripe -grid stdcell_grid -layer $::env(FP_PDN_RAILS_LAYER) -width $::env(FP_PDN_RAIL_WIDTH) -followpins -starts_with POWER + add_pdn_connect -grid stdcell_grid -layers [subst {$::env(FP_PDN_RAILS_LAYER) $::env(FP_PDN_LOWER_LAYER)}] } - - # Adds the core ring if enabled. if { $::env(FP_PDN_CORE_RING) == 1 } { - add_pdn_ring \ - -grid stdcell_grid \ - -layers "$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)" \ - -widths "$::env(FP_PDN_CORE_RING_VWIDTH) $::env(FP_PDN_CORE_RING_HWIDTH)" \ - -spacings "$::env(FP_PDN_CORE_RING_VSPACING) $::env(FP_PDN_CORE_RING_HSPACING)" \ - -core_offset "$::env(FP_PDN_CORE_RING_VOFFSET) $::env(FP_PDN_CORE_RING_HOFFSET)" + add_pdn_ring -grid stdcell_grid -layer [subst {$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)}] \ + -widths [subst {$::env(FP_PDN_CORE_RING_VWIDTH) $::env(FP_PDN_CORE_RING_HWIDTH)}] \ + -spacings [subst {$::env(FP_PDN_CORE_RING_VSPACING) $::env(FP_PDN_CORE_RING_HSPACING)}] \ + -core_offset [subst {$::env(FP_PDN_CORE_RING_VOFFSET) $::env(FP_PDN_CORE_RING_HOFFSET)}] } - -define_pdn_grid \ - -macro \ - -default \ - -name macro \ - -starts_with POWER \ - -halo "$::env(FP_PDN_HORIZONTAL_HALO) $::env(FP_PDN_VERTICAL_HALO)" - -add_pdn_connect \ - -grid macro \ - -layers "$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)" +# A general macro that follows the premise of the set heirarchy. You may want to modify this or add other macro configs +# The macro power pin names are assumed to match the VDD and GND net names +# TODO: parameterize the power pin names +set macro { + orient {R0 R180 MX MY R90 R270 MXR90 MYR90} + power_pins $::env(VDD_NET) + ground_pins $::env(GND_NET) + blockages $::env(MACRO_BLOCKAGES_LAYER) + straps { + } + connect {{$::env(FP_PDN_LOWER_LAYER)_PIN_ver $::env(FP_PDN_UPPER_LAYER)}} +} +if { $::env(FP_PDN_ENABLE_MACROS_GRID) == 1} { + if { [llength $::env(FP_PDN_MACROS)] > 0 } { + # generate automatically per instance: + foreach macro_instance $::env(FP_PDN_MACROS) { + set macro_instance_grid [subst $macro] + dict append $macro_instance_grid instance $macro_instance + set ::halo [list $::env(FP_PDN_HORIZONTAL_HALO) $::env(FP_PDN_VERTICAL_HALO)] + pdngen::specify_grid macro [subst $macro_instance_grid] + } + } else { + set ::halo [list $::env(FP_PDN_HORIZONTAL_HALO) $::env(FP_PDN_VERTICAL_HALO)] + pdngen::specify_grid macro [subst $macro] + } + # CAN NOT ENABLE THE TCL COMMAND BECAUSE THERE IS NO ARGUMENT FOR SPECIFYING THE POWER AND GROUND PIN NAMES ON THE MACRO + # define_pdn_grid -macro -orient {R0 R180 MX MY R90 R270 MXR90 MYR90} -grid_over_pg_pins -starts_with POWER -pin_direction vertical -halo [subst {$::env(FP_PDN_HORIZONTAL_HALO) $::env(FP_PDN_VERTICAL_HALO)}] + # add_pdn_connect -layers [subst {$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)}] +} else { + define_pdn_grid -macro -orient {R0 R180 MX MY R90 R270 MXR90 MYR90} -grid_over_pg_pins -starts_with POWER -halo [subst {$::env(FP_PDN_HORIZONTAL_HALO) $::env(FP_PDN_VERTICAL_HALO)}] +} +# POWER or GROUND #Std. cell rails starting with power or ground rails at the bottom of the core area +set ::rails_start_with "POWER" ; +# POWER or GROUND #Upper metal stripes starting with power or ground rails at the left/bottom of the core area +set ::stripes_start_with "POWER" ;
diff --git a/signoff/user_project_wrapper/OPENLANE_VERSION b/signoff/user_project_wrapper/OPENLANE_VERSION index 078e9d2..80c7664 100644 --- a/signoff/user_project_wrapper/OPENLANE_VERSION +++ b/signoff/user_project_wrapper/OPENLANE_VERSION
@@ -1 +1 @@ -openlane 0dc6fb79c91082b94f8ded78d70f8bacbab96bf2 +openlane N/A
diff --git a/signoff/user_project_wrapper/PDK_SOURCES b/signoff/user_project_wrapper/PDK_SOURCES index b08beb4..22e7dc1 100644 --- a/signoff/user_project_wrapper/PDK_SOURCES +++ b/signoff/user_project_wrapper/PDK_SOURCES
@@ -1 +1,3 @@ -open_pdks 41c0908b47130d5675ff8484255b43f66463a7d6 +openlane 70923d7fbd8998c8da87d905cf9e69bffc13709f +skywater-pdk c094b6e83a4f9298e47f696ec5a7fd53535ec5eb +open_pdks 476f7428f7f686de51a5164c702629a9b9f2da46
diff --git a/signoff/user_project_wrapper/final_summary_report.csv b/signoff/user_project_wrapper/final_summary_report.csv index fd0ffe5..3cd9116 100644 --- a/signoff/user_project_wrapper/final_summary_report.csv +++ b/signoff/user_project_wrapper/final_summary_report.csv
@@ -1,2 +1,2 @@ ,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY -0,/project/openlane/user_project_wrapper,user_project_wrapper,user_project_wrapper,flow completed,1h2m10s0ms,0h4m30s0ms,-2.0,-1,-1,-1,590.02,14,0,0,0,0,0,0,-1,0,0,-1,-1,1528399,14110,0.0,-1,-1,0.0,0.0,0.0,-1,-1,0.0,0.0,-1,0.0,7.57,9.14,1.71,2.11,0.0,391,4307,391,4307,0,0,0,14,0,0,0,0,0,0,0,0,-1,-1,-1,0,0,0,0,100.0,10.0,10,AREA 0,5,50,1,80,90,0.55,0.3,sky130_fd_sc_hd,4,0 +0,/home/dinesha/workarea/opencore/git/riscduino_qcore/openlane/user_project_wrapper,user_project_wrapper,user_project_wrapper,flow completed,2h17m48s0ms,0h4m40s0ms,-2.0,-1,-1,-1,571.57,15,0,0,0,0,0,0,-1,0,0,-1,-1,1528755,14508,0.0,-1,-1,0.0,0.0,0.0,-1,-1,0.0,0.0,-1,0.0,7.38,8.83,1.75,2.51,0.0,409,4330,409,4330,0,0,0,15,0,0,0,0,0,0,0,0,-1,-1,-1,0,0,0,0,100.0,10.0,10,AREA 0,5,50,1,80,90,0.55,0.3,sky130_fd_sc_hd,4,0