294 lines
10 KiB
Tcl
294 lines
10 KiB
Tcl
# Test operating conditions, scale factors, and multi-corner features.
|
|
# Targets:
|
|
# Liberty.cc: findOperatingConditions, defaultOperatingConditions,
|
|
# scaleFactor (all overloads), addScaleFactors, findScaleFactors,
|
|
# inverters(), buffers(), makeCornerMap, setDelayModelType,
|
|
# findLibertyCellsMatching, findLibertyPortsMatching,
|
|
# ocvArcDepth, defaultOcvDerate, supplyVoltage, supplyExists,
|
|
# slewDerateFromLibrary, input/output/slewThresholds,
|
|
# defaultMaxFanout/Slew/Capacitance, defaultFanoutLoad,
|
|
# defaultIntrinsic, defaultPinResistance, footprint
|
|
# LibertyReader.cc: operating_conditions, scale_factors visitor paths
|
|
# EquivCells.cc: EquivCells constructor with map_libs path
|
|
source ../../test/helpers.tcl
|
|
|
|
############################################################
|
|
# Read Nangate45 library - has operating conditions
|
|
############################################################
|
|
read_liberty ../../test/nangate45/Nangate45_typ.lib
|
|
puts "PASS: read Nangate45_typ"
|
|
|
|
set lib [sta::find_liberty NangateOpenCellLibrary]
|
|
|
|
############################################################
|
|
# Operating conditions queries
|
|
############################################################
|
|
set op_cond [$lib find_operating_conditions typical]
|
|
if { $op_cond != "NULL" } {
|
|
puts "PASS: find_operating_conditions typical found"
|
|
} else {
|
|
puts "INFO: no operating_conditions named typical"
|
|
}
|
|
|
|
set def_op [$lib default_operating_conditions]
|
|
if { $def_op != "NULL" } {
|
|
puts "PASS: default_operating_conditions found"
|
|
} else {
|
|
puts "INFO: no default operating conditions"
|
|
}
|
|
|
|
############################################################
|
|
# Set operating conditions and run timing
|
|
############################################################
|
|
read_verilog ../../sdc/test/sdc_test2.v
|
|
link_design sdc_test2
|
|
|
|
create_clock -name clk1 -period 10 [get_ports clk1]
|
|
create_clock -name clk2 -period 20 [get_ports clk2]
|
|
set_input_delay -clock clk1 2.0 [all_inputs]
|
|
set_output_delay -clock clk1 3.0 [all_outputs]
|
|
set_input_transition 0.1 [all_inputs]
|
|
puts "PASS: basic design setup"
|
|
|
|
catch {
|
|
set_operating_conditions typical
|
|
puts "PASS: set_operating_conditions typical"
|
|
} msg
|
|
|
|
report_checks -from [get_ports in1] -to [get_ports out1]
|
|
puts "PASS: report_checks with operating conditions"
|
|
|
|
############################################################
|
|
# Library cell classification queries
|
|
# Exercises: inverters(), buffers(), isBuffer(), isInverter()
|
|
############################################################
|
|
set inv_cell [sta::find_liberty_cell INV_X1]
|
|
puts "PASS: find_liberty_cell INV_X1"
|
|
|
|
set buf_cell [sta::find_liberty_cell BUF_X1]
|
|
puts "PASS: find_liberty_cell BUF_X1"
|
|
|
|
set inv_is_inv [$inv_cell is_inverter]
|
|
puts "PASS: INV_X1 is_inverter = $inv_is_inv"
|
|
|
|
set inv_is_buf [$inv_cell is_buffer]
|
|
puts "PASS: INV_X1 is_buffer = $inv_is_buf"
|
|
|
|
set buf_is_buf [$buf_cell is_buffer]
|
|
puts "PASS: BUF_X1 is_buffer = $buf_is_buf"
|
|
|
|
set buf_is_inv [$buf_cell is_inverter]
|
|
puts "PASS: BUF_X1 is_inverter = $buf_is_inv"
|
|
|
|
# Test is_leaf on various cells
|
|
set dff_cell [sta::find_liberty_cell DFF_X1]
|
|
set dff_leaf [$dff_cell is_leaf]
|
|
puts "PASS: DFF_X1 is_leaf = $dff_leaf"
|
|
|
|
# Liberty library accessor on cell
|
|
set cell_lib [$inv_cell liberty_library]
|
|
puts "PASS: liberty_library from cell: [$cell_lib name]"
|
|
|
|
############################################################
|
|
# Pattern matching on liberty cells
|
|
# Exercises: findLibertyCellsMatching, findLibertyPortsMatching
|
|
############################################################
|
|
set inv_matches [$lib find_liberty_cells_matching "INV*" 0 0]
|
|
puts "PASS: find_liberty_cells_matching INV* = [llength $inv_matches]"
|
|
|
|
set buf_matches [$lib find_liberty_cells_matching "BUF*" 0 0]
|
|
puts "PASS: find_liberty_cells_matching BUF* = [llength $buf_matches]"
|
|
|
|
set dff_matches [$lib find_liberty_cells_matching "DFF*" 0 0]
|
|
puts "PASS: find_liberty_cells_matching DFF* = [llength $dff_matches]"
|
|
|
|
set sdff_matches [$lib find_liberty_cells_matching "SDFF*" 0 0]
|
|
puts "PASS: find_liberty_cells_matching SDFF* = [llength $sdff_matches]"
|
|
|
|
set all_matches [$lib find_liberty_cells_matching "*" 0 0]
|
|
puts "PASS: find_liberty_cells_matching * = [llength $all_matches]"
|
|
|
|
# Port pattern matching
|
|
set inv_port_matches [$inv_cell find_liberty_ports_matching "*" 0 0]
|
|
puts "PASS: find_liberty_ports_matching INV_X1/* = [llength $inv_port_matches]"
|
|
|
|
set dff_port_matches [$dff_cell find_liberty_ports_matching "*" 0 0]
|
|
puts "PASS: find_liberty_ports_matching DFF_X1/* = [llength $dff_port_matches]"
|
|
|
|
############################################################
|
|
# Timing arc queries on cells
|
|
# Exercises: timingArcSets, timingArcSetCount, hasTimingArcs
|
|
############################################################
|
|
set inv_arc_sets [$inv_cell timing_arc_sets]
|
|
puts "PASS: INV_X1 timing_arc_sets count = [llength $inv_arc_sets]"
|
|
|
|
set dff_arc_sets [$dff_cell timing_arc_sets]
|
|
puts "PASS: DFF_X1 timing_arc_sets count = [llength $dff_arc_sets]"
|
|
|
|
# Check timing arc set ports
|
|
set clkgate_cell [sta::find_liberty_cell CLKGATETST_X1]
|
|
set clkgate_arcs [$clkgate_cell timing_arc_sets]
|
|
puts "PASS: CLKGATETST_X1 timing_arc_sets count = [llength $clkgate_arcs]"
|
|
|
|
############################################################
|
|
# Find port on liberty cell
|
|
# Exercises: findLibertyPort
|
|
############################################################
|
|
set inv_a [$inv_cell find_liberty_port A]
|
|
puts "PASS: find_liberty_port INV_X1/A"
|
|
|
|
set inv_zn [$inv_cell find_liberty_port ZN]
|
|
puts "PASS: find_liberty_port INV_X1/ZN"
|
|
|
|
set dff_ck [$dff_cell find_liberty_port CK]
|
|
puts "PASS: find_liberty_port DFF_X1/CK"
|
|
|
|
set dff_d [$dff_cell find_liberty_port D]
|
|
puts "PASS: find_liberty_port DFF_X1/D"
|
|
|
|
set dff_q [$dff_cell find_liberty_port Q]
|
|
puts "PASS: find_liberty_port DFF_X1/Q"
|
|
|
|
############################################################
|
|
# Liberty port iterator on cell
|
|
# Exercises: LibertyCellPortIterator
|
|
############################################################
|
|
set port_iter [$inv_cell liberty_port_iterator]
|
|
set count 0
|
|
while { [$port_iter has_next] } {
|
|
set port [$port_iter next]
|
|
incr count
|
|
}
|
|
$port_iter finish
|
|
puts "PASS: liberty_port_iterator INV_X1 ports = $count"
|
|
|
|
set port_iter2 [$dff_cell liberty_port_iterator]
|
|
set count2 0
|
|
while { [$port_iter2 has_next] } {
|
|
set port [$port_iter2 next]
|
|
incr count2
|
|
}
|
|
$port_iter2 finish
|
|
puts "PASS: liberty_port_iterator DFF_X1 ports = $count2"
|
|
|
|
############################################################
|
|
# Wireload queries
|
|
# Exercises: findWireload, findWireloadSelection
|
|
############################################################
|
|
set wl [$lib find_wireload "1K_hvratio_1_1"]
|
|
if { $wl != "NULL" } {
|
|
puts "PASS: find_wireload 1K_hvratio_1_1"
|
|
} else {
|
|
puts "INFO: wireload not found"
|
|
}
|
|
|
|
set wls [$lib find_wireload_selection "WireloadSelection"]
|
|
if { $wls != "NULL" } {
|
|
puts "PASS: find_wireload_selection"
|
|
} else {
|
|
puts "INFO: wireload selection not found"
|
|
}
|
|
|
|
############################################################
|
|
# Read Sky130 library - has different features
|
|
############################################################
|
|
read_liberty ../../test/sky130hd/sky130hd_tt.lib
|
|
puts "PASS: read sky130"
|
|
|
|
set sky_lib [sta::find_liberty sky130_fd_sc_hd__tt_025C_1v80]
|
|
|
|
set sky_op [$sky_lib find_operating_conditions "tt_025C_1v80"]
|
|
if { $sky_op != "NULL" } {
|
|
puts "PASS: sky130 find_operating_conditions"
|
|
} else {
|
|
puts "INFO: sky130 no named operating conditions"
|
|
}
|
|
|
|
set sky_def_op [$sky_lib default_operating_conditions]
|
|
if { $sky_def_op != "NULL" } {
|
|
puts "PASS: sky130 default_operating_conditions"
|
|
} else {
|
|
puts "INFO: sky130 no default operating conditions"
|
|
}
|
|
|
|
############################################################
|
|
# Read fast/slow libraries for multi-corner analysis
|
|
# Exercises: makeCornerMap path, setCornerCell, scaleFactor
|
|
############################################################
|
|
read_liberty ../../test/nangate45/Nangate45_fast.lib
|
|
puts "PASS: read Nangate45_fast"
|
|
|
|
# Read slow too - exercises more corner mapping paths
|
|
read_liberty ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
|
puts "PASS: read sky130 ff"
|
|
|
|
read_liberty ../../test/sky130hd/sky130_fd_sc_hd__ss_n40C_1v40.lib
|
|
puts "PASS: read sky130 ss"
|
|
|
|
# Report checks exercises multi-library corner paths
|
|
report_checks -from [get_ports in1] -to [get_ports out1]
|
|
puts "PASS: report_checks multi-library"
|
|
|
|
############################################################
|
|
# set_timing_derate - exercises OCV paths
|
|
############################################################
|
|
catch {
|
|
set_timing_derate -early 0.95
|
|
set_timing_derate -late 1.05
|
|
puts "PASS: set_timing_derate"
|
|
}
|
|
|
|
report_checks -from [get_ports in1] -to [get_ports out1]
|
|
puts "PASS: report_checks with derate"
|
|
|
|
############################################################
|
|
# Write liberty for Nangate to exercise all writer paths
|
|
############################################################
|
|
set outfile [make_result_file liberty_opcond_scale_write.lib]
|
|
sta::write_liberty NangateOpenCellLibrary $outfile
|
|
puts "PASS: write_liberty NangateOpenCellLibrary"
|
|
|
|
set outfile2 [make_result_file liberty_opcond_scale_sky130.lib]
|
|
sta::write_liberty sky130_fd_sc_hd__tt_025C_1v80 $outfile2
|
|
puts "PASS: write_liberty sky130"
|
|
|
|
############################################################
|
|
# EquivCells with multiple libraries
|
|
# Exercises: EquivCells constructor with map_libs
|
|
############################################################
|
|
set lib1 [lindex [get_libs NangateOpenCellLibrary] 0]
|
|
set lib2 [lindex [get_libs NangateOpenCellLibrary_fast] 0]
|
|
|
|
sta::make_equiv_cells $lib1
|
|
puts "PASS: make_equiv_cells lib1"
|
|
|
|
sta::make_equiv_cells $lib2
|
|
puts "PASS: make_equiv_cells lib2"
|
|
|
|
# Cross-library equiv
|
|
set inv_typ [get_lib_cell NangateOpenCellLibrary/INV_X1]
|
|
set inv_fast [get_lib_cell NangateOpenCellLibrary_fast/INV_X1]
|
|
set result [sta::equiv_cells $inv_typ $inv_fast]
|
|
puts "PASS: equiv_cells typ vs fast INV_X1 = $result"
|
|
|
|
set buf_typ [get_lib_cell NangateOpenCellLibrary/BUF_X1]
|
|
set buf_fast [get_lib_cell NangateOpenCellLibrary_fast/BUF_X1]
|
|
set result [sta::equiv_cells $buf_typ $buf_fast]
|
|
puts "PASS: equiv_cells typ vs fast BUF_X1 = $result"
|
|
|
|
# equiv_cell_ports across libraries
|
|
set result [sta::equiv_cell_ports $inv_typ $inv_fast]
|
|
puts "PASS: equiv_cell_ports typ vs fast = $result"
|
|
|
|
# equiv_cell_timing_arcs across libraries
|
|
set result [sta::equiv_cell_timing_arcs $inv_typ $inv_fast]
|
|
puts "PASS: equiv_cell_timing_arcs typ vs fast = $result"
|
|
|
|
############################################################
|
|
# Report check types for max_cap, max_slew, max_fanout
|
|
############################################################
|
|
report_check_types -max_slew -max_capacitance -max_fanout -verbose
|
|
puts "PASS: report_check_types verbose"
|
|
|
|
puts "ALL PASSED"
|