add creating `.lib` for the design at the end of the STA run

add all process corners liberties for the IO cells
update spef mapping based on the updated instances names in the top-level caravel
This commit is contained in:
Passant 2022-10-10 15:46:41 -07:00
parent ddbf9a15df
commit b3f69ba769
2 changed files with 128 additions and 45 deletions

View File

@ -1,47 +1,89 @@
##PT script ##PT script
set link_path "* $::env(PT_LIB_ROOT)/scs130hvl_tt_3.3v_25C.lib \
$::env(PT_LIB_ROOT)/scs130hvl_tt_3.3v_lowhv_3.3v_lv_1.8v_25C.lib \ # Adding SCL and IO link libraries based on the process corner specified
$::env(PT_LIB_ROOT)/s8iom0s8_top_gpiov2_tt_tt_1p80v_x_3p30v_025C.lib \
$::env(PT_LIB_ROOT)/s8iom0s8_top_ground_hvc_wpad_tt_1.80v_3.30v_3.30v_025C.lib \
$::env(PT_LIB_ROOT)/s8iom0s8_top_ground_lvc_wpad_tt_1.80v_3.30v_025C.lib \
$::env(PT_LIB_ROOT)/s8iom0s8_top_power_lvc_wpad_tt_1.80v_3.30v_3.30v_025C.lib \
$::env(PT_LIB_ROOT)/s8iom0s8_top_xres4v2_tt_tt_1p80v_x_3p30v_025C.lib \
$::env(PT_LIB_ROOT)/simple_por.lib \
$::env(PT_LIB_ROOT)/sky130_ef_io__corner_pad.lib \
$::env(PT_LIB_ROOT)/spare_logic_block.lib \
$::env(PT_LIB_ROOT)/sky130_sram_2kbyte_1rw1r_32x512_8_TT_1p8V_25C.lib \
"
if {$::env(PROC_CORNER) == "t"} { if {$::env(PROC_CORNER) == "t"} {
append link_path "$::env(PT_LIB_ROOT)/scs130hd_tt_1.80v_25C.lib" set link_path "* $::env(PT_LIB_ROOT)/scs130hd_tt_1.80v_25C.lib \
$::env(PT_LIB_ROOT)/scs130hvl_tt_3.3v_25C.lib \
$::env(PT_LIB_ROOT)/scs130hvl_tt_3.3v_lowhv_3.3v_lv_1.8v_25C.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_fd_io__top_xres4v2_tt_tt_025C_1v80_3v30.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__gpiov2_pad_tt_tt_025C_1v80_3v30.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vccd_lvc_clamped_pad_tt_025C_1v80_3v30_3v30.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vdda_hvc_clamped_pad_tt_025C_1v80_3v30_3v30.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vssa_hvc_clamped_pad_tt_025C_1v80_3v30_3v30.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vssd_lvc_clamped3_pad_tt_025C_1v80_3v30.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vccd_lvc_clamped3_pad_tt_025C_1v80_3v30_3v30.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vssd_lvc_clamped_pad_tt_025C_1v80_3v30.lib \
"
} elseif {$::env(PROC_CORNER) == "f"} { } elseif {$::env(PROC_CORNER) == "f"} {
append link_path "$::env(PT_LIB_ROOT)/scs130hd_ff_1.95v_-40C.lib" set link_path "* $::env(PT_LIB_ROOT)/scs130hd_ff_1.95v_-40C.lib \
$::env(PT_LIB_ROOT)/scs130hvl_ff_5.5v_-40C.lib \
$::env(PT_LIB_ROOT)/scs130hvl_ff_5.5v_lowhv_5.5v_lv_1.95v_-40C.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_fd_io__top_xres4v2_ff_ff_n40C_1v95_5v50.lib.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__gpiov2_pad_wrapped_ff_ff_n40C_1v95_5v50.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vccd_lvc_clamped_pad_ff_n40C_1v95_5v50_5v50.lib.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vdda_hvc_clamped_pad_ff_n40C_1v95_5v50_5v50.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vssa_hvc_clamped_pad_ff_n40C_1v95_5v50_5v50.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vssd_lvc_clamped3_pad_ff_n40C_1v95_5v50.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vccd_lvc_clamped3_pad_ff_n40C_1v95_5v50_5v50.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vssd_lvc_clamped_pad_ff_n40C_1v95_5v50.lib \
"
} elseif {$::env(PROC_CORNER) == "s"} { } elseif {$::env(PROC_CORNER) == "s"} {
append link_path "$::env(PT_LIB_ROOT)/scs130hd_ss_1.40v_100C.lib" set link_path "* $::env(PT_LIB_ROOT)/scs130hd_ss_1.40v_100C.lib \
$::env(PT_LIB_ROOT)/scs130hvl_ss_3.00v_100C.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_fd_io__top_xres4v2_ss_ss_100C_1v60_3v00.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__gpiov2_pad_wrapped_ss_ss_100C_1v60_3v00.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vccd_lvc_clamped_pad_ss_100C_1v60_3v00_3v00.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vdda_hvc_clamped_pad_ss_100C_1v60_3v00_3v00.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vssa_hvc_clamped_pad_ss_100C_1v60_3v00_3v00.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vssd_lvc_clamped3_pad_ss_100C_1v60_3v00.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vccd_lvc_clamped3_pad_ss_100C_1v60_3v00_3v00.lib \
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vssd_lvc_clamped_pad_ss_100C_1v60_3v00.lib \
"
} }
# Reading design netlist
# TODO: get chip io netlist instead of reading the RTL
set search_path "$::env(CARAVEL_ROOT)/verilog/gl $::env(MCW_ROOT)/verilog/gl $::env(PT_LIB_ROOT)" set search_path "$::env(CARAVEL_ROOT)/verilog/gl $::env(MCW_ROOT)/verilog/gl $::env(PT_LIB_ROOT)"
foreach verilog "[glob $::env(CARAVEL_ROOT)/verilog/gl/*.v] [glob $::env(MCW_ROOT)/verilog/gl/*.v]" { foreach verilog "[glob $::env(CARAVEL_ROOT)/verilog/gl/*.v] [glob $::env(MCW_ROOT)/verilog/gl/*.v]" {
puts "list of .v: $verilog" if {$verilog != "$::env(CARAVEL_ROOT)/verilog/gl/chip_io.v"} {
read_verilog $verilog read_verilog $verilog
}
} }
read_verilog $::env(CARAVEL_ROOT)/verilog/rtl/defines.v
read_verilog $::env(CARAVEL_ROOT)/verilog/rtl/mprj_io.v
read_verilog $::env(CARAVEL_ROOT)/verilog/rtl/chip_io.v
current_design $::env(DESIGN) current_design $::env(DESIGN)
link link
read_sdc $::env(CARAVEL_ROOT)/openlane/$::env(DESIGN)/signoff.sdc
# Reading constraints (signoff)
if {$::env(DESIGN) == "mgmt_core_wrapper"} {
read_sdc $::env(MCW_ROOT)/openlane/$::env(DESIGN)/signoff.sdc
} else {
read_sdc $::env(CARAVEL_ROOT)/openlane/$::env(DESIGN)/signoff.sdc
}
# Reading parasitics based on the RC corner specified
proc read_spefs {design rc_corner} { proc read_spefs {design rc_corner} {
set spef_mapping(rstb_level) $::env(CARAVEL_ROOT)/spef/multicorner/xres_buf.${rc_corner}.spef set spef_mapping(rstb_level) $::env(CARAVEL_ROOT)/spef/multicorner/xres_buf.${rc_corner}.spef
set spef_mapping(padframe) $::env(CARAVEL_ROOT)/spef/multicorner/chip_io.${rc_corner}.spef set spef_mapping(padframe) $::env(CARAVEL_ROOT)/spef/multicorner/chip_io.${rc_corner}.spef
set spef_mapping(housekeeping) $::env(CARAVEL_ROOT)/spef/multicorner/housekeeping.${rc_corner}.spef set spef_mapping(housekeeping) $::env(CARAVEL_ROOT)/spef/multicorner/housekeeping.${rc_corner}.spef
set spef_mapping(mgmt_buffers) $::env(CARAVEL_ROOT)/spef/multicorner/mgmt_protect.${rc_corner}.spef
set spef_mapping(pll) $::env(CARAVEL_ROOT)/spef/multicorner/digital_pll.${rc_corner}.spef set spef_mapping(pll) $::env(CARAVEL_ROOT)/spef/multicorner/digital_pll.${rc_corner}.spef
set spef_mapping(clocking) $::env(CARAVEL_ROOT)/spef/multicorner/caravel_clocking.${rc_corner}.spef set spef_mapping(clock_ctrl) $::env(CARAVEL_ROOT)/spef/multicorner/caravel_clocking.${rc_corner}.spef
set spef_mapping(mgmt_buffers) $::env(CARAVEL_ROOT)/spef/multicorner/mgmt_protect.${rc_corner}.spef
set spef_mapping(mgmt_buffers/powergood_check) $::env(CARAVEL_ROOT)/spef/multicorner/mgmt_protect_hv.${rc_corner}.spef set spef_mapping(mgmt_buffers/powergood_check) $::env(CARAVEL_ROOT)/spef/multicorner/mgmt_protect_hv.${rc_corner}.spef
set spef_mapping(powergood_check) $::env(CARAVEL_ROOT)/spef/multicorner/mgmt_protect_hv.${rc_corner}.spef
set spef_mapping(mgmt_buffers/mprj_logic_high_inst) $::env(CARAVEL_ROOT)/spef/multicorner/mprj_logic_high.${rc_corner}.spef set spef_mapping(mgmt_buffers/mprj_logic_high_inst) $::env(CARAVEL_ROOT)/spef/multicorner/mprj_logic_high.${rc_corner}.spef
set spef_mapping(mprj_logic_high_inst) $::env(CARAVEL_ROOT)/spef/multicorner/mprj_logic_high.${rc_corner}.spef
set spef_mapping(mgmt_buffers/mprj2_logic_high_inst) $::env(CARAVEL_ROOT)/spef/multicorner/mprj2_logic_high.${rc_corner}.spef
set spef_mapping(mprj2_logic_high_inst) $::env(CARAVEL_ROOT)/spef/multicorner/mprj2_logic_high.${rc_corner}.spef
set spef_mapping(soc) $::env(MCW_ROOT)/spef/multicorner/mgmt_core_wrapper.${rc_corner}.spef set spef_mapping(soc) $::env(MCW_ROOT)/spef/multicorner/mgmt_core_wrapper.${rc_corner}.spef
set spef_mapping(soc/DFFRAM_0) $::env(MCW_ROOT)/spef/multicorner/DFFRAM.${rc_corner}.spef set spef_mapping(soc/\core.DFFRAM) $::env(MCW_ROOT)/spef/multicorner/DFFRAM.${rc_corner}.spef
set spef_mapping(soc/core) $::env(MCW_ROOT)/spef/multicorner/mgmt_core.${rc_corner}.spef set spef_mapping(\core.DFFRAM) $::env(MCW_ROOT)/spef/multicorner/DFFRAM.${rc_corner}.spef
set spef_mapping(soc/\core.DFFRAM_512) $::env(MCW_ROOT)/spef/multicorner/DFFRAM_512.${rc_corner}.spef
set spef_mapping(\core.DFFRAM_512) $::env(MCW_ROOT)/spef/multicorner/DFFRAM_512.${rc_corner}.spef
set spef_mapping(gpio_logic_high) $::env(CARAVEL_ROOT)/spef/multicorner/gpio_logic_high.${rc_corner}.spef
set spef_mapping(\gpio_control_bidir_1[0]/gpio_logic_high) $::env(CARAVEL_ROOT)/spef/multicorner/gpio_logic_high.${rc_corner}.spef set spef_mapping(\gpio_control_bidir_1[0]/gpio_logic_high) $::env(CARAVEL_ROOT)/spef/multicorner/gpio_logic_high.${rc_corner}.spef
set spef_mapping(\gpio_control_bidir_1[1]/gpio_logic_high) $::env(CARAVEL_ROOT)/spef/multicorner/gpio_logic_high.${rc_corner}.spef set spef_mapping(\gpio_control_bidir_1[1]/gpio_logic_high) $::env(CARAVEL_ROOT)/spef/multicorner/gpio_logic_high.${rc_corner}.spef
set spef_mapping(\gpio_control_bidir_2[0]/gpio_logic_high) $::env(CARAVEL_ROOT)/spef/multicorner/gpio_logic_high.${rc_corner}.spef set spef_mapping(\gpio_control_bidir_2[0]/gpio_logic_high) $::env(CARAVEL_ROOT)/spef/multicorner/gpio_logic_high.${rc_corner}.spef
@ -161,38 +203,55 @@ proc read_spefs {design rc_corner} {
foreach key [array names spef_mapping] { foreach key [array names spef_mapping] {
read_parasitics -path $key $spef_mapping($key) read_parasitics -path $key $spef_mapping($key)
} }
read_parasitics -verbose $::env(CARAVEL_ROOT)/spef/multicorner/$::env(DESIGN).${rc_corner}.spef -pin_cap_included if {$design == "mgmt_core_wrapper"} {
read_parasitics -verbose $::env(MCW_ROOT)/spef/multicorner/$::env(DESIGN).${rc_corner}.spef -pin_cap_included
} else {
read_parasitics -verbose $::env(CARAVEL_ROOT)/spef/multicorner/$::env(DESIGN).${rc_corner}.spef -pin_cap_included
}
} }
proc report_results {design rc_corner proc_corner} { proc report_results {design rc_corner proc_corner} {
report_constraint -all_violators -significant_digits 4 -nosplit > $::env(OUT_DIR)/pt_reports/${design}-${rc_corner}-${proc_corner}-all_viol.rpt report_constraint -all_violators -significant_digits 4 -nosplit > $::env(OUT_DIR)/pt_reports/${design}/${design}-${rc_corner}-${proc_corner}-all_viol.rpt
report_timing -delay min -path_type full_clock_expanded -transition_time -capacitance -nets -nosplit \ report_timing -delay min -path_type full_clock_expanded -transition_time -capacitance -nets -nosplit \
-max_paths 1000 -nworst 10 -slack_lesser_than 100 -significant_digits 4 -include_hierarchical_pins > $::env(OUT_DIR)/pt_reports/${design}-${rc_corner}-${proc_corner}-min_timing.rpt -max_paths 1000 -nworst 10 -slack_lesser_than 100 -significant_digits 4 -include_hierarchical_pins > $::env(OUT_DIR)/pt_reports/${design}/${design}-${rc_corner}-${proc_corner}-min_timing.rpt
report_timing -delay max -path_type full_clock_expanded -transition_time -capacitance -nets -nosplit \ report_timing -delay max -path_type full_clock_expanded -transition_time -capacitance -nets -nosplit \
-max_paths 1000 -nworst 10 -slack_lesser_than 100 -significant_digits 4 -include_hierarchical_pins > $::env(OUT_DIR)/pt_reports/${design}-${rc_corner}-${proc_corner}-max_timing.rpt -max_paths 1000 -nworst 10 -slack_lesser_than 100 -significant_digits 4 -include_hierarchical_pins > $::env(OUT_DIR)/pt_reports/${design}/${design}-${rc_corner}-${proc_corner}-max_timing.rpt
if {$design == "caravel"} { if {$design == "caravel"} {
report_timing -delay min -path_type full_clock_expanded -transition_time -capacitance -nets -nosplit -group clk \ report_timing -delay min -path_type full_clock_expanded -transition_time -capacitance -nets -nosplit -group clk \
-max_paths 1000 -nworst 10 -slack_lesser_than 100 -significant_digits 4 -include_hierarchical_pins > $::env(OUT_DIR)/pt_reports/${design}-${rc_corner}-${proc_corner}-clk-min_timing.rpt -max_paths 1000 -nworst 10 -slack_lesser_than 100 -significant_digits 4 -include_hierarchical_pins > $::env(OUT_DIR)/pt_reports/${design}/${design}-${rc_corner}-${proc_corner}-clk-min_timing.rpt
report_timing -delay min -path_type full_clock_expanded -transition_time -capacitance -nets -nosplit -group hk_serial_clk \ report_timing -delay min -path_type full_clock_expanded -transition_time -capacitance -nets -nosplit -group hk_serial_clk \
-max_paths 1000 -nworst 10 -slack_lesser_than 100 -significant_digits 4 -include_hierarchical_pins > $::env(OUT_DIR)/pt_reports/${design}-${rc_corner}-${proc_corner}-hk_serial_clk-min_timing.rpt -max_paths 1000 -nworst 10 -slack_lesser_than 100 -significant_digits 4 -include_hierarchical_pins > $::env(OUT_DIR)/pt_reports/${design}/${design}-${rc_corner}-${proc_corner}-hk_serial_clk-min_timing.rpt
report_timing -delay max -path_type full_clock_expanded -transition_time -capacitance -nets -nosplit -group hk_serial_clk \ report_timing -delay max -path_type full_clock_expanded -transition_time -capacitance -nets -nosplit -group hk_serial_clk \
-max_paths 1000 -nworst 10 -slack_lesser_than 100 -significant_digits 4 -include_hierarchical_pins > $::env(OUT_DIR)/pt_reports/${design}-${rc_corner}-${proc_corner}-hk_serial_clk-max_timing.rpt -max_paths 1000 -nworst 10 -slack_lesser_than 100 -significant_digits 4 -include_hierarchical_pins > $::env(OUT_DIR)/pt_reports/${design}/${design}-${rc_corner}-${proc_corner}-hk_serial_clk-max_timing.rpt
report_timing -delay min -path_type full_clock_expanded -transition_time -capacitance -nets -nosplit -group hkspi_clk \ report_timing -delay min -path_type full_clock_expanded -transition_time -capacitance -nets -nosplit -group hkspi_clk \
-max_paths 1000 -nworst 10 -slack_lesser_than 100 -significant_digits 4 -include_hierarchical_pins > $::env(OUT_DIR)/pt_reports/${design}-${rc_corner}-${proc_corner}-hkspi_clk-min_timing.rpt -max_paths 1000 -nworst 10 -slack_lesser_than 100 -significant_digits 4 -include_hierarchical_pins > $::env(OUT_DIR)/pt_reports/${design}/${design}-${rc_corner}-${proc_corner}-hkspi_clk-min_timing.rpt
report_timing -delay min -through [get_cells soc] -path_type full_clock_expanded -transition_time -capacitance -nets -nosplit \ report_timing -delay min -through [get_cells soc] -path_type full_clock_expanded -transition_time -capacitance -nets -nosplit \
-max_paths 1000 -nworst 10 -slack_lesser_than 100 -significant_digits 4 -include_hierarchical_pins > $::env(OUT_DIR)/pt_reports/${design}-${rc_corner}-${proc_corner}-soc-min_timing.rpt -max_paths 1000 -nworst 10 -slack_lesser_than 100 -significant_digits 4 -include_hierarchical_pins > $::env(OUT_DIR)/pt_reports/${design}/${design}-${rc_corner}-${proc_corner}-soc-min_timing.rpt
report_timing -delay max -through [get_cells soc] -path_type full_clock_expanded -transition_time -capacitance -nets -nosplit \ report_timing -delay max -through [get_cells soc] -path_type full_clock_expanded -transition_time -capacitance -nets -nosplit \
-max_paths 1000 -nworst 10 -slack_lesser_than 100 -significant_digits 4 -include_hierarchical_pins > $::env(OUT_DIR)/pt_reports/${design}-${rc_corner}-${proc_corner}-soc-max_timing.rpt -max_paths 1000 -nworst 10 -slack_lesser_than 100 -significant_digits 4 -include_hierarchical_pins > $::env(OUT_DIR)/pt_reports/${design}/${design}-${rc_corner}-${proc_corner}-soc-max_timing.rpt
} }
write_sdf -version 3.0 -significant_digits 4 $::env(OUT_DIR)/pt_sdf/${design}-${rc_corner}-${proc_corner}.sdf write_sdf -version 3.0 -significant_digits 4 $::env(OUT_DIR)/pt_sdf/${design}/${design}-${rc_corner}-${proc_corner}.sdf
# Extract timing model
set extract_model_clock_transition_limit 0.75
set extract_model_data_transition_limit 0.75
set_app_var extract_model_capacitance_limit 1.0
set extract_model_num_capacitance_points 7
set extract_model_num_clock_transition_points 7
set extract_model_num_data_transition_points 7
set extract_model_use_conservative_current_slew true
set extract_model_enable_report_delay_calculation true
set extract_model_with_clock_latency_arcs true
extract_model -output $::env(OUT_DIR)/pt_etm/${design}/${design}-${rc_corner}-${proc_corner} -format {db lib} -test_design
} }
read_spefs $::env(DESIGN) $::env(RC_CORNER) read_spefs $::env(DESIGN) $::env(RC_CORNER)

View File

@ -28,6 +28,8 @@ def run_sta (
# Enviornment Variables # Enviornment Variables
check_env_vars() check_env_vars()
os.environ["PDK_ROOT"] = os.getenv('PDK_ROOT')
os.environ["PDK"] = os.getenv('PDK')
os.environ["PT_LIB_ROOT"] = os.getenv('PT_LIB_ROOT') os.environ["PT_LIB_ROOT"] = os.getenv('PT_LIB_ROOT')
os.environ["CARAVEL_ROOT"] = os.getenv('CARAVEL_ROOT') os.environ["CARAVEL_ROOT"] = os.getenv('CARAVEL_ROOT')
os.environ["MCW_ROOT"] = os.getenv('MCW_ROOT') os.environ["MCW_ROOT"] = os.getenv('MCW_ROOT')
@ -39,25 +41,35 @@ def run_sta (
# PrimeTime command # PrimeTime command
PT_tcl = f"{SCRIPT_DIR}/pt_sta.tcl" PT_tcl = f"{SCRIPT_DIR}/pt_sta.tcl"
pt_command = f"source /tools/bashrc_snps; pt_shell -f {PT_tcl} -output_log_file {log_dir}/{design}-{rc_corner}-{proc_corner}-sta.log" pt_command = f"source /tools/bashrc_snps; pt_shell -f {PT_tcl} -output_log_file {log_dir}/{design}/{design}-{rc_corner}-{proc_corner}-sta.log"
os.system(pt_command) os.system(pt_command)
# Check if there exists any violations # Check if there exists any violations
sta_pass=search_viol(f"{output_dir}/pt_reports/{design}-{rc_corner}-{proc_corner}-all_viol.rpt") sta_pass=search_viol(f"{output_dir}/pt_reports/{design}/{design}-{rc_corner}-{proc_corner}-all_viol.rpt")
if sta_pass == "pass": if sta_pass == "pass":
print (f"STA run passed!") print (f"STA run passed!")
else: else:
print (f"STA run failed!") print (f"STA run failed!")
if sta_pass == "viol": if sta_pass == "viol":
print(f"There are violations. check report: {output_dir}/pt_reports/{design}-{rc_corner}-{proc_corner}-all_viol.rpt") print(f"There are violations. check report: {output_dir}/pt_reports/{design}/{design}-{rc_corner}-{proc_corner}-all_viol.rpt")
else: else:
print(f"Linking failed. check log: {log_dir}/{design}-{rc_corner}-{proc_corner}-sta.log") print(f"Linking failed. check log: {log_dir}/{design}/{design}-{rc_corner}-{proc_corner}-sta.log")
# Check the required env variables # Check the required env variables
def check_env_vars(): def check_env_vars():
pdk_root = os.getenv('PDK_ROOT')
pdk = os.getenv('PDK')
pt_lib_root = os.getenv('PT_LIB_ROOT') pt_lib_root = os.getenv('PT_LIB_ROOT')
caravel_root = os.getenv('CARAVEL_ROOT') caravel_root = os.getenv('CARAVEL_ROOT')
mcw_root = os.getenv('MCW_ROOT') mcw_root = os.getenv('MCW_ROOT')
if pdk_root is None:
raise FileNotFoundError(
"Please export PDK_ROOT to the PDK path"
)
if pdk is None:
raise FileNotFoundError(
"Please export PDK to either sky130A or sky130B"
)
if pt_lib_root is None: if pt_lib_root is None:
raise FileNotFoundError( raise FileNotFoundError(
"Please export PT_LIB_ROOT to the PrimeTime liberties path" "Please export PT_LIB_ROOT to the PrimeTime liberties path"
@ -143,18 +155,30 @@ if __name__ == "__main__":
except FileExistsError: except FileExistsError:
# directory already exists # directory already exists
pass pass
try: try:
os.makedirs(os.path.join(output,"pt_reports")) os.makedirs(log)
except FileExistsError:
# directory already exists
pass
try:
os.makedirs(os.path.join(log,args.design))
except FileExistsError: except FileExistsError:
# directory already exists # directory already exists
pass pass
try: sub_dirs = ['pt_reports', 'pt_sdf', 'pt_etm']
os.makedirs(os.path.join(output,"pt_sdf")) for item in sub_dirs:
except FileExistsError: path = os.path.join(output,item)
# directory already exists try:
pass os.makedirs(path)
except FileExistsError:
# directory already exists
pass
try:
os.makedirs(os.path.join(path,args.design))
except FileExistsError:
# directory already exists
pass
if args.all: if args.all:
run_sta_all (args.design, output, log) run_sta_all (args.design, output, log)