mpw-6 pdn fix
diff --git a/Makefile b/Makefile index 1fcad3c..09c44b5 100644 --- a/Makefile +++ b/Makefile
@@ -207,6 +207,7 @@ gzip -f maglef/* gzip -f spef/* gzip -f spi/lvs/* + gzip -f verilog/gl/* unzip: gzip -d def/* @@ -216,6 +217,7 @@ gzip -d maglef/* gzip -d spef/* gzip -d spi/lvs/* + gzip -d verilog/gl/* .PHONY: help help:
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/pinmux/config.tcl b/openlane/pinmux/config.tcl index 7650732..f844215 100755 --- a/openlane/pinmux/config.tcl +++ b/openlane/pinmux/config.tcl
@@ -85,6 +85,9 @@ set ::env(PL_TARGET_DENSITY) "0.30" set ::env(CELL_PAD) "4" +set ::env(FP_IO_VEXTEND) {6} +set ::env(FP_IO_HEXTEND) {6} + # helps in anteena fix set ::env(USE_ARC_ANTENNA_CHECK) "0" @@ -105,6 +108,6 @@ set ::env(QUIT_ON_TIMING_VIOLATIONS) "0" -set ::env(QUIT_ON_MAGIC_DRC) "0" -set ::env(QUIT_ON_LVS_ERROR) "0" +set ::env(QUIT_ON_MAGIC_DRC) "1" +set ::env(QUIT_ON_LVS_ERROR) "1" set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
diff --git a/openlane/qspim_top/config.tcl b/openlane/qspim_top/config.tcl index f17f63d..187e486 100755 --- a/openlane/qspim_top/config.tcl +++ b/openlane/qspim_top/config.tcl
@@ -101,5 +101,5 @@ set ::env(QUIT_ON_TIMING_VIOLATIONS) "0" set ::env(QUIT_ON_MAGIC_DRC) "1" -set ::env(QUIT_ON_LVS_ERROR) "0" +set ::env(QUIT_ON_LVS_ERROR) "1" set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
diff --git a/openlane/uart_i2cm_usb_spi_top/config.tcl b/openlane/uart_i2cm_usb_spi_top/config.tcl index a97080d..802f0cf 100644 --- a/openlane/uart_i2cm_usb_spi_top/config.tcl +++ b/openlane/uart_i2cm_usb_spi_top/config.tcl
@@ -128,5 +128,5 @@ set ::env(QUIT_ON_TIMING_VIOLATIONS) "0" set ::env(QUIT_ON_MAGIC_DRC) "1" -set ::env(QUIT_ON_LVS_ERROR) "0" +set ::env(QUIT_ON_LVS_ERROR) "1" set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
diff --git a/openlane/user_project_wrapper/config.tcl b/openlane/user_project_wrapper/config.tcl index 1751888..e58ee59 100644 --- a/openlane/user_project_wrapper/config.tcl +++ b/openlane/user_project_wrapper/config.tcl
@@ -148,72 +148,51 @@ 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.i_core_top_1 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.mpw4.tcl b/openlane/user_project_wrapper/interactive.mpw4.tcl deleted file mode 100644 index 1c24305..0000000 --- a/openlane/user_project_wrapper/interactive.mpw4.tcl +++ /dev/null
@@ -1,394 +0,0 @@ -#!/usr/bin/tclsh -# SPDX-FileCopyrightText: 2020 Efabless Corporation -# Copyright 2020 Efabless Corporation -# Copyright 2020 Sylvain Munaut -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# 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 -} - -proc run_placement {args} { - puts_info "Running Placement..." -# |----------------------------------------------------| -# |---------------- 3. PLACEMENT ------------------| -# |----------------------------------------------------| - set ::env(CURRENT_STAGE) placement - - if { [info exists ::env(PL_TARGET_DENSITY_CELLS)] } { - set old_pl_target_density $::env(PL_TARGET_DENSITY) - set ::env(PL_TARGET_DENSITY) $::env(PL_TARGET_DENSITY_CELLS) - } - - if { $::env(PL_RANDOM_GLB_PLACEMENT) } { - # useful for very tiny designs - random_global_placement - } else { - global_placement_or - } - - if { [info exists ::env(PL_TARGET_DENSITY_CELLS)] } { - set ::env(PL_TARGET_DENSITY) $old_pl_target_density - } - - run_resizer_design - - if { [info exists ::env(DONT_BUFFER_PORTS) ]} { - remove_buffers - } - detailed_placement_or - scrot_klayout -layout $::env(CURRENT_DEF) -} - - -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 -} - -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 -} - -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 { ($::env(DIODE_INSERTION_STRATEGY) == 2) || ($::env(DIODE_INSERTION_STRATEGY) == 5) } { - run_antenna_check - heal_antenna_violators; # modifies the routed DEF - } - -} - -proc run_power_pins_insertion_step {args} { - # set_def $::env(tritonRoute_result_file_tag).def - if { ! [ info exists ::env(POWER_PINS_INSERTION_CURRENT_DEF) ] } { - set ::env(POWER_PINS_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF) - } else { - set ::env(CURRENT_DEF) $::env(POWER_PINS_INSERTION_CURRENT_DEF) - } - if { $::env(LVS_INSERT_POWER_PINS) } { - write_powered_verilog - set_netlist $::env(lvs_result_file_tag).powered.v - } - -} - - -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 } { - 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 { $drc_enabled } { - 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 { $antenna_check_enabled } { - run_antenna_check - } -} - - -proc gen_pdn {args} { - puts_info "Generating PDN..." - TIMER::timer_start - - set ::env(SAVE_DEF) [index_file $::env(pdn_tmp_file_tag).def] - set ::env(PGA_RPT_FILE) [index_file $::env(pdn_report_file_tag).pga.rpt] - - try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/pdn.tcl \ - |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(pdn_log_file_tag).log 0] - - - TIMER::timer_stop - exec echo "[TIMER::get_runtime]" >> [index_file $::env(pdn_log_file_tag)_runtime.txt 0] - - quit_on_unconnected_pdn_nodes - - set_def $::env(SAVE_DEF) -} - -proc run_power_grid_generation {args} { - - if {[info exists ::env(FP_PDN_POWER_STRAPS)]} { - set power_domains [split $::env(FP_PDN_POWER_STRAPS) ","] - } - - # 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) ","] - 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] - 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)." - } - } - - # 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) "1" - 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..." - # |----------------------------------------------------| - # |---------------- 2. FLOORPLAN ------------------| - # |----------------------------------------------------| - # - # intial fp - init_floorplan - - - # place io - if { [info exists ::env(FP_PIN_ORDER_CFG)] } { - place_io_ol - } else { - if { [info exists ::env(FP_CONTEXT_DEF)] && [info exists ::env(FP_CONTEXT_LEF)] } { - place_io - global_placement_or - place_contextualized_io \ - -lef $::env(FP_CONTEXT_LEF) \ - -def $::env(FP_CONTEXT_DEF) - } else { - 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(TMP_DIR)/macro_placement.cfg - manual_macro_placement f - } else { - global_placement_or - basic_macro_placement - } - } - - # tapcell - tap_decap_or - scrot_klayout -layout $::env(CURRENT_DEF) - # power grid generation - run_power_grid_generation -} - - -proc run_flow {args} { - set script_dir [file dirname [file normalize [info script]]] - - set options { - {-design required} - {-save_path optional} - {-no_lvs optional} - {-no_drc optional} - {-no_antennacheck optional} - } - set flags {-save} - parse_key_args "run_flow" args arg_values $options flags_map $flags -no_consume - - prep {*}$args - - 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 ""} \ - "diode_insertion" {run_diode_insertion_2_5_step ""} \ - "power_pins_insertion" {run_power_pins_insertion_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] - - if { [info exists flags_map(-save) ] } { - if { ! [info exists arg_values(-save_path)] } { - set arg_values(-save_path) "" - } - save_views -lef_path $::env(magic_result_file_tag).lef \ - -def_path $::env(CURRENT_DEF) \ - -gds_path $::env(magic_result_file_tag).gds \ - -mag_path $::env(magic_result_file_tag).mag \ - -maglef_path $::env(magic_result_file_tag).lef.mag \ - -spice_path $::env(magic_result_file_tag).spice \ - -spef_path $::env(CURRENT_SPEF) \ - -verilog_path $::env(CURRENT_NETLIST) \ - -save_path $arg_values(-save_path) \ - -tag $::env(RUN_TAG) - } - - - calc_total_runtime - save_state - generate_final_summary_report - - check_timing_violations - - puts_success "Flow Completed Without Fatal Errors." - -} - -run_flow {*}$argv
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/mpw5/config.tcl b/openlane/user_project_wrapper/mpw5/config.tcl new file mode 100644 index 0000000..e58ee59 --- /dev/null +++ b/openlane/user_project_wrapper/mpw5/config.tcl
@@ -0,0 +1,198 @@ +# SPDX-FileCopyrightText: 2020 Efabless Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# SPDX-License-Identifier: Apache-2.0 + +# Base Configurations. Don't Touch +# section begin + +set ::env(PDK) "sky130A" +set ::env(STD_CELL_LIBRARY) "sky130_fd_sc_hd" + +# YOU ARE NOT ALLOWED TO CHANGE ANY VARIABLES DEFINED IN THE FIXED WRAPPER CFGS +source $::env(CARAVEL_ROOT)/openlane/user_project_wrapper/fixed_wrapper_cfgs.tcl + + +# YOU CAN CHANGE ANY VARIABLES DEFINED IN THE DEFAULT WRAPPER CFGS BY OVERRIDING THEM IN THIS CONFIG.TCL +source $::env(CARAVEL_ROOT)/openlane/user_project_wrapper/default_wrapper_cfgs.tcl + + +set script_dir [file dirname [file normalize [info script]]] +set proj_dir [file dirname [file normalize [info script]]] + +set ::env(DESIGN_NAME) user_project_wrapper +set verilog_root $proj_dir/../../verilog/ +set lef_root $proj_dir/../../lef/ +set gds_root $proj_dir/../../gds/ +#section end + +# User Configurations +# +set ::env(DESIGN_IS_CORE) 1 +set ::env(FP_PDN_CORE_RING) 1 + + +## Source Verilog Files +set ::env(VERILOG_FILES) "\ + $proj_dir/../../verilog/rtl//yifive/ycr2c/src/top/ycr2_top_wb.sv \ + $proj_dir/../../verilog/rtl/user_project_wrapper.v" + + +## Clock configurations +set ::env(CLOCK_PORT) "user_clock2 wb_clk_i" +#set ::env(CLOCK_NET) "mprj.clk" + +set ::env(CLOCK_PERIOD) "10" + +## Internal Macros +### Macro Placement +set ::env(FP_SIZING) "absolute" +set ::env(MACRO_PLACEMENT_CFG) $proj_dir/macro.cfg + +set ::env(PDN_CFG) $proj_dir/pdn_cfg.tcl + +set ::env(SDC_FILE) "$proj_dir/base.sdc" +set ::env(BASE_SDC_FILE) "$proj_dir/base.sdc" + +set ::env(SYNTH_READ_BLACKBOX_LIB) 1 + +### Black-box verilog and views +set ::env(VERILOG_FILES_BLACKBOX) "\ + $proj_dir/../../verilog/gl/qspim_top.v \ + $proj_dir/../../verilog/gl/wb_interconnect.v \ + $proj_dir/../../verilog/gl/pinmux.v \ + $proj_dir/../../verilog/gl/uart_i2c_usb_spi_top.v \ + $proj_dir/../../verilog/gl/wb_host.v \ + $proj_dir/../../verilog/gl/ycr_intf.v \ + $proj_dir/../../verilog/gl/ycr_core_top.v \ + $proj_dir/../../verilog/gl/ycr2_iconnect.v \ + $proj_dir/../../verilog/gl/digital_pll.v \ + $::env(PDK_ROOT)/sky130A/libs.ref/sky130_sram_macros/verilog/sky130_sram_2kbyte_1rw1r_32x512_8.v \ + " + +set ::env(EXTRA_LEFS) "\ + $lef_root/qspim_top.lef \ + $lef_root/pinmux.lef \ + $lef_root/wb_interconnect.lef \ + $lef_root/uart_i2c_usb_spi_top.lef \ + $lef_root/wb_host.lef \ + $lef_root/ycr_intf.lef \ + $lef_root/ycr_core_top.lef \ + $lef_root/ycr2_iconnect.lef \ + $lef_root/digital_pll.lef \ + $::env(PDK_ROOT)/sky130A/libs.ref/sky130_sram_macros/lef/sky130_sram_2kbyte_1rw1r_32x512_8.lef \ + " + +set ::env(EXTRA_GDS_FILES) "\ + $gds_root/qspim_top.gds \ + $gds_root/pinmux.gds \ + $gds_root/wb_interconnect.gds \ + $gds_root/uart_i2c_usb_spi_top.gds \ + $gds_root/wb_host.gds \ + $gds_root/ycr_intf.gds \ + $gds_root/ycr_core_top.gds \ + $gds_root/ycr2_iconnect.gds \ + $gds_root/digital_pll.gds \ + $::env(PDK_ROOT)/sky130A/libs.ref/sky130_sram_macros/gds/sky130_sram_2kbyte_1rw1r_32x512_8.gds \ + " + +set ::env(SYNTH_DEFINES) [list SYNTHESIS ] + +set ::env(VERILOG_INCLUDE_DIRS) [glob $script_dir/../../verilog/rtl/yifive/ycr2c/src/includes ] + +#set ::env(GLB_RT_MAXLAYER) 6 +set ::env(RT_MAX_LAYER) {met5} + +set ::env(FP_PDN_CHECK_NODES) 0 + + +## Internal Macros +### Macro PDN Connections +set ::env(FP_PDN_ENABLE_MACROS_GRID) "1" +set ::env(FP_PDN_ENABLE_GLOBAL_CONNECTIONS) "1" + +set ::env(VDD_NETS) {vccd1 vccd2 vdda1 vdda2} +set ::env(GND_NETS) {vssd1 vssd2 vssa1 vssa2} +# +set ::env(VDD_PIN) {vccd1} +set ::env(GND_PIN) {vssd1} + +set ::env(GLB_RT_OBS) " \ + li1 150 130 833.1 546.54,\ + met1 150 130 833.1 546.54,\ + met2 150 130 833.1 546.54,\ + met3 150 130 833.1 546.54,\ + + li1 950 130 1633.1 546.54,\ + met1 950 130 1633.1 546.54,\ + met2 950 130 1633.1 546.54,\ + met3 950 130 1633.1 546.54,\ + + li1 150 750 833.1 1166.54,\ + met1 150 750 833.1 1166.54,\ + met2 150 750 833.1 1166.54,\ + met3 150 750 833.1 1166.54,\ + met1 950 650 1760 660 ,\ + met3 950 650 1760 660 ,\ + met5 0 0 2920 3520" + +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 \ +# " + + +# 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) "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_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/mpw5/interactive.tcl b/openlane/user_project_wrapper/mpw5/interactive.tcl new file mode 100644 index 0000000..ccfa729 --- /dev/null +++ b/openlane/user_project_wrapper/mpw5/interactive.tcl
@@ -0,0 +1,371 @@ +#!/usr/bin/tclsh +# SPDX-FileCopyrightText: 2020 Efabless Corporation +# Copyright 2020 Efabless Corporation +# Copyright 2020 Sylvain Munaut +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# 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 +} +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 +} +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 +} +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 { ($::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 } { + 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 { $drc_enabled } { + 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 { $antenna_check_enabled } { + run_antenna_check + } +} +proc run_eco_step {args} { + if { $::env(ECO_ENABLE) == 1 } { + run_eco + } +} +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(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(SPEF_TYPICAL)] } { + lappend arg_list -spef_path $::env(SPEF_TYPICAL) + } + if { [info exists ::env(CURRENT_SDF)] } { + lappend arg_list -sdf_path $::env(CURRENT_SDF) + } + 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" + set result [exec $::env(OPENROAD_BIN) -python $::env(DESIGN_DIR)/hooks/post_run.py] + puts_info "$result" + } else { + puts_info "hooks/post_run.py not found, skipping" + } +} +proc gen_pdn {args} { + puts_info "Generating PDN..." + 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(FP_PDN_POWER_STRAPS)]} { + set power_domains [split $::env(FP_PDN_POWER_STRAPS) ","] + } + # 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) ","] + 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] + 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)." + } + } + + # 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..." + # |----------------------------------------------------| + # |---------------- 2. FLOORPLAN ------------------| + # |----------------------------------------------------| + # + # 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}]] + puts_warn "You're using FP_IO_HMETAL 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_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 + } else { + if { [info exists ::env(FP_CONTEXT_DEF)] && [info exists ::env(FP_CONTEXT_LEF)] } { + place_io + global_placement_or + place_contextualized_io \ + -lef $::env(FP_CONTEXT_LEF) \ + -def $::env(FP_CONTEXT_DEF) + } else { + 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 + manual_macro_placement f + } else { + global_placement_or + 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} + {-from optional} + {-to optional} + {-save_path optional} + {-override_env optional} + } + set flags {-save -run_hooks -no_lvs -no_drc -no_antennacheck } + 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 arg_values(-override_env)] } { + set env_overrides [split $arg_values(-override_env) ','] + foreach override $env_overrides { + set kva [split $override '='] + set key [lindex $kva 0] + set value [lindex $kva 1] + 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 ""}\ + "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)] } { + set arg_values(-save_path) $::env(DESIGN_DIR) + } + save_final_views\ + -save_path $arg_values(-save_path)\ + -tag $::env(RUN_TAG) + } + calc_total_runtime + save_state + generate_final_summary_report + + check_timing_violations + + if { [info exists arg_values(-save_path)]\ + && $arg_values(-save_path) != "" } { + set ::env(HOOK_OUTPUT_PATH) "[file normalize $arg_values(-save_path)]" + } else { + set ::env(HOOK_OUTPUT_PATH) $::env(RESULTS_DIR)/final + } + + if {[info exists flags_map(-run_hooks)]} { + run_post_run_hooks + } + + puts_success "Flow complete." + show_warnings "Note that the following warnings have been generated:" +} +run_flow {*}$argv
diff --git a/openlane/user_project_wrapper/mpw5/pdn_cfg.tcl b/openlane/user_project_wrapper/mpw5/pdn_cfg.tcl new file mode 100644 index 0000000..552a90e --- /dev/null +++ b/openlane/user_project_wrapper/mpw5/pdn_cfg.tcl
@@ -0,0 +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 + } + foreach ground_pin $::env(STD_CELL_GROUND_PINS) { + add_global_connection -net $::env(GND_NET) -inst_pattern .* -pin_pattern $ground_pin -ground + } + } +} +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 [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 +} +# 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 [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 -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)}] +} +# 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/openlane/user_project_wrapper/mpw6/config.tcl b/openlane/user_project_wrapper/mpw6/config.tcl new file mode 100644 index 0000000..3826900 --- /dev/null +++ b/openlane/user_project_wrapper/mpw6/config.tcl
@@ -0,0 +1,219 @@ +# SPDX-FileCopyrightText: 2020 Efabless Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# SPDX-License-Identifier: Apache-2.0 + +# Base Configurations. Don't Touch +# section begin + +set ::env(PDK) "sky130A" +set ::env(STD_CELL_LIBRARY) "sky130_fd_sc_hd" + +# YOU ARE NOT ALLOWED TO CHANGE ANY VARIABLES DEFINED IN THE FIXED WRAPPER CFGS +source $::env(CARAVEL_ROOT)/openlane/user_project_wrapper/fixed_wrapper_cfgs.tcl + + +# YOU CAN CHANGE ANY VARIABLES DEFINED IN THE DEFAULT WRAPPER CFGS BY OVERRIDING THEM IN THIS CONFIG.TCL +source $::env(CARAVEL_ROOT)/openlane/user_project_wrapper/default_wrapper_cfgs.tcl + + +set script_dir [file dirname [file normalize [info script]]] +set proj_dir [file dirname [file normalize [info script]]] + +set ::env(DESIGN_NAME) user_project_wrapper +set verilog_root $proj_dir/../../verilog/ +set lef_root $proj_dir/../../lef/ +set gds_root $proj_dir/../../gds/ +#section end + +# User Configurations +# +set ::env(DESIGN_IS_CORE) 1 +set ::env(FP_PDN_CORE_RING) 1 + + +## Source Verilog Files +set ::env(VERILOG_FILES) "\ + $proj_dir/../../verilog/rtl//yifive/ycr2c/src/top/ycr2_top_wb.sv \ + $proj_dir/../../verilog/rtl/user_project_wrapper.v" + + +## Clock configurations +set ::env(CLOCK_PORT) "user_clock2 wb_clk_i" +#set ::env(CLOCK_NET) "mprj.clk" + +set ::env(CLOCK_PERIOD) "10" + +## Internal Macros +### Macro Placement +set ::env(FP_SIZING) "absolute" +set ::env(MACRO_PLACEMENT_CFG) $proj_dir/macro.cfg + +set ::env(PDN_CFG) $proj_dir/pdn_cfg.tcl + +set ::env(SDC_FILE) "$proj_dir/base.sdc" +set ::env(BASE_SDC_FILE) "$proj_dir/base.sdc" + +set ::env(SYNTH_READ_BLACKBOX_LIB) 1 + +### Black-box verilog and views +set ::env(VERILOG_FILES_BLACKBOX) "\ + $proj_dir/../../verilog/gl/qspim_top.v \ + $proj_dir/../../verilog/gl/wb_interconnect.v \ + $proj_dir/../../verilog/gl/pinmux.v \ + $proj_dir/../../verilog/gl/uart_i2c_usb_spi_top.v \ + $proj_dir/../../verilog/gl/wb_host.v \ + $proj_dir/../../verilog/gl/ycr_intf.v \ + $proj_dir/../../verilog/gl/ycr_core_top.v \ + $proj_dir/../../verilog/gl/ycr2_iconnect.v \ + $proj_dir/../../verilog/gl/digital_pll.v \ + $::env(PDK_ROOT)/sky130A/libs.ref/sky130_sram_macros/verilog/sky130_sram_2kbyte_1rw1r_32x512_8.v \ + " + +set ::env(EXTRA_LEFS) "\ + $lef_root/qspim_top.lef \ + $lef_root/pinmux.lef \ + $lef_root/wb_interconnect.lef \ + $lef_root/uart_i2c_usb_spi_top.lef \ + $lef_root/wb_host.lef \ + $lef_root/ycr_intf.lef \ + $lef_root/ycr_core_top.lef \ + $lef_root/ycr2_iconnect.lef \ + $lef_root/digital_pll.lef \ + $::env(PDK_ROOT)/sky130A/libs.ref/sky130_sram_macros/lef/sky130_sram_2kbyte_1rw1r_32x512_8.lef \ + " + +set ::env(EXTRA_GDS_FILES) "\ + $gds_root/qspim_top.gds \ + $gds_root/pinmux.gds \ + $gds_root/wb_interconnect.gds \ + $gds_root/uart_i2c_usb_spi_top.gds \ + $gds_root/wb_host.gds \ + $gds_root/ycr_intf.gds \ + $gds_root/ycr_core_top.gds \ + $gds_root/ycr2_iconnect.gds \ + $gds_root/digital_pll.gds \ + $::env(PDK_ROOT)/sky130A/libs.ref/sky130_sram_macros/gds/sky130_sram_2kbyte_1rw1r_32x512_8.gds \ + " + +set ::env(SYNTH_DEFINES) [list SYNTHESIS ] + +set ::env(VERILOG_INCLUDE_DIRS) [glob $script_dir/../../verilog/rtl/yifive/ycr2c/src/includes ] + +#set ::env(GLB_RT_MAXLAYER) 6 +set ::env(RT_MAX_LAYER) {met5} + +set ::env(FP_PDN_CHECK_NODES) 0 + + +## Internal Macros +### Macro PDN Connections +set ::env(FP_PDN_ENABLE_MACROS_GRID) "1" +set ::env(FP_PDN_ENABLE_GLOBAL_CONNECTIONS) "1" + +set ::env(VDD_NETS) {vccd1 vccd2 vdda1 vdda2} +set ::env(GND_NETS) {vssd1 vssd2 vssa1 vssa2} +# +set ::env(VDD_PIN) {vccd1} +set ::env(GND_PIN) {vssd1} + +set ::env(GLB_RT_OBS) " \ + li1 150 130 833.1 546.54,\ + met1 150 130 833.1 546.54,\ + met2 150 130 833.1 546.54,\ + met3 150 130 833.1 546.54,\ + + li1 950 130 1633.1 546.54,\ + met1 950 130 1633.1 546.54,\ + met2 950 130 1633.1 546.54,\ + met3 950 130 1633.1 546.54,\ + + li1 150 750 833.1 1166.54,\ + met1 150 750 833.1 1166.54,\ + met2 150 750 833.1 1166.54,\ + met3 150 750 833.1 1166.54,\ + met1 950 650 1760 660 ,\ + met3 950 650 1760 660 ,\ + met5 0 0 2920 3520" + +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 \ + " + + +# 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) "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/mpw6/interactive.tcl b/openlane/user_project_wrapper/mpw6/interactive.tcl new file mode 100644 index 0000000..07190b7 --- /dev/null +++ b/openlane/user_project_wrapper/mpw6/interactive.tcl
@@ -0,0 +1,456 @@ +#!/usr/bin/tclsh +# SPDX-FileCopyrightText: 2020 Efabless Corporation +# Copyright 2020 Efabless Corporation +# Copyright 2020 Sylvain Munaut +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# 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 +} + +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 +} + +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 +} + +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 { ($::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; + 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 { $drc_enabled } { + if { $::env(RUN_MAGIC_DRC) } { + run_magic_drc + } + if {$::env(RUN_KLAYOUT_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 { $antenna_check_enabled } { + run_antenna_check + } +} + +proc run_eco_step {args} { + if { $::env(ECO_ENABLE) == 1 } { + run_eco_flow + } +} + +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 + + # 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(CURRENT_SDF)] } { + lappend arg_list -sdf_path $::env(CURRENT_SDF) + } + 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" + set result [exec $::env(OPENROAD_BIN) -python $::env(DESIGN_DIR)/hooks/post_run.py] + puts_info "$result" + } else { + 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] + + 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) + } + + 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 + if {[info exists ::env(FP_PDN_MACRO_HOOKS)]} { + set macro_hooks [dict create] + 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] + 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)." + } + } + + gen_pdn +} + +proc run_floorplan {args} { + puts_info "Running Floorplanning..." + # |----------------------------------------------------| + # |---------------- 2. FLOORPLAN ------------------| + # |----------------------------------------------------| + # + # 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}]] + puts_warn "You're using FP_IO_HMETAL 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_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 + } else { + if { [info exists ::env(FP_CONTEXT_DEF)] && [info exists ::env(FP_CONTEXT_LEF)] } { + place_io + global_placement_or + place_contextualized_io \ + -lef $::env(FP_CONTEXT_LEF) \ + -def $::env(FP_CONTEXT_DEF) + } else { + 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 + manual_macro_placement f + } else { + global_placement_or + 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} + {-from optional} + {-to optional} + {-save_path optional} + {-override_env optional} + } + set flags {-save -run_hooks -no_lvs -no_drc -no_antennacheck } + 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 { + set kva [split $override '='] + set key [lindex $kva 0] + set value [lindex $kva 1] + 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_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)] } { + set arg_values(-save_path) $::env(DESIGN_DIR) + } + save_final_views\ + -save_path $arg_values(-save_path)\ + -tag $::env(RUN_TAG) + } + calc_total_runtime + save_state + generate_final_summary_report + + check_timing_violations + + if { [info exists arg_values(-save_path)]\ + && $arg_values(-save_path) != "" } { + set ::env(HOOK_OUTPUT_PATH) "[file normalize $arg_values(-save_path)]" + } else { + set ::env(HOOK_OUTPUT_PATH) $::env(RESULTS_DIR)/final + } + + if {[info exists flags_map(-run_hooks)]} { + run_post_run_hooks + } + + puts_success "Flow complete." + + show_warnings "Note that the following warnings have been generated:" + +} + +run_flow {*}$argv
diff --git a/openlane/user_project_wrapper/mpw6/pdn_cfg.tcl b/openlane/user_project_wrapper/mpw6/pdn_cfg.tcl new file mode 100644 index 0000000..1bd5f1e --- /dev/null +++ b/openlane/user_project_wrapper/mpw6/pdn_cfg.tcl
@@ -0,0 +1,165 @@ +# 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) +} + +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 + } + foreach ground_pin $::env(STD_CELL_GROUND_PINS) { + 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 +# 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)" +} 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 +} + +# 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)" +} + + +# 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)" +} + +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)"
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/openlane/wb_host/config.tcl b/openlane/wb_host/config.tcl index 0d8ff81..4116b09 100755 --- a/openlane/wb_host/config.tcl +++ b/openlane/wb_host/config.tcl
@@ -109,5 +109,5 @@ set ::env(PL_RESIZER_DESIGN_OPTIMIZATIONS) "1" set ::env(QUIT_ON_TIMING_VIOLATIONS) "0" set ::env(QUIT_ON_MAGIC_DRC) "1" -set ::env(QUIT_ON_LVS_ERROR) "0" +set ::env(QUIT_ON_LVS_ERROR) "1" set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
diff --git a/openlane/wb_interconnect/config.tcl b/openlane/wb_interconnect/config.tcl index 33ac3c6..55b38f4 100755 --- a/openlane/wb_interconnect/config.tcl +++ b/openlane/wb_interconnect/config.tcl
@@ -119,7 +119,7 @@ set ::env(QUIT_ON_TIMING_VIOLATIONS) "0" set ::env(QUIT_ON_MAGIC_DRC) "1" -set ::env(QUIT_ON_LVS_ERROR) "0" +set ::env(QUIT_ON_LVS_ERROR) "1" set ::env(QUIT_ON_SLEW_VIOLATIONS) "0" set ::env(GLB_RESIZER_TIMING_OPTIMIZATIONS) "0"
diff --git a/openlane/ycr2_iconnect/config.tcl b/openlane/ycr2_iconnect/config.tcl index 389847d..cf9debf 100644 --- a/openlane/ycr2_iconnect/config.tcl +++ b/openlane/ycr2_iconnect/config.tcl
@@ -94,7 +94,7 @@ set ::env(QUIT_ON_TIMING_VIOLATIONS) "0" set ::env(QUIT_ON_MAGIC_DRC) "1" -set ::env(QUIT_ON_LVS_ERROR) "0" +set ::env(QUIT_ON_LVS_ERROR) "1" set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
diff --git a/openlane/ycr_core_top/config.tcl b/openlane/ycr_core_top/config.tcl index 161152f..70e8196 100644 --- a/openlane/ycr_core_top/config.tcl +++ b/openlane/ycr_core_top/config.tcl
@@ -88,7 +88,7 @@ set ::env(QUIT_ON_TIMING_VIOLATIONS) "0" set ::env(QUIT_ON_MAGIC_DRC) "1" -set ::env(QUIT_ON_LVS_ERROR) "0" +set ::env(QUIT_ON_LVS_ERROR) "1" set ::env(QUIT_ON_SLEW_VIOLATIONS) "0" #Need to cross-check why global timing opimization creating setup vio with hugh hold fix
diff --git a/openlane/ycr_intf/config.tcl b/openlane/ycr_intf/config.tcl index 8e583e5..2ef0b86 100644 --- a/openlane/ycr_intf/config.tcl +++ b/openlane/ycr_intf/config.tcl
@@ -81,7 +81,7 @@ set ::env(QUIT_ON_TIMING_VIOLATIONS) "0" set ::env(QUIT_ON_MAGIC_DRC) "1" -set ::env(QUIT_ON_LVS_ERROR) "0" +set ::env(QUIT_ON_LVS_ERROR) "1" set ::env(QUIT_ON_SLEW_VIOLATIONS) "0" #Need to cross-check why global timing opimization creating setup vio with hugh hold fix
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 330ed0a..d4326b1 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,0h48m46s0ms,0h3m41s0ms,-2.0,-1,-1,-1,575.41,12,0,0,0,0,0,0,-1,0,0,-1,-1,1408320,10261,0.0,-1,-1,0.0,0.0,0.0,-1,-1,0.0,0.0,-1,0.0,5.31,6.28,1.5,2.1,0.0,349,3687,349,3687,0,0,0,12,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_dcore/openlane/user_project_wrapper,user_project_wrapper,user_project_wrapper,flow completed,1h43m41s0ms,0h4m1s0ms,-2.0,-1,-1,-1,594.3,13,0,0,0,0,0,0,-1,0,0,-1,-1,1415412,10457,0.0,-1,-1,0.0,0.0,0.0,-1,-1,0.0,0.0,-1,0.0,5.37,6.22,1.45,2.47,0.0,367,3710,367,3710,0,0,0,13,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