test: Apply review feedback - part3
Remove unnecessary catch blocks from Tcl test files across all modules, add report_checks after each set_wire_load_model in liberty_wireload, rewrite liberty_sky130_corners for actual multi-corner timing analysis with define_corners, and expand C++ tests (TestSearchIncremental 8→36, TestPower 71→96, TestSpice 98→126 tests). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
547737f71e
commit
e57c8043cd
|
|
@ -33,11 +33,7 @@ puts "--- report_checks -from/-to ---"
|
|||
report_checks -from [get_ports d] -to [get_ports q]
|
||||
|
||||
puts "--- report_checks -through ---"
|
||||
set rc [catch { report_checks -through [get_pins reg1/Q] } msg]
|
||||
if { $rc == 0 } {
|
||||
} else {
|
||||
puts "INFO: report_checks -through: $msg"
|
||||
}
|
||||
report_checks -through [get_pins reg1/Q]
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# Edge queries (Graph.cc edge functions)
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ foreach lib_name {fakeram45_64x32 fakeram45_256x16 fakeram45_512x64
|
|||
fakeram45_1024x32 fakeram45_64x96} {
|
||||
read_liberty ../../test/nangate45/${lib_name}.lib
|
||||
set cell [get_lib_cell ${lib_name}/${lib_name}]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set port_iter [$cell liberty_port_iterator]
|
||||
set bus_count 0
|
||||
set bit_count 0
|
||||
|
|
@ -109,7 +109,7 @@ foreach cell_name {INV_X1 INV_X2 BUF_X1 BUF_X2 CLKBUF_X1
|
|||
TINV_X1 CLKGATETST_X1 HA_X1 FA_X1
|
||||
ANTENNA_X1 FILLCELL_X1 FILLCELL_X2 LOGIC0_X1 LOGIC1_X1} {
|
||||
set cell [get_lib_cell NangateOpenCellLibrary/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set is_leaf [$cell is_leaf]
|
||||
set is_buf [$cell is_buffer]
|
||||
set is_inv [$cell is_inverter]
|
||||
|
|
@ -129,7 +129,7 @@ puts "--- test_cell / scan queries ---"
|
|||
# SDFF has test_cell
|
||||
set sdff [get_lib_cell NangateOpenCellLibrary/SDFF_X1]
|
||||
set tc [$sdff test_cell]
|
||||
if {$tc != "NULL"} {
|
||||
if {$tc != "NULL" && $tc ne ""} {
|
||||
puts "SDFF_X1 has test_cell"
|
||||
} else {
|
||||
puts "SDFF_X1 test_cell is null"
|
||||
|
|
@ -137,7 +137,7 @@ if {$tc != "NULL"} {
|
|||
|
||||
set sdffr [get_lib_cell NangateOpenCellLibrary/SDFFR_X1]
|
||||
set tc [$sdffr test_cell]
|
||||
if {$tc != "NULL"} {
|
||||
if {$tc != "NULL" && $tc ne ""} {
|
||||
puts "SDFFR_X1 has test_cell"
|
||||
} else {
|
||||
puts "SDFFR_X1 test_cell is null"
|
||||
|
|
@ -145,7 +145,7 @@ if {$tc != "NULL"} {
|
|||
|
||||
set sdffrs [get_lib_cell NangateOpenCellLibrary/SDFFRS_X1]
|
||||
set tc [$sdffrs test_cell]
|
||||
if {$tc != "NULL"} {
|
||||
if {$tc != "NULL" && $tc ne ""} {
|
||||
puts "SDFFRS_X1 has test_cell"
|
||||
} else {
|
||||
puts "SDFFRS_X1 test_cell is null"
|
||||
|
|
@ -154,7 +154,7 @@ if {$tc != "NULL"} {
|
|||
# Regular DFF should NOT have test_cell
|
||||
set dff [get_lib_cell NangateOpenCellLibrary/DFF_X1]
|
||||
set tc [$dff test_cell]
|
||||
if {$tc != "NULL"} {
|
||||
if {$tc != "NULL" && $tc ne ""} {
|
||||
puts "DFF_X1 has test_cell (unexpected)"
|
||||
} else {
|
||||
puts "DFF_X1 has no test_cell (expected)"
|
||||
|
|
|
|||
|
|
@ -31,11 +31,9 @@ puts "INV_X1 is_buffer = [$inv_x1 is_buffer]"
|
|||
puts "INV_X1 is_inverter = [$inv_x1 is_inverter]"
|
||||
|
||||
# Clock gate cells
|
||||
catch {
|
||||
set clkgate [get_lib_cell NangateOpenCellLibrary/CLKGATETST_X1]
|
||||
puts "CLKGATETST_X1 is_buffer = [$clkgate is_buffer]"
|
||||
puts "CLKGATETST_X1 is_inverter = [$clkgate is_inverter]"
|
||||
}
|
||||
set clkgate [get_lib_cell NangateOpenCellLibrary/CLKGATETST_X1]
|
||||
puts "CLKGATETST_X1 is_buffer = [$clkgate is_buffer]"
|
||||
puts "CLKGATETST_X1 is_inverter = [$clkgate is_inverter]"
|
||||
|
||||
# DFF
|
||||
set dff [get_lib_cell NangateOpenCellLibrary/DFF_X1]
|
||||
|
|
@ -44,11 +42,9 @@ puts "DFF_X1 is_inverter = [$dff is_inverter]"
|
|||
puts "DFF_X1 is_leaf = [$dff is_leaf]"
|
||||
|
||||
# Test cell for scan DFF
|
||||
catch {
|
||||
set sdff [get_lib_cell NangateOpenCellLibrary/SDFF_X1]
|
||||
set tc [$sdff test_cell]
|
||||
puts "SDFF_X1 test_cell = $tc"
|
||||
}
|
||||
set sdff [get_lib_cell NangateOpenCellLibrary/SDFF_X1]
|
||||
set tc [$sdff test_cell]
|
||||
puts "SDFF_X1 test_cell = $tc"
|
||||
|
||||
############################################################
|
||||
# Port function queries (exercises FuncExpr::to_string)
|
||||
|
|
@ -181,21 +177,19 @@ foreach cell_name {
|
|||
sky130_fd_sc_hd__dlxtp_1
|
||||
sky130_fd_sc_hd__ebufn_1
|
||||
} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
puts "$cell_name is_buffer=[$cell is_buffer] is_inverter=[$cell is_inverter]"
|
||||
set port_iter [$cell liberty_port_iterator]
|
||||
while {[$port_iter has_next]} {
|
||||
set port [$port_iter next]
|
||||
set func [$port function]
|
||||
set dir [sta::liberty_port_direction $port]
|
||||
set pwr [$port is_pwr_gnd]
|
||||
if {$pwr} {
|
||||
puts " [$port bus_name] pwr_gnd=1"
|
||||
}
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
puts "$cell_name is_buffer=[$cell is_buffer] is_inverter=[$cell is_inverter]"
|
||||
set port_iter [$cell liberty_port_iterator]
|
||||
while {[$port_iter has_next]} {
|
||||
set port [$port_iter next]
|
||||
set func [$port function]
|
||||
set dir [sta::liberty_port_direction $port]
|
||||
set pwr [$port is_pwr_gnd]
|
||||
if {$pwr} {
|
||||
puts " [$port bus_name] pwr_gnd=1"
|
||||
}
|
||||
$port_iter finish
|
||||
}
|
||||
$port_iter finish
|
||||
}
|
||||
|
||||
############################################################
|
||||
|
|
@ -204,7 +198,7 @@ foreach cell_name {
|
|||
puts "--- operating conditions ---"
|
||||
set sky_lib [lindex [get_libs sky130_fd_sc_hd__tt_025C_1v80] 0]
|
||||
set default_oc [$sky_lib default_operating_conditions]
|
||||
if {$default_oc != "NULL"} {
|
||||
if {$default_oc != "NULL" && $default_oc ne ""} {
|
||||
puts "Sky130 default OC process=[$default_oc process] voltage=[$default_oc voltage] temp=[$default_oc temperature]"
|
||||
}
|
||||
|
||||
|
|
@ -220,27 +214,21 @@ foreach cell_name {
|
|||
sg13g2_dfrbp_1 sg13g2_dfrbp_2
|
||||
sg13g2_ebufn_2
|
||||
} {
|
||||
catch {
|
||||
set cell [get_lib_cell sg13g2_stdcell_typ_1p20V_25C/$cell_name]
|
||||
puts "$cell_name is_buffer=[$cell is_buffer] is_inverter=[$cell is_inverter]"
|
||||
set arc_sets [$cell timing_arc_sets]
|
||||
puts " arc_sets=[llength $arc_sets]"
|
||||
}
|
||||
set cell [get_lib_cell sg13g2_stdcell_typ_1p20V_25C/$cell_name]
|
||||
puts "$cell_name is_buffer=[$cell is_buffer] is_inverter=[$cell is_inverter]"
|
||||
set arc_sets [$cell timing_arc_sets]
|
||||
puts " arc_sets=[llength $arc_sets]"
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Ensure voltage waveforms (exercises ensureVoltageWaveforms)
|
||||
############################################################
|
||||
puts "--- ensure voltage waveforms ---"
|
||||
catch {
|
||||
set inv [get_lib_cell NangateOpenCellLibrary/INV_X1]
|
||||
$inv ensure_voltage_waveforms
|
||||
}
|
||||
set inv [get_lib_cell NangateOpenCellLibrary/INV_X1]
|
||||
$inv ensure_voltage_waveforms
|
||||
|
||||
catch {
|
||||
set dff [get_lib_cell NangateOpenCellLibrary/DFF_X1]
|
||||
$dff ensure_voltage_waveforms
|
||||
}
|
||||
set dff [get_lib_cell NangateOpenCellLibrary/DFF_X1]
|
||||
$dff ensure_voltage_waveforms
|
||||
|
||||
############################################################
|
||||
# Liberty cell matching with regex patterns
|
||||
|
|
|
|||
|
|
@ -31,19 +31,15 @@ set cap_d [get_property $dff_d capacitance]
|
|||
|
||||
# Larger drive strengths have different capacitances
|
||||
foreach size {1 2 4 8 16 32} {
|
||||
catch {
|
||||
set pin [get_lib_pin NangateOpenCellLibrary/INV_X${size}/A]
|
||||
set cap [get_property $pin capacitance]
|
||||
puts "INV_X${size}/A cap = $cap"
|
||||
}
|
||||
set pin [get_lib_pin NangateOpenCellLibrary/INV_X${size}/A]
|
||||
set cap [get_property $pin capacitance]
|
||||
puts "INV_X${size}/A cap = $cap"
|
||||
}
|
||||
|
||||
foreach size {1 2 4 8 16 32} {
|
||||
catch {
|
||||
set pin [get_lib_pin NangateOpenCellLibrary/BUF_X${size}/A]
|
||||
set cap [get_property $pin capacitance]
|
||||
puts "BUF_X${size}/A cap = $cap"
|
||||
}
|
||||
set pin [get_lib_pin NangateOpenCellLibrary/BUF_X${size}/A]
|
||||
set cap [get_property $pin capacitance]
|
||||
puts "BUF_X${size}/A cap = $cap"
|
||||
}
|
||||
|
||||
############################################################
|
||||
|
|
@ -56,22 +52,18 @@ foreach cell_name {INV_X1 INV_X2 INV_X4 INV_X8 INV_X16 INV_X32
|
|||
NOR2_X1 NOR2_X2 NOR2_X4
|
||||
AOI21_X1 OAI21_X1 MUX2_X1 FA_X1 HA_X1
|
||||
TINV_X1 CLKGATETST_X1} {
|
||||
catch {
|
||||
set cell [get_lib_cell NangateOpenCellLibrary/$cell_name]
|
||||
set area [get_property $cell area]
|
||||
puts "$cell_name area = $area"
|
||||
}
|
||||
set cell [get_lib_cell NangateOpenCellLibrary/$cell_name]
|
||||
set area [get_property $cell area]
|
||||
puts "$cell_name area = $area"
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Cell dont_use, is_macro, is_memory queries
|
||||
############################################################
|
||||
foreach cell_name {INV_X1 BUF_X1 DFF_X1 ANTENNA_X1 FILLCELL_X1} {
|
||||
catch {
|
||||
set cell [get_lib_cell NangateOpenCellLibrary/$cell_name]
|
||||
set du [get_property $cell dont_use]
|
||||
puts "$cell_name dont_use = $du"
|
||||
}
|
||||
set cell [get_lib_cell NangateOpenCellLibrary/$cell_name]
|
||||
set du [get_property $cell dont_use]
|
||||
puts "$cell_name dont_use = $du"
|
||||
}
|
||||
|
||||
############################################################
|
||||
|
|
@ -135,9 +127,7 @@ report_check_types -max_skew
|
|||
############################################################
|
||||
report_power
|
||||
|
||||
catch {
|
||||
report_power -instances [get_cells *]
|
||||
}
|
||||
report_power -instances [get_cells *]
|
||||
|
||||
############################################################
|
||||
# Sky130 cells - different tristate and latch cells
|
||||
|
|
@ -145,28 +135,28 @@ catch {
|
|||
read_liberty ../../test/sky130hd/sky130hd_tt.lib
|
||||
|
||||
# Tristate buffer
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__ebufn_1}
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__ebufn_2}
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__ebufn_4}
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__ebufn_1
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__ebufn_2
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__ebufn_4
|
||||
|
||||
# Latch cells
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__dlxtp_1}
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__dlxtn_1}
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__dlxtp_1
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__dlxtn_1
|
||||
|
||||
# Scan flip-flops
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__sdfxtp_1}
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__sdfxbp_1}
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__sdfxtp_1
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__sdfxbp_1
|
||||
|
||||
# DFF with async set/clear (exercises recovery/removal)
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__dfxtp_1}
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__dfrtp_1}
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__dfstp_1}
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__dfbbp_1}
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__dfxtp_1
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__dfrtp_1
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__dfstp_1
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__dfbbp_1
|
||||
|
||||
# Mux cells
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__mux2_1}
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__mux2i_1}
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__mux4_1}
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__mux2_1
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__mux2i_1
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__mux4_1
|
||||
|
||||
############################################################
|
||||
# Write roundtrip to exercise all writer cell/arc/model paths
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ foreach cell_name {sky130_fd_sc_hd__dlclkp_1 sky130_fd_sc_hd__dlclkp_2
|
|||
sky130_fd_sc_hd__dlclkp_4} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set area [get_property $cell area]
|
||||
set lp [get_property $cell cell_leakage_power]
|
||||
puts "$cell_name area=$area leakage=$lp"
|
||||
|
|
@ -67,22 +67,20 @@ foreach cell_name {sky130_fd_sc_hd__dlclkp_1 sky130_fd_sc_hd__dlclkp_2
|
|||
# sdlclkp cells have latch_posedge_precontrol type
|
||||
foreach cell_name {sky130_fd_sc_hd__sdlclkp_1 sky130_fd_sc_hd__sdlclkp_2
|
||||
sky130_fd_sc_hd__sdlclkp_4} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
set area [get_property $cell area]
|
||||
puts "$cell_name area=$area"
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set area [get_property $cell area]
|
||||
puts "$cell_name area=$area"
|
||||
|
||||
# Iterate ports to check clock_gate_* pin attributes
|
||||
set port_iter [$cell liberty_port_iterator]
|
||||
while {[$port_iter has_next]} {
|
||||
set port [$port_iter next]
|
||||
set dir [sta::liberty_port_direction $port]
|
||||
set func [$port function]
|
||||
puts " [get_name $port] dir=$dir func=$func"
|
||||
}
|
||||
$port_iter finish
|
||||
# Iterate ports to check clock_gate_* pin attributes
|
||||
set port_iter [$cell liberty_port_iterator]
|
||||
while {[$port_iter has_next]} {
|
||||
set port [$port_iter next]
|
||||
set dir [sta::liberty_port_direction $port]
|
||||
set func [$port function]
|
||||
puts " [get_name $port] dir=$dir func=$func"
|
||||
}
|
||||
$port_iter finish
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -101,7 +99,7 @@ foreach cell_name {sky130_fd_sc_hd__lpflow_lsbuf_lh_hl_isowell_tap_1
|
|||
sky130_fd_sc_hd__lpflow_lsbuf_lh_isowell_tap_4} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set area [get_property $cell area]
|
||||
set lp [get_property $cell cell_leakage_power]
|
||||
puts "$cell_name area=$area leakage=$lp"
|
||||
|
|
@ -130,24 +128,22 @@ puts "--- pg_pin queries ---"
|
|||
foreach cell_name {sky130_fd_sc_hd__inv_1 sky130_fd_sc_hd__buf_1
|
||||
sky130_fd_sc_hd__nand2_1 sky130_fd_sc_hd__dfxtp_1
|
||||
sky130_fd_sc_hd__dlclkp_1 sky130_fd_sc_hd__sdfxtp_1} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
set pwr_count 0
|
||||
set sig_count 0
|
||||
set port_iter [$cell liberty_port_iterator]
|
||||
while {[$port_iter has_next]} {
|
||||
set port [$port_iter next]
|
||||
set is_pwr [$port is_pwr_gnd]
|
||||
if {$is_pwr} {
|
||||
incr pwr_count
|
||||
} else {
|
||||
incr sig_count
|
||||
}
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set pwr_count 0
|
||||
set sig_count 0
|
||||
set port_iter [$cell liberty_port_iterator]
|
||||
while {[$port_iter has_next]} {
|
||||
set port [$port_iter next]
|
||||
set is_pwr [$port is_pwr_gnd]
|
||||
if {$is_pwr} {
|
||||
incr pwr_count
|
||||
} else {
|
||||
incr sig_count
|
||||
}
|
||||
$port_iter finish
|
||||
puts "$cell_name: pwr_pins=$pwr_count signal_pins=$sig_count"
|
||||
}
|
||||
$port_iter finish
|
||||
puts "$cell_name: pwr_pins=$pwr_count signal_pins=$sig_count"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -159,7 +155,7 @@ puts "--- clock gate timing arcs ---"
|
|||
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__dlclkp_1]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set arcs [$cell timing_arc_sets]
|
||||
set arc_count [llength $arcs]
|
||||
puts "dlclkp_1 arc_sets = $arc_count"
|
||||
|
|
@ -174,7 +170,7 @@ catch {
|
|||
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__sdlclkp_1]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set arcs [$cell timing_arc_sets]
|
||||
set arc_count [llength $arcs]
|
||||
puts "sdlclkp_1 arc_sets = $arc_count"
|
||||
|
|
@ -191,7 +187,7 @@ puts "--- level shifter timing arcs ---"
|
|||
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__lpflow_lsbuf_lh_hl_isowell_tap_1]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "lsbuf_lh_hl_isowell_tap_1 arcs = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
|
|
@ -210,14 +206,12 @@ foreach cell_name {sky130_fd_sc_hd__inv_1 sky130_fd_sc_hd__inv_2
|
|||
sky130_fd_sc_hd__clkinv_1 sky130_fd_sc_hd__clkbuf_1
|
||||
sky130_fd_sc_hd__nand2_1 sky130_fd_sc_hd__nor2_1
|
||||
sky130_fd_sc_hd__dfxtp_1 sky130_fd_sc_hd__dlclkp_1} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
set is_buf [$cell is_buffer]
|
||||
set is_inv [$cell is_inverter]
|
||||
set is_leaf [$cell is_leaf]
|
||||
puts "$cell_name: is_buffer=$is_buf is_inverter=$is_inv is_leaf=$is_leaf"
|
||||
}
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set is_buf [$cell is_buffer]
|
||||
set is_inv [$cell is_inverter]
|
||||
set is_leaf [$cell is_leaf]
|
||||
puts "$cell_name: is_buffer=$is_buf is_inverter=$is_inv is_leaf=$is_leaf"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -240,13 +234,11 @@ puts "IHP VDD exists: $ihp_vdd_exists"
|
|||
|
||||
# Query IHP cells
|
||||
foreach cell_name {sg13g2_inv_1 sg13g2_buf_1 sg13g2_nand2_1 sg13g2_nor2_1} {
|
||||
catch {
|
||||
set cell [get_lib_cell sg13g2_stdcell_typ_1p20V_25C/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
set area [get_property $cell area]
|
||||
set is_buf [$cell is_buffer]
|
||||
set is_inv [$cell is_inverter]
|
||||
puts "IHP $cell_name: area=$area buf=$is_buf inv=$is_inv"
|
||||
}
|
||||
set cell [get_lib_cell sg13g2_stdcell_typ_1p20V_25C/$cell_name]
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set area [get_property $cell area]
|
||||
set is_buf [$cell is_buffer]
|
||||
set is_inv [$cell is_inverter]
|
||||
puts "IHP $cell_name: area=$area buf=$is_buf inv=$is_inv"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ foreach cell_prefix {INVx BUFx} {
|
|||
catch {
|
||||
set cell_name "${cell_prefix}${size}_ASAP7_75t_R"
|
||||
set cell [get_lib_cell asap7sc7p5t_INVBUF_RVT_FF_nldm_211120/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set equivs [sta::find_equiv_cells $cell]
|
||||
if {$equivs != ""} {
|
||||
puts "$cell_name equiv count = [llength $equivs]"
|
||||
|
|
@ -49,7 +49,7 @@ foreach cell_prefix {INVx BUFx} {
|
|||
catch {
|
||||
set cell_name "${cell_prefix}${size}_ASAP7_75t_L"
|
||||
set cell [get_lib_cell asap7sc7p5t_INVBUF_LVT_FF_nldm_211120/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set equivs [sta::find_equiv_cells $cell]
|
||||
if {$equivs != ""} {
|
||||
puts "LVT $cell_name equiv count = [llength $equivs]"
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ foreach cell_name {sky130_fd_sc_hd__inv_1 sky130_fd_sc_hd__inv_2
|
|||
sky130_fd_sc_hd__mux2_1 sky130_fd_sc_hd__mux2i_1} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set lp [get_property $cell cell_leakage_power]
|
||||
puts "$cell_name leakage=$lp"
|
||||
}
|
||||
|
|
@ -40,7 +40,7 @@ foreach cell_name {sky130_fd_sc_hd__dfxtp_1 sky130_fd_sc_hd__dfxtp_2
|
|||
sky130_fd_sc_hd__sdfstp_1 sky130_fd_sc_hd__dfbbp_1} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set lp [get_property $cell cell_leakage_power]
|
||||
set area [get_property $cell area]
|
||||
puts "$cell_name leakage=$lp area=$area"
|
||||
|
|
@ -53,7 +53,7 @@ foreach cell_name {sky130_fd_sc_hd__ebufn_1 sky130_fd_sc_hd__ebufn_2
|
|||
sky130_fd_sc_hd__ebufn_4 sky130_fd_sc_hd__ebufn_8} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set lp [get_property $cell cell_leakage_power]
|
||||
puts "$cell_name leakage=$lp"
|
||||
}
|
||||
|
|
@ -65,7 +65,7 @@ foreach cell_name {sky130_fd_sc_hd__dlclkp_1 sky130_fd_sc_hd__dlclkp_2
|
|||
sky130_fd_sc_hd__sdlclkp_1} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set lp [get_property $cell cell_leakage_power]
|
||||
puts "$cell_name leakage=$lp"
|
||||
}
|
||||
|
|
@ -77,11 +77,11 @@ foreach cell_name {sky130_fd_sc_hd__dlclkp_1 sky130_fd_sc_hd__dlclkp_2
|
|||
############################################################
|
||||
puts "--- detailed cell reports ---"
|
||||
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__inv_1}
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__inv_1
|
||||
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__nand2_1}
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__nand2_1
|
||||
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__dfxtp_1}
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__dfxtp_1
|
||||
|
||||
############################################################
|
||||
# Read Nangate library for internal power with when conditions
|
||||
|
|
@ -97,7 +97,7 @@ foreach cell_name {INV_X1 INV_X2 INV_X4 BUF_X1 BUF_X2 BUF_X4
|
|||
TINV_X1 TLAT_X1 CLKGATETST_X1} {
|
||||
catch {
|
||||
set cell [get_lib_cell NangateOpenCellLibrary/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set lp [get_property $cell cell_leakage_power]
|
||||
puts "$cell_name leakage=$lp"
|
||||
}
|
||||
|
|
@ -123,9 +123,7 @@ report_power -digits 8
|
|||
|
||||
# Per-instance power
|
||||
foreach inst_name {buf1 inv1 and1 or1 nand1 nor1 reg1 reg2 reg3} {
|
||||
catch {
|
||||
report_power -instances [get_cells $inst_name]
|
||||
}
|
||||
report_power -instances [get_cells $inst_name]
|
||||
}
|
||||
|
||||
############################################################
|
||||
|
|
@ -137,7 +135,7 @@ foreach cell_name {sg13g2_inv_1 sg13g2_buf_1 sg13g2_nand2_1
|
|||
sg13g2_nor2_1 sg13g2_and2_1 sg13g2_or2_1} {
|
||||
catch {
|
||||
set cell [get_lib_cell sg13g2_stdcell_typ_1p20V_25C/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set lp [get_property $cell cell_leakage_power]
|
||||
set area [get_property $cell area]
|
||||
puts "IHP $cell_name leakage=$lp area=$area"
|
||||
|
|
|
|||
|
|
@ -53,20 +53,18 @@ foreach cell_name {sky130_fd_sc_hd__buf_1 sky130_fd_sc_hd__nand2_1
|
|||
sky130_fd_sc_hd__dfxtp_1 sky130_fd_sc_hd__dfrtp_1
|
||||
sky130_fd_sc_hd__ebufn_1 sky130_fd_sc_hd__dlclkp_1
|
||||
sky130_fd_sc_hd__mux2_1 sky130_fd_sc_hd__sdfxtp_1} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
set pg_count 0
|
||||
set port_iter [$cell liberty_port_iterator]
|
||||
while {[$port_iter has_next]} {
|
||||
set port [$port_iter next]
|
||||
if {[$port is_pwr_gnd]} {
|
||||
incr pg_count
|
||||
}
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set pg_count 0
|
||||
set port_iter [$cell liberty_port_iterator]
|
||||
while {[$port_iter has_next]} {
|
||||
set port [$port_iter next]
|
||||
if {[$port is_pwr_gnd]} {
|
||||
incr pg_count
|
||||
}
|
||||
$port_iter finish
|
||||
puts "$cell_name pg_pin_count=$pg_count"
|
||||
}
|
||||
$port_iter finish
|
||||
puts "$cell_name pg_pin_count=$pg_count"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -93,7 +91,7 @@ foreach cell_name {sky130_fd_sc_hd__inv_1 sky130_fd_sc_hd__inv_2
|
|||
sky130_fd_sc_hd__fa_1} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set lp [get_property $cell cell_leakage_power]
|
||||
puts "$cell_name leakage=$lp"
|
||||
}
|
||||
|
|
@ -113,7 +111,7 @@ foreach cell_name {sky130_fd_sc_hd__dfxtp_1 sky130_fd_sc_hd__dfxtp_2
|
|||
sky130_fd_sc_hd__sdlclkp_1 sky130_fd_sc_hd__dlclkp_1} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set lp [get_property $cell cell_leakage_power]
|
||||
set area [get_property $cell area]
|
||||
puts "$cell_name leakage=$lp area=$area"
|
||||
|
|
@ -126,11 +124,11 @@ foreach cell_name {sky130_fd_sc_hd__dfxtp_1 sky130_fd_sc_hd__dfxtp_2
|
|||
############################################################
|
||||
puts "--- detailed cell reports with pg_pin ---"
|
||||
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__inv_1}
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__dfxtp_1}
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__dfrtp_1}
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__ebufn_1}
|
||||
catch {report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__dlclkp_1}
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__inv_1
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__dfxtp_1
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__dfrtp_1
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__ebufn_1
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__dlclkp_1
|
||||
|
||||
############################################################
|
||||
# Read IHP library (different voltage/supply naming)
|
||||
|
|
@ -142,7 +140,7 @@ foreach cell_name {sg13g2_inv_1 sg13g2_buf_1 sg13g2_nand2_1
|
|||
sg13g2_dfrbp_1 sg13g2_dlhq_1} {
|
||||
catch {
|
||||
set cell [get_lib_cell sg13g2_stdcell_typ_1p20V_25C/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set lp [get_property $cell cell_leakage_power]
|
||||
set area [get_property $cell area]
|
||||
puts "IHP $cell_name leakage=$lp area=$area"
|
||||
|
|
|
|||
|
|
@ -63,9 +63,9 @@ set nand_cell [get_lib_cell NangateOpenCellLibrary/NAND2_X1]
|
|||
catch { puts "NAND2_X1 leakage_power: [get_property $nand_cell cell_leakage_power]" }
|
||||
|
||||
# Area property
|
||||
catch { puts "INV_X1 area: [get_property $inv_cell area]" }
|
||||
catch { puts "BUF_X1 area: [get_property $buf_cell area]" }
|
||||
catch { puts "DFF_X1 area: [get_property $dff_cell area]" }
|
||||
puts "INV_X1 area: [get_property $inv_cell area]"
|
||||
puts "BUF_X1 area: [get_property $buf_cell area]"
|
||||
puts "DFF_X1 area: [get_property $dff_cell area]"
|
||||
|
||||
############################################################
|
||||
# Cell properties - is_buffer, is_inverter, etc.
|
||||
|
|
@ -94,7 +94,7 @@ read_liberty ../../test/sky130hd/sky130hd_tt.lib
|
|||
# Query sky130 cell leakage powers
|
||||
set sky_inv [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__inv_1]
|
||||
catch { puts "sky130 inv leakage: [get_property $sky_inv cell_leakage_power]" }
|
||||
catch { puts "sky130 inv area: [get_property $sky_inv area]" }
|
||||
puts "sky130 inv area: [get_property $sky_inv area]"
|
||||
|
||||
# Write sky130 liberty
|
||||
set outfile2 [make_result_file liberty_power_write_sky130.lib]
|
||||
|
|
@ -108,7 +108,7 @@ read_liberty ../../test/ihp-sg13g2/sg13g2_stdcell_typ_1p20V_25C.lib
|
|||
|
||||
set ihp_inv [get_lib_cell sg13g2_stdcell_typ_1p20V_25C/sg13g2_inv_1]
|
||||
catch { puts "IHP inv leakage: [get_property $ihp_inv cell_leakage_power]" }
|
||||
catch { puts "IHP inv area: [get_property $ihp_inv area]" }
|
||||
puts "IHP inv area: [get_property $ihp_inv area]"
|
||||
|
||||
############################################################
|
||||
# Read ASAP7 CCSN library (CCS timing + power models)
|
||||
|
|
@ -129,4 +129,4 @@ read_liberty ../../test/asap7/asap7sc7p5t_SEQ_RVT_FF_nldm_220123.lib
|
|||
|
||||
set asap7_dff [get_lib_cell asap7sc7p5t_SEQ_RVT_FF_nldm_220123/DFFHQNx1_ASAP7_75t_R]
|
||||
catch { puts "ASAP7 DFF leakage: [get_property $asap7_dff cell_leakage_power]" }
|
||||
catch { puts "ASAP7 DFF area: [get_property $asap7_dff area]" }
|
||||
puts "ASAP7 DFF area: [get_property $asap7_dff area]"
|
||||
|
|
|
|||
|
|
@ -17,14 +17,14 @@ foreach cell_name {sky130_fd_sc_hd__sdfxtp_1 sky130_fd_sc_hd__sdfxtp_2
|
|||
sky130_fd_sc_hd__sdfxtp_4} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set area [get_property $cell area]
|
||||
set lp [get_property $cell cell_leakage_power]
|
||||
puts "$cell_name area=$area leakage=$lp"
|
||||
|
||||
# Check test_cell
|
||||
set tc [$cell test_cell]
|
||||
if {$tc != "NULL"} {
|
||||
if {$tc != "NULL" && $tc ne ""} {
|
||||
puts " has test_cell: yes"
|
||||
} else {
|
||||
puts " has test_cell: no"
|
||||
|
|
@ -51,12 +51,12 @@ foreach cell_name {sky130_fd_sc_hd__sdfxtp_1 sky130_fd_sc_hd__sdfxtp_2
|
|||
foreach cell_name {sky130_fd_sc_hd__sdfxbp_1 sky130_fd_sc_hd__sdfxbp_2} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set area [get_property $cell area]
|
||||
puts "$cell_name area=$area"
|
||||
|
||||
set tc [$cell test_cell]
|
||||
if {$tc != "NULL"} {
|
||||
if {$tc != "NULL" && $tc ne ""} {
|
||||
puts " has test_cell: yes"
|
||||
} else {
|
||||
puts " has test_cell: no"
|
||||
|
|
@ -82,12 +82,12 @@ foreach cell_name {sky130_fd_sc_hd__sdfrtp_1 sky130_fd_sc_hd__sdfrtp_2
|
|||
sky130_fd_sc_hd__sdfrtp_4} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set area [get_property $cell area]
|
||||
puts "$cell_name area=$area"
|
||||
|
||||
set tc [$cell test_cell]
|
||||
if {$tc != "NULL"} {
|
||||
if {$tc != "NULL" && $tc ne ""} {
|
||||
puts " has test_cell: yes"
|
||||
} else {
|
||||
puts " has test_cell: no"
|
||||
|
|
@ -113,7 +113,7 @@ foreach cell_name {sky130_fd_sc_hd__sdfstp_1 sky130_fd_sc_hd__sdfstp_2
|
|||
sky130_fd_sc_hd__sdfstp_4} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set area [get_property $cell area]
|
||||
puts "$cell_name area=$area"
|
||||
|
||||
|
|
@ -141,7 +141,7 @@ foreach cell_name {sky130_fd_sc_hd__sdfxtp_1 sky130_fd_sc_hd__sdfrtp_1
|
|||
sky130_fd_sc_hd__sdfstp_1} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set arcs [$cell timing_arc_sets]
|
||||
set arc_count [llength $arcs]
|
||||
puts "$cell_name arc_sets = $arc_count"
|
||||
|
|
@ -162,7 +162,7 @@ read_liberty ../../test/nangate45/Nangate45_typ.lib
|
|||
foreach cell_name {SDFF_X1 SDFF_X2 SDFFR_X1 SDFFS_X1 SDFFRS_X1} {
|
||||
catch {
|
||||
set cell [get_lib_cell NangateOpenCellLibrary/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set tc [$cell test_cell]
|
||||
puts "$cell_name test_cell=[expr {$tc != "NULL" ? "yes" : "no"}]"
|
||||
|
||||
|
|
@ -183,7 +183,7 @@ foreach cell_name {SDFF_X1 SDFF_X2 SDFFR_X1 SDFFS_X1 SDFFRS_X1} {
|
|||
# Nangate CLKGATETST cell (clock gate test)
|
||||
catch {
|
||||
set cell [get_lib_cell NangateOpenCellLibrary/CLKGATETST_X1]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set tc [$cell test_cell]
|
||||
set area [get_property $cell area]
|
||||
puts "CLKGATETST_X1 area=$area test_cell=[expr {$tc != "NULL" ? "yes" : "no"}]"
|
||||
|
|
@ -203,7 +203,7 @@ read_liberty ../../test/asap7/asap7sc7p5t_SEQ_RVT_FF_nldm_220123.lib
|
|||
# ASAP7 ICG cell has statetable (exercises clock gate paths)
|
||||
catch {
|
||||
set cell [get_lib_cell asap7sc7p5t_SEQ_RVT_FF_nldm_220123/ICGx1_ASAP7_75t_R]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "ASAP7 ICGx1 arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
|
|
@ -217,7 +217,7 @@ foreach cell_name {DFFHQNx1_ASAP7_75t_R DFFHQx1_ASAP7_75t_R
|
|||
DFFHQNx2_ASAP7_75t_R DFFHQx2_ASAP7_75t_R} {
|
||||
catch {
|
||||
set cell [get_lib_cell asap7sc7p5t_SEQ_RVT_FF_nldm_220123/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "$cell_name arcs=[llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
|
|
|
|||
|
|
@ -18,27 +18,23 @@ puts "sdfxtp_1 area = $sdf_area"
|
|||
|
||||
# Check test_cell exists
|
||||
set tc [$sdf_cell test_cell]
|
||||
if {$tc != "NULL"} {
|
||||
if {$tc != "NULL" && $tc ne ""} {
|
||||
} else {
|
||||
}
|
||||
|
||||
# Query scan ports
|
||||
foreach port_name {SCD SCE CLK D Q} {
|
||||
catch {
|
||||
set port [$sdf_cell find_liberty_port $port_name]
|
||||
if {$port != "NULL"} {
|
||||
set dir [sta::liberty_port_direction $port]
|
||||
puts "sdfxtp_1/$port_name dir=$dir"
|
||||
}
|
||||
set port [$sdf_cell find_liberty_port $port_name]
|
||||
if {$port != "NULL" && $port ne ""} {
|
||||
set dir [sta::liberty_port_direction $port]
|
||||
puts "sdfxtp_1/$port_name dir=$dir"
|
||||
}
|
||||
}
|
||||
|
||||
# Another scan cell
|
||||
catch {
|
||||
set sdf_cell2 [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__sdfxbp_1]
|
||||
set area2 [get_property $sdf_cell2 area]
|
||||
puts "sdfxbp_1 area = $area2"
|
||||
}
|
||||
set sdf_cell2 [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__sdfxbp_1]
|
||||
set area2 [get_property $sdf_cell2 area]
|
||||
puts "sdfxbp_1 area = $area2"
|
||||
|
||||
############################################################
|
||||
# Query tristate buffer cells (exercises three_state parsing)
|
||||
|
|
@ -51,7 +47,7 @@ foreach cell_name {sky130_fd_sc_hd__ebufn_1 sky130_fd_sc_hd__ebufn_2
|
|||
puts "$cell_name area = $area"
|
||||
# Query tristate enable function
|
||||
set z_port [$cell find_liberty_port "Z"]
|
||||
if {$z_port != "NULL"} {
|
||||
if {$z_port != "NULL" && $z_port ne ""} {
|
||||
set tri_en [$z_port tristate_enable]
|
||||
puts "$cell_name Z tristate_enable = $tri_en"
|
||||
}
|
||||
|
|
@ -63,12 +59,10 @@ foreach cell_name {sky130_fd_sc_hd__ebufn_1 sky130_fd_sc_hd__ebufn_2
|
|||
############################################################
|
||||
foreach cell_name {sky130_fd_sc_hd__dlxtp_1 sky130_fd_sc_hd__dlxtn_1
|
||||
sky130_fd_sc_hd__dlxbn_1 sky130_fd_sc_hd__dlxbp_1} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
set area [get_property $cell area]
|
||||
puts "$cell_name area = $area"
|
||||
}
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set area [get_property $cell area]
|
||||
puts "$cell_name area = $area"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -77,14 +71,12 @@ foreach cell_name {sky130_fd_sc_hd__dlxtp_1 sky130_fd_sc_hd__dlxtn_1
|
|||
############################################################
|
||||
foreach cell_name {sky130_fd_sc_hd__dfrtp_1 sky130_fd_sc_hd__dfstp_1
|
||||
sky130_fd_sc_hd__dfxtp_1 sky130_fd_sc_hd__dfbbp_1} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
set area [get_property $cell area]
|
||||
set is_buf [$cell is_buffer]
|
||||
set is_inv [$cell is_inverter]
|
||||
puts "$cell_name area=$area is_buf=$is_buf is_inv=$is_inv"
|
||||
}
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set area [get_property $cell area]
|
||||
set is_buf [$cell is_buffer]
|
||||
set is_inv [$cell is_inverter]
|
||||
puts "$cell_name area=$area is_buf=$is_buf is_inv=$is_inv"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -96,7 +88,7 @@ foreach cell_name {sky130_fd_sc_hd__inv_1 sky130_fd_sc_hd__buf_1
|
|||
sky130_fd_sc_hd__dfxtp_1} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set lp [get_property $cell cell_leakage_power]
|
||||
puts "$cell_name leakage = $lp"
|
||||
}
|
||||
|
|
@ -109,20 +101,18 @@ foreach cell_name {sky130_fd_sc_hd__inv_1 sky130_fd_sc_hd__buf_1
|
|||
foreach cell_name {sky130_fd_sc_hd__and2_1 sky130_fd_sc_hd__or2_1
|
||||
sky130_fd_sc_hd__xor2_1 sky130_fd_sc_hd__xnor2_1
|
||||
sky130_fd_sc_hd__mux2_1} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
set port_iter [$cell liberty_port_iterator]
|
||||
while {[$port_iter has_next]} {
|
||||
set port [$port_iter next]
|
||||
set dir [sta::liberty_port_direction $port]
|
||||
set func [$port function]
|
||||
if {$func != ""} {
|
||||
puts "$cell_name/[get_name $port] dir=$dir func=$func"
|
||||
}
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set port_iter [$cell liberty_port_iterator]
|
||||
while {[$port_iter has_next]} {
|
||||
set port [$port_iter next]
|
||||
set dir [sta::liberty_port_direction $port]
|
||||
set func [$port function]
|
||||
if {$func != ""} {
|
||||
puts "$cell_name/[get_name $port] dir=$dir func=$func"
|
||||
}
|
||||
$port_iter finish
|
||||
}
|
||||
$port_iter finish
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -136,19 +126,17 @@ read_liberty ../../test/nangate45/Nangate45_typ.lib
|
|||
############################################################
|
||||
foreach cell_name {INV_X1 INV_X2 INV_X4 BUF_X1 BUF_X2 BUF_X4
|
||||
NAND2_X1 NOR2_X1 AOI21_X1 OAI21_X1} {
|
||||
catch {
|
||||
set cell [get_lib_cell NangateOpenCellLibrary/$cell_name]
|
||||
set port_iter [$cell liberty_port_iterator]
|
||||
while {[$port_iter has_next]} {
|
||||
set port [$port_iter next]
|
||||
set dir [sta::liberty_port_direction $port]
|
||||
if {$dir == "input"} {
|
||||
set cap [get_property $port capacitance]
|
||||
puts "$cell_name/[get_name $port] cap=$cap"
|
||||
}
|
||||
set cell [get_lib_cell NangateOpenCellLibrary/$cell_name]
|
||||
set port_iter [$cell liberty_port_iterator]
|
||||
while {[$port_iter has_next]} {
|
||||
set port [$port_iter next]
|
||||
set dir [sta::liberty_port_direction $port]
|
||||
if {$dir == "input"} {
|
||||
set cap [get_property $port capacitance]
|
||||
puts "$cell_name/[get_name $port] cap=$cap"
|
||||
}
|
||||
$port_iter finish
|
||||
}
|
||||
$port_iter finish
|
||||
}
|
||||
|
||||
############################################################
|
||||
|
|
@ -157,7 +145,7 @@ foreach cell_name {INV_X1 INV_X2 INV_X4 BUF_X1 BUF_X2 BUF_X4
|
|||
foreach cell_name {DFF_X1 DFFR_X1 DFFS_X1 DFFRS_X1} {
|
||||
catch {
|
||||
set cell [get_lib_cell NangateOpenCellLibrary/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set arcs [$cell timing_arc_sets]
|
||||
set arc_count [llength $arcs]
|
||||
puts "$cell_name arc_sets = $arc_count"
|
||||
|
|
@ -179,7 +167,7 @@ read_liberty ../../test/nangate45/fakeram45_64x7.lib
|
|||
# Query bus ports
|
||||
catch {
|
||||
set cell [get_lib_cell fakeram45_64x7/fakeram45_64x7]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set port_iter [$cell liberty_port_iterator]
|
||||
while {[$port_iter has_next]} {
|
||||
set port [$port_iter next]
|
||||
|
|
@ -212,7 +200,7 @@ read_liberty ../../test/asap7/asap7sc7p5t_SEQ_RVT_FF_nldm_220123.lib
|
|||
# Query ASAP7 latch cells
|
||||
catch {
|
||||
set cell [get_lib_cell asap7sc7p5t_SEQ_RVT_FF_nldm_220123/DLLx1_ASAP7_75t_R]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set arcs [$cell timing_arc_sets]
|
||||
set arc_count [llength $arcs]
|
||||
puts "DLLx1 arc_sets = $arc_count"
|
||||
|
|
@ -225,7 +213,7 @@ catch {
|
|||
# Query ICG (Integrated Clock Gate) cell with statetable
|
||||
catch {
|
||||
set cell [get_lib_cell asap7sc7p5t_SEQ_RVT_FF_nldm_220123/ICGx1_ASAP7_75t_R]
|
||||
if {$cell != "NULL"} {
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set arcs [$cell timing_arc_sets]
|
||||
set arc_count [llength $arcs]
|
||||
puts "ICGx1 arc_sets = $arc_count"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,122 @@
|
|||
Warning: ../../test/sky130hs/sky130_fd_sc_hs__tt_025C_1v80.lib line 1, library sky130_fd_sc_hs__tt_025C_1v80 already exists.
|
||||
--- Fast corner, max ---
|
||||
Startpoint: reg1 (rising edge-triggered flip-flop clocked by clk)
|
||||
Endpoint: out1 (output port clocked by clk)
|
||||
Path Group: clk
|
||||
Path Type: max
|
||||
Corner: fast
|
||||
|
||||
Delay Time Description
|
||||
---------------------------------------------------------
|
||||
0.00 0.00 clock clk (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 ^ reg1/CLK (sky130_fd_sc_hd__dfxtp_1)
|
||||
0.18 0.18 v reg1/Q (sky130_fd_sc_hd__dfxtp_1)
|
||||
0.04 0.22 v buf2/X (sky130_fd_sc_hd__buf_1)
|
||||
0.00 0.22 v out1 (out)
|
||||
0.22 data arrival time
|
||||
|
||||
10.00 10.00 clock clk (rise edge)
|
||||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 10.00 clock reconvergence pessimism
|
||||
-3.00 7.00 output external delay
|
||||
7.00 data required time
|
||||
---------------------------------------------------------
|
||||
7.00 data required time
|
||||
-0.22 data arrival time
|
||||
---------------------------------------------------------
|
||||
6.78 slack (MET)
|
||||
|
||||
|
||||
--- Slow corner, max ---
|
||||
Startpoint: reg1 (rising edge-triggered flip-flop clocked by clk)
|
||||
Endpoint: out1 (output port clocked by clk)
|
||||
Path Group: clk
|
||||
Path Type: max
|
||||
Corner: slow
|
||||
|
||||
Delay Time Description
|
||||
---------------------------------------------------------
|
||||
0.00 0.00 clock clk (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 ^ reg1/CLK (sky130_fd_sc_hd__dfxtp_1)
|
||||
1.20 1.20 ^ reg1/Q (sky130_fd_sc_hd__dfxtp_1)
|
||||
0.21 1.41 ^ buf2/X (sky130_fd_sc_hd__buf_1)
|
||||
0.00 1.41 ^ out1 (out)
|
||||
1.41 data arrival time
|
||||
|
||||
10.00 10.00 clock clk (rise edge)
|
||||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 10.00 clock reconvergence pessimism
|
||||
-3.00 7.00 output external delay
|
||||
7.00 data required time
|
||||
---------------------------------------------------------
|
||||
7.00 data required time
|
||||
-1.41 data arrival time
|
||||
---------------------------------------------------------
|
||||
5.59 slack (MET)
|
||||
|
||||
|
||||
--- Fast corner, min ---
|
||||
Startpoint: reg1 (rising edge-triggered flip-flop clocked by clk)
|
||||
Endpoint: reg2 (rising edge-triggered flip-flop clocked by clk)
|
||||
Path Group: clk
|
||||
Path Type: min
|
||||
Corner: fast
|
||||
|
||||
Delay Time Description
|
||||
---------------------------------------------------------
|
||||
0.00 0.00 clock clk (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 ^ reg1/CLK (sky130_fd_sc_hd__dfxtp_1)
|
||||
0.18 0.18 ^ reg1/Q (sky130_fd_sc_hd__dfxtp_1)
|
||||
0.00 0.18 ^ reg2/D (sky130_fd_sc_hd__dfxtp_1)
|
||||
0.18 data arrival time
|
||||
|
||||
0.00 0.00 clock clk (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 clock reconvergence pessimism
|
||||
0.00 ^ reg2/CLK (sky130_fd_sc_hd__dfxtp_1)
|
||||
-0.02 -0.02 library hold time
|
||||
-0.02 data required time
|
||||
---------------------------------------------------------
|
||||
-0.02 data required time
|
||||
-0.18 data arrival time
|
||||
---------------------------------------------------------
|
||||
0.20 slack (MET)
|
||||
|
||||
|
||||
--- Slow corner, min ---
|
||||
Startpoint: reg1 (rising edge-triggered flip-flop clocked by clk)
|
||||
Endpoint: reg2 (rising edge-triggered flip-flop clocked by clk)
|
||||
Path Group: clk
|
||||
Path Type: min
|
||||
Corner: slow
|
||||
|
||||
Delay Time Description
|
||||
---------------------------------------------------------
|
||||
0.00 0.00 clock clk (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 ^ reg1/CLK (sky130_fd_sc_hd__dfxtp_1)
|
||||
0.93 0.93 v reg1/Q (sky130_fd_sc_hd__dfxtp_1)
|
||||
0.00 0.93 v reg2/D (sky130_fd_sc_hd__dfxtp_1)
|
||||
0.93 data arrival time
|
||||
|
||||
0.00 0.00 clock clk (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 clock reconvergence pessimism
|
||||
0.00 ^ reg2/CLK (sky130_fd_sc_hd__dfxtp_1)
|
||||
-0.22 -0.22 library hold time
|
||||
-0.22 data required time
|
||||
---------------------------------------------------------
|
||||
-0.22 data required time
|
||||
-0.93 data arrival time
|
||||
---------------------------------------------------------
|
||||
1.15 slack (MET)
|
||||
|
||||
|
||||
Cell sky130_fd_sc_hd__inv_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -9,8 +124,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
A input 0.00-0.00
|
||||
Y output function=!A
|
||||
Cell sky130_fd_sc_hd__inv_2
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -18,8 +133,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
A input 0.00-0.00
|
||||
Y output function=!A
|
||||
Cell sky130_fd_sc_hd__inv_4
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -27,8 +142,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
A input 0.01-0.01
|
||||
Y output function=!A
|
||||
Cell sky130_fd_sc_hd__buf_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -36,8 +151,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
A input 0.00-0.00
|
||||
X output function=A
|
||||
Cell sky130_fd_sc_hd__buf_2
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -45,8 +160,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
A input 0.00-0.00
|
||||
X output function=A
|
||||
Cell sky130_fd_sc_hd__buf_4
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -54,8 +169,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
A input 0.00-0.00
|
||||
X output function=A
|
||||
Cell sky130_fd_sc_hd__nand2_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -64,8 +179,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
B input 0.00-0.00
|
||||
Y output function=!A+!B
|
||||
Cell sky130_fd_sc_hd__nand3_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -75,8 +190,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
C input 0.00-0.00
|
||||
Y output function=(!A+!B)+!C
|
||||
Cell sky130_fd_sc_hd__nand4_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -87,8 +202,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
D input 0.00-0.00
|
||||
Y output function=((!A+!B)+!C)+!D
|
||||
Cell sky130_fd_sc_hd__nor2_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -97,8 +212,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
B input 0.00-0.00
|
||||
Y output function=!A*!B
|
||||
Cell sky130_fd_sc_hd__nor3_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -108,8 +223,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
C input 0.00-0.00
|
||||
Y output function=(!A*!B)*!C
|
||||
Cell sky130_fd_sc_hd__nor4_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -120,8 +235,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
D input 0.00-0.00
|
||||
Y output function=((!A*!B)*!C)*!D
|
||||
Cell sky130_fd_sc_hd__and2_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -130,8 +245,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
B input 0.00-0.00
|
||||
X output function=A*B
|
||||
Cell sky130_fd_sc_hd__and3_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -141,8 +256,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
C input 0.00-0.00
|
||||
X output function=(A*B)*C
|
||||
Cell sky130_fd_sc_hd__and4_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -153,8 +268,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
D input 0.00-0.00
|
||||
X output function=((A*B)*C)*D
|
||||
Cell sky130_fd_sc_hd__or2_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -163,8 +278,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
B input 0.00-0.00
|
||||
X output function=A+B
|
||||
Cell sky130_fd_sc_hd__or3_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -174,8 +289,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
C input 0.00-0.00
|
||||
X output function=(A+B)+C
|
||||
Cell sky130_fd_sc_hd__or4_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -186,8 +301,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
D input 0.00-0.00
|
||||
X output function=((A+B)+C)+D
|
||||
Cell sky130_fd_sc_hd__xor2_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -196,8 +311,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
B input 0.00-0.00
|
||||
X output function=(A*!B)+(!A*B)
|
||||
Cell sky130_fd_sc_hd__xnor2_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -206,8 +321,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
B input 0.00-0.00
|
||||
Y output function=(!A*!B)+(A*B)
|
||||
Cell sky130_fd_sc_hd__a21o_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -217,8 +332,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
B1 input 0.00-0.00
|
||||
X output function=(A1*A2)+B1
|
||||
Cell sky130_fd_sc_hd__a21oi_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -228,8 +343,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
B1 input 0.00-0.00
|
||||
Y output function=(!A1*!B1)+(!A2*!B1)
|
||||
Cell sky130_fd_sc_hd__a22o_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -240,8 +355,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
B2 input 0.00-0.00
|
||||
X output function=(B1*B2)+(A1*A2)
|
||||
Cell sky130_fd_sc_hd__a22oi_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -252,8 +367,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
B2 input 0.00-0.00
|
||||
Y output function=(((!A1*!B1)+(!A1*!B2))+(!A2*!B1))+(!A2*!B2)
|
||||
Cell sky130_fd_sc_hd__o21a_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -263,8 +378,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
B1 input 0.00-0.00
|
||||
X output function=(A1*B1)+(A2*B1)
|
||||
Cell sky130_fd_sc_hd__o21ai_0
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -274,8 +389,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
B1 input 0.00-0.00
|
||||
Y output function=(!A1*!A2)+!B1
|
||||
Cell sky130_fd_sc_hd__o22a_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -286,8 +401,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
B2 input 0.00-0.00
|
||||
X output function=(((A1*B1)+(A2*B1))+(A1*B2))+(A2*B2)
|
||||
Cell sky130_fd_sc_hd__o22ai_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -298,8 +413,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
B2 input 0.00-0.00
|
||||
Y output function=(!B1*!B2)+(!A1*!A2)
|
||||
Cell sky130_fd_sc_hd__a31o_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -310,8 +425,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
B1 input 0.00-0.00
|
||||
X output function=((A1*A2)*A3)+B1
|
||||
Cell sky130_fd_sc_hd__a32o_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -323,8 +438,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
B2 input 0.00-0.00
|
||||
X output function=((A1*A2)*A3)+(B1*B2)
|
||||
Cell sky130_fd_sc_hd__mux2_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -334,8 +449,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
S input 0.00-0.00
|
||||
X output function=(A0*!S)+(A1*S)
|
||||
Cell sky130_fd_sc_hd__mux4_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -348,8 +463,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
S1 input 0.00-0.00
|
||||
X output function=((((A0*!S0)*!S1)+((A1*S0)*!S1))+((A2*!S0)*S1))+((A3*S0)*S1)
|
||||
Cell sky130_fd_sc_hd__fa_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -360,19 +475,19 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
COUT output function=((A*B)+(A*CIN))+(B*CIN)
|
||||
SUM output function=((((A*!B)*!CIN)+((!A*B)*!CIN))+((!A*!B)*CIN))+((A*B)*CIN)
|
||||
Cell sky130_fd_sc_hd__ha_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
VPWR power
|
||||
A input 0.00-0.00
|
||||
B input 0.00-0.00
|
||||
B input 0.00
|
||||
COUT output function=A*B
|
||||
SUM output function=(A*!B)+(!A*B)
|
||||
Cell sky130_fd_sc_hd__maj3_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -382,8 +497,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
C input 0.00-0.00
|
||||
X output function=((A*B)+(A*C))+(B*C)
|
||||
Cell sky130_fd_sc_hd__dfxtp_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
IQ internal
|
||||
IQ_N internal
|
||||
VGND ground
|
||||
|
|
@ -394,8 +509,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
D input 0.00-0.00
|
||||
Q output function=IQ
|
||||
Cell sky130_fd_sc_hd__dfrtp_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
IQ internal
|
||||
IQ_N internal
|
||||
VGND ground
|
||||
|
|
@ -407,8 +522,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
Q output function=IQ
|
||||
RESET_B input 0.00-0.00
|
||||
Cell sky130_fd_sc_hd__dfstp_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
IQ internal
|
||||
IQ_N internal
|
||||
VGND ground
|
||||
|
|
@ -420,8 +535,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
Q output function=IQ
|
||||
SET_B input 0.00-0.00
|
||||
Cell sky130_fd_sc_hd__dfbbp_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
IQ internal
|
||||
IQ_N internal
|
||||
VGND ground
|
||||
|
|
@ -435,8 +550,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
RESET_B input 0.00-0.00
|
||||
SET_B input 0.00-0.00
|
||||
Cell sky130_fd_sc_hd__dlxtp_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
IQ internal
|
||||
IQ_N internal
|
||||
VGND ground
|
||||
|
|
@ -447,8 +562,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
GATE input 0.00-0.00
|
||||
Q output function=IQ
|
||||
Cell sky130_fd_sc_hd__dlxtn_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
IQ internal
|
||||
IQ_N internal
|
||||
VGND ground
|
||||
|
|
@ -459,8 +574,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
GATE_N input 0.00-0.00
|
||||
Q output function=IQ
|
||||
Cell sky130_fd_sc_hd__sdfxtp_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
IQ internal
|
||||
IQ_N internal
|
||||
VGND ground
|
||||
|
|
@ -473,8 +588,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
SCD input 0.00-0.00
|
||||
SCE input 0.00-0.00
|
||||
Cell sky130_fd_sc_hd__sdfxbp_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
IQ internal
|
||||
IQ_N internal
|
||||
VGND ground
|
||||
|
|
@ -488,8 +603,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
SCD input 0.00-0.00
|
||||
SCE input 0.00-0.00
|
||||
Cell sky130_fd_sc_hd__ebufn_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -498,8 +613,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
TE_B input 0.00-0.00
|
||||
Z tristate enable=!TE_B function=A 0.00
|
||||
Cell sky130_fd_sc_hd__ebufn_2
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -508,8 +623,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
TE_B input 0.00-0.00
|
||||
Z tristate enable=!TE_B function=A 0.00
|
||||
Cell sky130_fd_sc_hd__clkbuf_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -517,8 +632,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
A input 0.00-0.00
|
||||
X output function=A
|
||||
Cell sky130_fd_sc_hd__clkbuf_2
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -526,8 +641,8 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
A input 0.00-0.00
|
||||
X output function=A
|
||||
Cell sky130_fd_sc_hd__clkinv_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -535,17 +650,17 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
A input 0.00-0.00
|
||||
Y output function=!A
|
||||
Cell sky130_fd_sc_hd__clkinv_2
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
VPWR power
|
||||
A input 0.00-0.00
|
||||
A input 0.00-0.01
|
||||
Y output function=!A
|
||||
Cell sky130_fd_sc_hd__conb_1
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
|
|
@ -553,55 +668,32 @@ File ../../test/sky130hd/sky130hd_tt.lib
|
|||
HI output function=1
|
||||
LO output function=0
|
||||
Cell sky130_fd_sc_hd__diode_2
|
||||
Library sky130_fd_sc_hd__tt_025C_1v80
|
||||
File ../../test/sky130hd/sky130hd_tt.lib
|
||||
Library sky130_fd_sc_hd__ff_n40C_1v95
|
||||
File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
VGND ground
|
||||
VNB unknown
|
||||
VPB unknown
|
||||
VPWR power
|
||||
DIODE input 0.00-0.00
|
||||
Warning: liberty_sky130_corners.tcl line 1, liberty cell 'sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__fill_1' not found.
|
||||
sky130_fd_sc_hd__inv_1/A: cap=0.002390 dir=input
|
||||
sky130_fd_sc_hd__inv_1: area=3.753600 dont_use=0
|
||||
sky130_fd_sc_hd__buf_1: area=3.753600 dont_use=0
|
||||
sky130_fd_sc_hd__dfxtp_1: area=20.019199 dont_use=0
|
||||
sky130_fd_sc_hd__dlxtp_1: area=15.014400 dont_use=0
|
||||
sky130_fd_sc_hd__sdfxtp_1: area=26.275200 dont_use=0
|
||||
sky130_fd_sc_hd__ebufn_1: area=10.009600 dont_use=0
|
||||
sky130_fd_sc_hd__mux2_1: area=11.260800 dont_use=0
|
||||
sky130_fd_sc_hd__fa_1: area=20.019199 dont_use=0
|
||||
sky130_fd_sc_hd__inv_1/A: cap=0.002392 dir=input
|
||||
sky130_fd_sc_hd__inv_1/Y: cap=0.000000 dir=output
|
||||
sky130_fd_sc_hd__buf_1/A: cap=0.002191 dir=input
|
||||
sky130_fd_sc_hd__buf_1/A: cap=0.002258 dir=input
|
||||
sky130_fd_sc_hd__buf_1/X: cap=0.000000 dir=output
|
||||
sky130_fd_sc_hd__nand2_1/A: cap=0.002375 dir=input
|
||||
sky130_fd_sc_hd__nand2_1/B: cap=0.002428 dir=input
|
||||
sky130_fd_sc_hd__nand2_1/A: cap=0.002387 dir=input
|
||||
sky130_fd_sc_hd__nand2_1/B: cap=0.002422 dir=input
|
||||
sky130_fd_sc_hd__nand2_1/Y: cap=0.000000 dir=output
|
||||
sky130_fd_sc_hd__dfxtp_1/CLK: cap=0.001877 dir=input
|
||||
sky130_fd_sc_hd__dfxtp_1/D: cap=0.001674 dir=input
|
||||
sky130_fd_sc_hd__dfxtp_1/CLK: cap=0.001937 dir=input
|
||||
sky130_fd_sc_hd__dfxtp_1/D: cap=0.001748 dir=input
|
||||
sky130_fd_sc_hd__dfxtp_1/Q: cap=0.000000 dir=output
|
||||
sky130_fd_sc_hd__dfrtp_1/CLK: cap=0.001871 dir=input
|
||||
sky130_fd_sc_hd__dfrtp_1/D: cap=0.002006 dir=input
|
||||
sky130_fd_sc_hd__dfrtp_1/RESET_B: cap=0.003632 dir=input
|
||||
sky130_fd_sc_hd__dfrtp_1/CLK: cap=0.001951 dir=input
|
||||
sky130_fd_sc_hd__dfrtp_1/D: cap=0.002086 dir=input
|
||||
sky130_fd_sc_hd__dfrtp_1/RESET_B: cap=0.003621 dir=input
|
||||
sky130_fd_sc_hd__dfrtp_1/Q: cap=0.000000 dir=output
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_LVT_FF_nldm_211120.lib.gz line 13156, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_LVT_FF_nldm_211120.lib.gz line 13189, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_LVT_FF_nldm_211120.lib.gz line 13222, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_LVT_FF_nldm_211120.lib.gz line 13255, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_LVT_FF_nldm_211120.lib.gz line 13288, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_LVT_FF_nldm_211120.lib.gz line 13321, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_LVT_FF_nldm_211120.lib.gz line 13354, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_LVT_FF_nldm_211120.lib.gz line 14748, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_LVT_FF_nldm_211120.lib.gz line 14781, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_LVT_FF_nldm_211120.lib.gz line 14814, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_SLVT_FF_nldm_211120.lib.gz line 13156, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_SLVT_FF_nldm_211120.lib.gz line 13189, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_SLVT_FF_nldm_211120.lib.gz line 13222, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_SLVT_FF_nldm_211120.lib.gz line 13255, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_SLVT_FF_nldm_211120.lib.gz line 13288, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_SLVT_FF_nldm_211120.lib.gz line 13321, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_SLVT_FF_nldm_211120.lib.gz line 13354, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_SLVT_FF_nldm_211120.lib.gz line 14748, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_SLVT_FF_nldm_211120.lib.gz line 14781, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_SLVT_FF_nldm_211120.lib.gz line 14814, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 13156, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 13189, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 13222, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 13255, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 13288, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 13321, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 13354, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 14748, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 14781, timing group from output port.
|
||||
Warning: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 14814, timing group from output port.
|
||||
|
|
|
|||
|
|
@ -1,28 +1,47 @@
|
|||
# Test multi-corner library reading and Sky130HS features.
|
||||
# Test multi-corner library reading and timing analysis with Sky130HD.
|
||||
source ../../test/helpers.tcl
|
||||
|
||||
############################################################
|
||||
# Read Sky130HD all corners
|
||||
# Define corners and read Sky130HD libraries per corner
|
||||
############################################################
|
||||
read_liberty ../../test/sky130hd/sky130hd_tt.lib
|
||||
define_corners fast slow
|
||||
|
||||
read_liberty ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
|
||||
read_liberty ../../test/sky130hd/sky130_fd_sc_hd__ss_n40C_1v40.lib
|
||||
read_liberty -corner fast ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
||||
read_liberty -corner slow ../../test/sky130hd/sky130_fd_sc_hd__ss_n40C_1v40.lib
|
||||
|
||||
############################################################
|
||||
# Read Sky130HS
|
||||
# Read design and link
|
||||
############################################################
|
||||
read_liberty ../../test/sky130hs/sky130hs_tt.lib
|
||||
|
||||
read_liberty ../../test/sky130hs/sky130_fd_sc_hs__tt_025C_1v80.lib
|
||||
read_verilog sky130_corners_test.v
|
||||
link_design sky130_corners_test
|
||||
|
||||
############################################################
|
||||
# Comprehensive cell reports across PDKs
|
||||
# Exercises: all timing model, power model, and arc code
|
||||
# Create constraints
|
||||
############################################################
|
||||
create_clock -name clk -period 10 [get_ports clk]
|
||||
set_input_delay -clock clk 2.0 [get_ports in1]
|
||||
set_input_delay -clock clk 2.0 [get_ports in2]
|
||||
set_output_delay -clock clk 3.0 [get_ports out1]
|
||||
set_output_delay -clock clk 3.0 [get_ports out2]
|
||||
|
||||
# Sky130HD cells - comprehensive reporting
|
||||
############################################################
|
||||
# Report timing per corner (shows different delays per corner)
|
||||
############################################################
|
||||
puts "--- Fast corner, max ---"
|
||||
report_checks -corner fast -path_delay max
|
||||
|
||||
puts "--- Slow corner, max ---"
|
||||
report_checks -corner slow -path_delay max
|
||||
|
||||
puts "--- Fast corner, min ---"
|
||||
report_checks -corner fast -path_delay min
|
||||
|
||||
puts "--- Slow corner, min ---"
|
||||
report_checks -corner slow -path_delay min
|
||||
|
||||
############################################################
|
||||
# Comprehensive cell reports - fast corner library
|
||||
############################################################
|
||||
set sky130_cells_to_report {
|
||||
sky130_fd_sc_hd__inv_1 sky130_fd_sc_hd__inv_2 sky130_fd_sc_hd__inv_4
|
||||
sky130_fd_sc_hd__buf_1 sky130_fd_sc_hd__buf_2 sky130_fd_sc_hd__buf_4
|
||||
|
|
@ -46,33 +65,28 @@ set sky130_cells_to_report {
|
|||
sky130_fd_sc_hd__clkbuf_1 sky130_fd_sc_hd__clkbuf_2
|
||||
sky130_fd_sc_hd__clkinv_1 sky130_fd_sc_hd__clkinv_2
|
||||
sky130_fd_sc_hd__conb_1
|
||||
sky130_fd_sc_hd__diode_2 sky130_fd_sc_hd__fill_1
|
||||
sky130_fd_sc_hd__diode_2
|
||||
}
|
||||
|
||||
foreach cell_name $sky130_cells_to_report {
|
||||
catch {
|
||||
report_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name
|
||||
}
|
||||
report_lib_cell sky130_fd_sc_hd__ff_n40C_1v95/$cell_name
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Cell property queries on Sky130
|
||||
# Cell property queries - slow corner library
|
||||
############################################################
|
||||
foreach cell_name {sky130_fd_sc_hd__inv_1 sky130_fd_sc_hd__buf_1
|
||||
sky130_fd_sc_hd__dfxtp_1 sky130_fd_sc_hd__dlxtp_1
|
||||
sky130_fd_sc_hd__sdfxtp_1 sky130_fd_sc_hd__ebufn_1
|
||||
sky130_fd_sc_hd__mux2_1 sky130_fd_sc_hd__fa_1} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
set area [get_property $cell area]
|
||||
set du [get_property $cell dont_use]
|
||||
set lp [get_property $cell cell_leakage_power]
|
||||
puts "$cell_name: area=$area dont_use=$du leakage=$lp"
|
||||
}
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__ss_n40C_1v40/$cell_name]
|
||||
set area [get_property $cell area]
|
||||
set du [get_property $cell dont_use]
|
||||
puts "$cell_name: area=$area dont_use=$du"
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Pin capacitance queries on Sky130
|
||||
# Pin capacitance queries - fast corner library
|
||||
############################################################
|
||||
foreach {cell_name pin_name} {
|
||||
sky130_fd_sc_hd__inv_1 A
|
||||
|
|
@ -90,53 +104,17 @@ foreach {cell_name pin_name} {
|
|||
sky130_fd_sc_hd__dfrtp_1 RESET_B
|
||||
sky130_fd_sc_hd__dfrtp_1 Q
|
||||
} {
|
||||
catch {
|
||||
set pin [get_lib_pin sky130_fd_sc_hd__tt_025C_1v80/$cell_name/$pin_name]
|
||||
set cap [get_property $pin capacitance]
|
||||
set dir [sta::liberty_port_direction $pin]
|
||||
puts "$cell_name/$pin_name: cap=$cap dir=$dir"
|
||||
}
|
||||
set pin [get_lib_pin sky130_fd_sc_hd__ff_n40C_1v95/$cell_name/$pin_name]
|
||||
set cap [get_property $pin capacitance]
|
||||
set dir [sta::liberty_port_direction $pin]
|
||||
puts "$cell_name/$pin_name: cap=$cap dir=$dir"
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Write all libraries to exercise all writer paths
|
||||
# Write libraries to exercise writer paths
|
||||
############################################################
|
||||
set outfile1 [make_result_file liberty_sky130_hd_tt.lib]
|
||||
sta::write_liberty sky130_fd_sc_hd__tt_025C_1v80 $outfile1
|
||||
set outfile1 [make_result_file liberty_sky130_hd_ff.lib]
|
||||
sta::write_liberty sky130_fd_sc_hd__ff_n40C_1v95 $outfile1
|
||||
|
||||
catch {
|
||||
set outfile2 [make_result_file liberty_sky130_hs_tt.lib]
|
||||
sta::write_liberty sky130_fd_sc_hs__tt_025C_1v80 $outfile2
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Read ASAP7 with various Vt combos to stress LibertyReader
|
||||
############################################################
|
||||
read_liberty ../../test/asap7/asap7sc7p5t_AO_LVT_FF_nldm_211120.lib.gz
|
||||
|
||||
read_liberty ../../test/asap7/asap7sc7p5t_AO_SLVT_FF_nldm_211120.lib.gz
|
||||
|
||||
read_liberty ../../test/asap7/asap7sc7p5t_OA_LVT_FF_nldm_211120.lib.gz
|
||||
|
||||
read_liberty ../../test/asap7/asap7sc7p5t_OA_SLVT_FF_nldm_211120.lib.gz
|
||||
|
||||
read_liberty ../../test/asap7/asap7sc7p5t_SIMPLE_LVT_FF_nldm_211120.lib.gz
|
||||
|
||||
read_liberty ../../test/asap7/asap7sc7p5t_SIMPLE_SLVT_FF_nldm_211120.lib.gz
|
||||
|
||||
read_liberty ../../test/asap7/asap7sc7p5t_INVBUF_LVT_TT_nldm_220122.lib.gz
|
||||
|
||||
read_liberty ../../test/asap7/asap7sc7p5t_INVBUF_SLVT_TT_nldm_220122.lib.gz
|
||||
|
||||
read_liberty ../../test/asap7/asap7sc7p5t_INVBUF_RVT_TT_nldm_220122.lib.gz
|
||||
|
||||
read_liberty ../../test/asap7/asap7sc7p5t_INVBUF_RVT_SS_nldm_220122.lib.gz
|
||||
|
||||
read_liberty ../../test/asap7/asap7sc7p5t_AO_RVT_SS_nldm_211120.lib.gz
|
||||
|
||||
read_liberty ../../test/asap7/asap7sc7p5t_OA_RVT_SS_nldm_211120.lib.gz
|
||||
|
||||
read_liberty ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz
|
||||
|
||||
# SRAM macro
|
||||
read_liberty ../../test/asap7/fakeram7_256x32.lib
|
||||
set outfile2 [make_result_file liberty_sky130_hd_ss.lib]
|
||||
sta::write_liberty sky130_fd_sc_hd__ss_n40C_1v40 $outfile2
|
||||
|
|
|
|||
|
|
@ -38,23 +38,19 @@ foreach arc $arcs {
|
|||
}
|
||||
|
||||
# sdfrtp has scan + async reset
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__sdfrtp_1]
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "sdfrtp_1 arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__sdfrtp_1]
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "sdfrtp_1 arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
|
||||
# sdfstp has scan + async set
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__sdfstp_1]
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "sdfstp_1 arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/sky130_fd_sc_hd__sdfstp_1]
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "sdfstp_1 arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
|
||||
############################################################
|
||||
|
|
@ -64,13 +60,11 @@ puts "--- tristate cell timing arcs ---"
|
|||
|
||||
foreach cell_name {sky130_fd_sc_hd__ebufn_1 sky130_fd_sc_hd__ebufn_2
|
||||
sky130_fd_sc_hd__ebufn_4 sky130_fd_sc_hd__ebufn_8} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "$cell_name arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "$cell_name arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -81,14 +75,12 @@ puts "--- clock gate cell timing arcs ---"
|
|||
|
||||
foreach cell_name {sky130_fd_sc_hd__dlclkp_1 sky130_fd_sc_hd__dlclkp_2
|
||||
sky130_fd_sc_hd__sdlclkp_1 sky130_fd_sc_hd__sdlclkp_2} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "$cell_name arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "$cell_name arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -100,14 +92,12 @@ puts "--- latch cell timing arcs ---"
|
|||
|
||||
foreach cell_name {sky130_fd_sc_hd__dlxtp_1 sky130_fd_sc_hd__dlxtn_1
|
||||
sky130_fd_sc_hd__dlxbn_1 sky130_fd_sc_hd__dlxbp_1} {
|
||||
catch {
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "$cell_name arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
set cell [get_lib_cell sky130_fd_sc_hd__tt_025C_1v80/$cell_name]
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "$cell_name arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -117,31 +107,25 @@ foreach cell_name {sky130_fd_sc_hd__dlxtp_1 sky130_fd_sc_hd__dlxtn_1
|
|||
############################################################
|
||||
read_liberty ../../test/asap7/asap7sc7p5t_SEQ_RVT_FF_nldm_220123.lib
|
||||
|
||||
catch {
|
||||
set cell [get_lib_cell asap7sc7p5t_SEQ_RVT_FF_nldm_220123/DFFHQNx1_ASAP7_75t_R]
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "DFFHQNx1 arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
set cell [get_lib_cell asap7sc7p5t_SEQ_RVT_FF_nldm_220123/DFFHQNx1_ASAP7_75t_R]
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "DFFHQNx1 arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
|
||||
catch {
|
||||
set cell [get_lib_cell asap7sc7p5t_SEQ_RVT_FF_nldm_220123/DLLx1_ASAP7_75t_R]
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "DLLx1 arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
set cell [get_lib_cell asap7sc7p5t_SEQ_RVT_FF_nldm_220123/DLLx1_ASAP7_75t_R]
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "DLLx1 arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
|
||||
catch {
|
||||
set cell [get_lib_cell asap7sc7p5t_SEQ_RVT_FF_nldm_220123/ICGx1_ASAP7_75t_R]
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "ICGx1 arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
set cell [get_lib_cell asap7sc7p5t_SEQ_RVT_FF_nldm_220123/ICGx1_ASAP7_75t_R]
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "ICGx1 arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
|
||||
############################################################
|
||||
|
|
@ -150,40 +134,34 @@ catch {
|
|||
read_liberty ../../test/ihp-sg13g2/sg13g2_stdcell_typ_1p20V_25C.lib
|
||||
|
||||
foreach cell_name {sg13g2_dlhq_1 sg13g2_dllq_1} {
|
||||
catch {
|
||||
set cell [get_lib_cell sg13g2_stdcell_typ_1p20V_25C/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "$cell_name arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
set cell [get_lib_cell sg13g2_stdcell_typ_1p20V_25C/$cell_name]
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "$cell_name arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach cell_name {sg13g2_dfrbp_1 sg13g2_dfrbp_2} {
|
||||
catch {
|
||||
set cell [get_lib_cell sg13g2_stdcell_typ_1p20V_25C/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "$cell_name arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
set cell [get_lib_cell sg13g2_stdcell_typ_1p20V_25C/$cell_name]
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "$cell_name arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach cell_name {sg13g2_sdfbbp_1} {
|
||||
catch {
|
||||
set cell [get_lib_cell sg13g2_stdcell_typ_1p20V_25C/$cell_name]
|
||||
if {$cell != "NULL"} {
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "$cell_name arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
set cell [get_lib_cell sg13g2_stdcell_typ_1p20V_25C/$cell_name]
|
||||
if {$cell != "NULL" && $cell ne ""} {
|
||||
set arcs [$cell timing_arc_sets]
|
||||
puts "$cell_name arc_sets = [llength $arcs]"
|
||||
foreach arc $arcs {
|
||||
puts " [$arc full_name] role=[$arc role]"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -220,13 +198,9 @@ read_liberty ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib
|
|||
|
||||
read_liberty ../../test/sky130hd/sky130_fd_sc_hd__ss_n40C_1v40.lib
|
||||
|
||||
catch {
|
||||
report_lib_cell sky130_fd_sc_hd__ff_n40C_1v95/sky130_fd_sc_hd__dfrtp_1
|
||||
}
|
||||
report_lib_cell sky130_fd_sc_hd__ff_n40C_1v95/sky130_fd_sc_hd__dfrtp_1
|
||||
|
||||
catch {
|
||||
report_lib_cell sky130_fd_sc_hd__ss_n40C_1v40/sky130_fd_sc_hd__dfrtp_1
|
||||
}
|
||||
report_lib_cell sky130_fd_sc_hd__ss_n40C_1v40/sky130_fd_sc_hd__dfrtp_1
|
||||
|
||||
############################################################
|
||||
# Write liberty
|
||||
|
|
|
|||
|
|
@ -1,2 +1,338 @@
|
|||
No paths found.
|
||||
No paths found.
|
||||
Startpoint: reg2 (rising edge-triggered flip-flop clocked by clk1)
|
||||
Endpoint: out1 (output port clocked by clk1)
|
||||
Path Group: clk1
|
||||
Path Type: max
|
||||
|
||||
Delay Time Description
|
||||
---------------------------------------------------------
|
||||
0.00 0.00 clock clk1 (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 ^ reg2/CK (DFF_X1)
|
||||
0.08 0.08 ^ reg2/Q (DFF_X1)
|
||||
0.00 0.08 ^ out1 (out)
|
||||
0.08 data arrival time
|
||||
|
||||
10.00 10.00 clock clk1 (rise edge)
|
||||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 10.00 clock reconvergence pessimism
|
||||
-3.00 7.00 output external delay
|
||||
7.00 data required time
|
||||
---------------------------------------------------------
|
||||
7.00 data required time
|
||||
-0.08 data arrival time
|
||||
---------------------------------------------------------
|
||||
6.92 slack (MET)
|
||||
|
||||
|
||||
Startpoint: reg2 (rising edge-triggered flip-flop clocked by clk1)
|
||||
Endpoint: out1 (output port clocked by clk1)
|
||||
Path Group: clk1
|
||||
Path Type: max
|
||||
|
||||
Delay Time Description
|
||||
---------------------------------------------------------
|
||||
0.00 0.00 clock clk1 (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 ^ reg2/CK (DFF_X1)
|
||||
0.08 0.08 ^ reg2/Q (DFF_X1)
|
||||
0.00 0.08 ^ out1 (out)
|
||||
0.08 data arrival time
|
||||
|
||||
10.00 10.00 clock clk1 (rise edge)
|
||||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 10.00 clock reconvergence pessimism
|
||||
-3.00 7.00 output external delay
|
||||
7.00 data required time
|
||||
---------------------------------------------------------
|
||||
7.00 data required time
|
||||
-0.08 data arrival time
|
||||
---------------------------------------------------------
|
||||
6.92 slack (MET)
|
||||
|
||||
|
||||
Startpoint: reg2 (rising edge-triggered flip-flop clocked by clk1)
|
||||
Endpoint: out1 (output port clocked by clk1)
|
||||
Path Group: clk1
|
||||
Path Type: max
|
||||
|
||||
Delay Time Description
|
||||
---------------------------------------------------------
|
||||
0.00 0.00 clock clk1 (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 ^ reg2/CK (DFF_X1)
|
||||
0.08 0.08 ^ reg2/Q (DFF_X1)
|
||||
0.00 0.08 ^ out1 (out)
|
||||
0.08 data arrival time
|
||||
|
||||
10.00 10.00 clock clk1 (rise edge)
|
||||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 10.00 clock reconvergence pessimism
|
||||
-3.00 7.00 output external delay
|
||||
7.00 data required time
|
||||
---------------------------------------------------------
|
||||
7.00 data required time
|
||||
-0.08 data arrival time
|
||||
---------------------------------------------------------
|
||||
6.92 slack (MET)
|
||||
|
||||
|
||||
Startpoint: reg2 (rising edge-triggered flip-flop clocked by clk1)
|
||||
Endpoint: out1 (output port clocked by clk1)
|
||||
Path Group: clk1
|
||||
Path Type: max
|
||||
|
||||
Delay Time Description
|
||||
---------------------------------------------------------
|
||||
0.00 0.00 clock clk1 (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 ^ reg2/CK (DFF_X1)
|
||||
0.08 0.08 ^ reg2/Q (DFF_X1)
|
||||
0.00 0.08 ^ out1 (out)
|
||||
0.08 data arrival time
|
||||
|
||||
10.00 10.00 clock clk1 (rise edge)
|
||||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 10.00 clock reconvergence pessimism
|
||||
-3.00 7.00 output external delay
|
||||
7.00 data required time
|
||||
---------------------------------------------------------
|
||||
7.00 data required time
|
||||
-0.08 data arrival time
|
||||
---------------------------------------------------------
|
||||
6.92 slack (MET)
|
||||
|
||||
|
||||
Startpoint: reg2 (rising edge-triggered flip-flop clocked by clk1)
|
||||
Endpoint: out1 (output port clocked by clk1)
|
||||
Path Group: clk1
|
||||
Path Type: max
|
||||
|
||||
Delay Time Description
|
||||
---------------------------------------------------------
|
||||
0.00 0.00 clock clk1 (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 ^ reg2/CK (DFF_X1)
|
||||
0.08 0.08 ^ reg2/Q (DFF_X1)
|
||||
0.00 0.08 ^ out1 (out)
|
||||
0.08 data arrival time
|
||||
|
||||
10.00 10.00 clock clk1 (rise edge)
|
||||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 10.00 clock reconvergence pessimism
|
||||
-3.00 7.00 output external delay
|
||||
7.00 data required time
|
||||
---------------------------------------------------------
|
||||
7.00 data required time
|
||||
-0.08 data arrival time
|
||||
---------------------------------------------------------
|
||||
6.92 slack (MET)
|
||||
|
||||
|
||||
Startpoint: reg2 (rising edge-triggered flip-flop clocked by clk1)
|
||||
Endpoint: out1 (output port clocked by clk1)
|
||||
Path Group: clk1
|
||||
Path Type: max
|
||||
|
||||
Delay Time Description
|
||||
---------------------------------------------------------
|
||||
0.00 0.00 clock clk1 (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 ^ reg2/CK (DFF_X1)
|
||||
0.08 0.08 ^ reg2/Q (DFF_X1)
|
||||
0.00 0.08 ^ out1 (out)
|
||||
0.08 data arrival time
|
||||
|
||||
10.00 10.00 clock clk1 (rise edge)
|
||||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 10.00 clock reconvergence pessimism
|
||||
-3.00 7.00 output external delay
|
||||
7.00 data required time
|
||||
---------------------------------------------------------
|
||||
7.00 data required time
|
||||
-0.08 data arrival time
|
||||
---------------------------------------------------------
|
||||
6.92 slack (MET)
|
||||
|
||||
|
||||
Startpoint: reg2 (rising edge-triggered flip-flop clocked by clk1)
|
||||
Endpoint: out1 (output port clocked by clk1)
|
||||
Path Group: clk1
|
||||
Path Type: max
|
||||
|
||||
Delay Time Description
|
||||
---------------------------------------------------------
|
||||
0.00 0.00 clock clk1 (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 ^ reg2/CK (DFF_X1)
|
||||
0.08 0.08 ^ reg2/Q (DFF_X1)
|
||||
0.00 0.08 ^ out1 (out)
|
||||
0.08 data arrival time
|
||||
|
||||
10.00 10.00 clock clk1 (rise edge)
|
||||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 10.00 clock reconvergence pessimism
|
||||
-3.00 7.00 output external delay
|
||||
7.00 data required time
|
||||
---------------------------------------------------------
|
||||
7.00 data required time
|
||||
-0.08 data arrival time
|
||||
---------------------------------------------------------
|
||||
6.92 slack (MET)
|
||||
|
||||
|
||||
Startpoint: reg2 (rising edge-triggered flip-flop clocked by clk1)
|
||||
Endpoint: out1 (output port clocked by clk1)
|
||||
Path Group: clk1
|
||||
Path Type: max
|
||||
|
||||
Delay Time Description
|
||||
---------------------------------------------------------
|
||||
0.00 0.00 clock clk1 (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 ^ reg2/CK (DFF_X1)
|
||||
0.08 0.08 ^ reg2/Q (DFF_X1)
|
||||
0.00 0.08 ^ out1 (out)
|
||||
0.08 data arrival time
|
||||
|
||||
10.00 10.00 clock clk1 (rise edge)
|
||||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 10.00 clock reconvergence pessimism
|
||||
-3.00 7.00 output external delay
|
||||
7.00 data required time
|
||||
---------------------------------------------------------
|
||||
7.00 data required time
|
||||
-0.08 data arrival time
|
||||
---------------------------------------------------------
|
||||
6.92 slack (MET)
|
||||
|
||||
|
||||
Startpoint: reg2 (rising edge-triggered flip-flop clocked by clk1)
|
||||
Endpoint: out1 (output port clocked by clk1)
|
||||
Path Group: clk1
|
||||
Path Type: max
|
||||
|
||||
Delay Time Description
|
||||
---------------------------------------------------------
|
||||
0.00 0.00 clock clk1 (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 ^ reg2/CK (DFF_X1)
|
||||
0.08 0.08 ^ reg2/Q (DFF_X1)
|
||||
0.00 0.08 ^ out1 (out)
|
||||
0.08 data arrival time
|
||||
|
||||
10.00 10.00 clock clk1 (rise edge)
|
||||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 10.00 clock reconvergence pessimism
|
||||
-3.00 7.00 output external delay
|
||||
7.00 data required time
|
||||
---------------------------------------------------------
|
||||
7.00 data required time
|
||||
-0.08 data arrival time
|
||||
---------------------------------------------------------
|
||||
6.92 slack (MET)
|
||||
|
||||
|
||||
Startpoint: reg2 (rising edge-triggered flip-flop clocked by clk1)
|
||||
Endpoint: out1 (output port clocked by clk1)
|
||||
Path Group: clk1
|
||||
Path Type: max
|
||||
|
||||
Delay Time Description
|
||||
---------------------------------------------------------
|
||||
0.00 0.00 clock clk1 (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 ^ reg2/CK (DFF_X1)
|
||||
0.08 0.08 ^ reg2/Q (DFF_X1)
|
||||
0.00 0.08 ^ out1 (out)
|
||||
0.08 data arrival time
|
||||
|
||||
10.00 10.00 clock clk1 (rise edge)
|
||||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 10.00 clock reconvergence pessimism
|
||||
-3.00 7.00 output external delay
|
||||
7.00 data required time
|
||||
---------------------------------------------------------
|
||||
7.00 data required time
|
||||
-0.08 data arrival time
|
||||
---------------------------------------------------------
|
||||
6.92 slack (MET)
|
||||
|
||||
|
||||
Startpoint: reg2 (rising edge-triggered flip-flop clocked by clk1)
|
||||
Endpoint: out1 (output port clocked by clk1)
|
||||
Path Group: clk1
|
||||
Path Type: max
|
||||
|
||||
Delay Time Description
|
||||
---------------------------------------------------------
|
||||
0.00 0.00 clock clk1 (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 ^ reg2/CK (DFF_X1)
|
||||
0.08 0.08 ^ reg2/Q (DFF_X1)
|
||||
0.00 0.08 ^ out1 (out)
|
||||
0.08 data arrival time
|
||||
|
||||
10.00 10.00 clock clk1 (rise edge)
|
||||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 10.00 clock reconvergence pessimism
|
||||
-3.00 7.00 output external delay
|
||||
7.00 data required time
|
||||
---------------------------------------------------------
|
||||
7.00 data required time
|
||||
-0.08 data arrival time
|
||||
---------------------------------------------------------
|
||||
6.92 slack (MET)
|
||||
|
||||
|
||||
Startpoint: reg2 (rising edge-triggered flip-flop clocked by clk1)
|
||||
Endpoint: out1 (output port clocked by clk1)
|
||||
Path Group: clk1
|
||||
Path Type: max
|
||||
|
||||
Delay Time Description
|
||||
---------------------------------------------------------
|
||||
0.00 0.00 clock clk1 (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 ^ reg2/CK (DFF_X1)
|
||||
0.08 0.08 ^ reg2/Q (DFF_X1)
|
||||
0.00 0.08 ^ out1 (out)
|
||||
0.08 data arrival time
|
||||
|
||||
10.00 10.00 clock clk1 (rise edge)
|
||||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 10.00 clock reconvergence pessimism
|
||||
-3.00 7.00 output external delay
|
||||
7.00 data required time
|
||||
---------------------------------------------------------
|
||||
7.00 data required time
|
||||
-0.08 data arrival time
|
||||
---------------------------------------------------------
|
||||
6.92 slack (MET)
|
||||
|
||||
|
||||
Startpoint: reg2 (rising edge-triggered flip-flop clocked by clk1)
|
||||
Endpoint: out1 (output port clocked by clk1)
|
||||
Path Group: clk1
|
||||
Path Type: max
|
||||
|
||||
Delay Time Description
|
||||
---------------------------------------------------------
|
||||
0.00 0.00 clock clk1 (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 ^ reg2/CK (DFF_X1)
|
||||
0.08 0.08 ^ reg2/Q (DFF_X1)
|
||||
0.00 0.08 ^ out1 (out)
|
||||
0.08 data arrival time
|
||||
|
||||
10.00 10.00 clock clk1 (rise edge)
|
||||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 10.00 clock reconvergence pessimism
|
||||
-3.00 7.00 output external delay
|
||||
7.00 data required time
|
||||
---------------------------------------------------------
|
||||
7.00 data required time
|
||||
-0.08 data arrival time
|
||||
---------------------------------------------------------
|
||||
6.92 slack (MET)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -12,41 +12,7 @@ read_verilog ../../sdc/test/sdc_test2.v
|
|||
link_design sdc_test2
|
||||
|
||||
############################################################
|
||||
# Wire load model queries
|
||||
############################################################
|
||||
|
||||
# Set various wire load models (Nangate has multiple)
|
||||
# Nangate has 1K, 3K, 5K wireload models with different h/v ratios
|
||||
set_wire_load_model -name "1K_hvratio_1_1"
|
||||
|
||||
set_wire_load_model -name "1K_hvratio_1_2"
|
||||
|
||||
set_wire_load_model -name "1K_hvratio_1_4"
|
||||
|
||||
set_wire_load_model -name "3K_hvratio_1_1"
|
||||
|
||||
set_wire_load_model -name "3K_hvratio_1_2"
|
||||
|
||||
set_wire_load_model -name "3K_hvratio_1_4"
|
||||
|
||||
set_wire_load_model -name "5K_hvratio_1_1"
|
||||
|
||||
set_wire_load_model -name "5K_hvratio_1_2"
|
||||
|
||||
set_wire_load_model -name "5K_hvratio_1_4"
|
||||
|
||||
############################################################
|
||||
# Wire load mode switching (exercises wireloadModeString)
|
||||
############################################################
|
||||
|
||||
set_wire_load_mode top
|
||||
|
||||
set_wire_load_mode enclosed
|
||||
|
||||
set_wire_load_mode segmented
|
||||
|
||||
############################################################
|
||||
# Setup constraints and report
|
||||
# Setup constraints (needed before report_checks)
|
||||
############################################################
|
||||
|
||||
create_clock -name clk1 -period 10 [get_ports clk1]
|
||||
|
|
@ -56,8 +22,49 @@ set_input_delay -clock clk1 2.0 [get_ports in3]
|
|||
set_output_delay -clock clk1 3.0 [get_ports out1]
|
||||
set_output_delay -clock clk1 3.0 [get_ports out2]
|
||||
|
||||
# Report checks with wire load
|
||||
report_checks -from [get_ports in1] -to [get_ports out1]
|
||||
############################################################
|
||||
# Wire load model queries - report_checks after each to show timing impact
|
||||
############################################################
|
||||
|
||||
set_wire_load_model -name "1K_hvratio_1_1"
|
||||
report_checks
|
||||
|
||||
set_wire_load_model -name "1K_hvratio_1_2"
|
||||
report_checks
|
||||
|
||||
set_wire_load_model -name "1K_hvratio_1_4"
|
||||
report_checks
|
||||
|
||||
set_wire_load_model -name "3K_hvratio_1_1"
|
||||
report_checks
|
||||
|
||||
set_wire_load_model -name "3K_hvratio_1_2"
|
||||
report_checks
|
||||
|
||||
set_wire_load_model -name "3K_hvratio_1_4"
|
||||
report_checks
|
||||
|
||||
set_wire_load_model -name "5K_hvratio_1_1"
|
||||
report_checks
|
||||
|
||||
set_wire_load_model -name "5K_hvratio_1_2"
|
||||
report_checks
|
||||
|
||||
set_wire_load_model -name "5K_hvratio_1_4"
|
||||
report_checks
|
||||
|
||||
############################################################
|
||||
# Wire load mode switching (exercises wireloadModeString)
|
||||
############################################################
|
||||
|
||||
set_wire_load_mode top
|
||||
report_checks
|
||||
|
||||
set_wire_load_mode enclosed
|
||||
report_checks
|
||||
|
||||
set_wire_load_mode segmented
|
||||
report_checks
|
||||
|
||||
############################################################
|
||||
# Write SDC with wireload info
|
||||
|
|
@ -105,4 +112,4 @@ sta::write_liberty sg13g2_stdcell_typ_1p20V_25C $outfile3
|
|||
|
||||
set_operating_conditions typical
|
||||
|
||||
report_checks -from [get_ports in1] -to [get_ports out1]
|
||||
report_checks
|
||||
|
|
|
|||
|
|
@ -82,58 +82,48 @@ foreach cell_name {INV_X1 BUF_X1 NAND2_X1 NOR2_X1 AND2_X1 OR2_X1
|
|||
|
||||
# Sequential cells (rising_edge, setup_rising, hold_rising, etc.)
|
||||
foreach cell_name {DFF_X1 DFF_X2 DFFR_X1 DFFS_X1 DFFRS_X1} {
|
||||
catch {
|
||||
set cell [get_lib_cell NangateOpenCellLibrary/$cell_name]
|
||||
set arc_sets [$cell timing_arc_sets]
|
||||
puts "$cell_name: [llength $arc_sets] arc sets"
|
||||
}
|
||||
set cell [get_lib_cell NangateOpenCellLibrary/$cell_name]
|
||||
set arc_sets [$cell timing_arc_sets]
|
||||
puts "$cell_name: [llength $arc_sets] arc sets"
|
||||
}
|
||||
|
||||
# Tristate cells (three_state_enable, three_state_disable)
|
||||
foreach cell_name {TINV_X1 TBUF_X1 TBUF_X2} {
|
||||
catch {
|
||||
set cell [get_lib_cell NangateOpenCellLibrary/$cell_name]
|
||||
set arc_sets [$cell timing_arc_sets]
|
||||
puts "$cell_name: [llength $arc_sets] arc sets"
|
||||
foreach arc_set $arc_sets {
|
||||
set role [$arc_set role]
|
||||
puts " role=$role"
|
||||
}
|
||||
set cell [get_lib_cell NangateOpenCellLibrary/$cell_name]
|
||||
set arc_sets [$cell timing_arc_sets]
|
||||
puts "$cell_name: [llength $arc_sets] arc sets"
|
||||
foreach arc_set $arc_sets {
|
||||
set role [$arc_set role]
|
||||
puts " role=$role"
|
||||
}
|
||||
}
|
||||
|
||||
# Scan cells (exercises test_cell and scan paths)
|
||||
foreach cell_name {SDFF_X1 SDFFR_X1 SDFFS_X1 SDFFRS_X1} {
|
||||
catch {
|
||||
set cell [get_lib_cell NangateOpenCellLibrary/$cell_name]
|
||||
set arc_sets [$cell timing_arc_sets]
|
||||
puts "$cell_name: [llength $arc_sets] arc sets"
|
||||
}
|
||||
set cell [get_lib_cell NangateOpenCellLibrary/$cell_name]
|
||||
set arc_sets [$cell timing_arc_sets]
|
||||
puts "$cell_name: [llength $arc_sets] arc sets"
|
||||
}
|
||||
|
||||
# Clock gate cell (may have min_pulse_width arcs)
|
||||
foreach cell_name {CLKGATETST_X1 CLKGATETST_X2 CLKGATETST_X4} {
|
||||
catch {
|
||||
set cell [get_lib_cell NangateOpenCellLibrary/$cell_name]
|
||||
set arc_sets [$cell timing_arc_sets]
|
||||
puts "$cell_name: [llength $arc_sets] arc sets"
|
||||
foreach arc_set $arc_sets {
|
||||
set role [$arc_set role]
|
||||
puts " role=$role"
|
||||
}
|
||||
set cell [get_lib_cell NangateOpenCellLibrary/$cell_name]
|
||||
set arc_sets [$cell timing_arc_sets]
|
||||
puts "$cell_name: [llength $arc_sets] arc sets"
|
||||
foreach arc_set $arc_sets {
|
||||
set role [$arc_set role]
|
||||
puts " role=$role"
|
||||
}
|
||||
}
|
||||
|
||||
# Latch cells (latch_enable, latch_d_to_q)
|
||||
foreach cell_name {TLAT_X1} {
|
||||
catch {
|
||||
set cell [get_lib_cell NangateOpenCellLibrary/$cell_name]
|
||||
set arc_sets [$cell timing_arc_sets]
|
||||
puts "$cell_name: [llength $arc_sets] arc sets"
|
||||
foreach arc_set $arc_sets {
|
||||
set role [$arc_set role]
|
||||
puts " role=$role"
|
||||
}
|
||||
set cell [get_lib_cell NangateOpenCellLibrary/$cell_name]
|
||||
set arc_sets [$cell timing_arc_sets]
|
||||
puts "$cell_name: [llength $arc_sets] arc sets"
|
||||
foreach arc_set $arc_sets {
|
||||
set role [$arc_set role]
|
||||
puts " role=$role"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,18 +73,18 @@ for {set i 0} {$i < 6} {incr i} {
|
|||
puts "created [llength $net_list] nets"
|
||||
|
||||
# Connect BUF_X1 input
|
||||
catch {connect_pin lifecycle_net_0 lifecycle_inst_0/A} msg
|
||||
set msg [connect_pin lifecycle_net_0 lifecycle_inst_0/A]
|
||||
puts "connect lifecycle_inst_0/A: $msg"
|
||||
|
||||
# Connect BUF_X1 output
|
||||
catch {connect_pin lifecycle_net_1 lifecycle_inst_0/Z} msg
|
||||
set msg [connect_pin lifecycle_net_1 lifecycle_inst_0/Z]
|
||||
puts "connect lifecycle_inst_0/Z: $msg"
|
||||
|
||||
# Connect INV_X1 input/output
|
||||
catch {connect_pin lifecycle_net_1 lifecycle_inst_3/A} msg
|
||||
set msg [connect_pin lifecycle_net_1 lifecycle_inst_3/A]
|
||||
puts "connect lifecycle_inst_3/A: $msg"
|
||||
|
||||
catch {connect_pin lifecycle_net_2 lifecycle_inst_3/ZN} msg
|
||||
set msg [connect_pin lifecycle_net_2 lifecycle_inst_3/ZN]
|
||||
puts "connect lifecycle_inst_3/ZN: $msg"
|
||||
|
||||
# Report net with connected pins (exercises connectedPinIterator)
|
||||
|
|
|
|||
|
|
@ -70,13 +70,8 @@ set sub2_hier_pins [get_pins -hierarchical sub2/*]
|
|||
puts "sub2/* pins (hier): [llength $sub2_hier_pins]"
|
||||
|
||||
# Query specific pin paths through hierarchy
|
||||
catch {
|
||||
set sub1_and [get_pins sub1/and_gate/A1]
|
||||
puts "sub1/and_gate/A1: [get_full_name $sub1_and]"
|
||||
} msg
|
||||
if {[string match "*Error*" $msg] || [string match "*not found*" $msg]} {
|
||||
puts "sub1/and_gate/A1: not accessible (flat network)"
|
||||
}
|
||||
set sub1_and [get_pins sub1/and_gate/A1]
|
||||
puts "sub1/and_gate/A1: [get_full_name $sub1_and]"
|
||||
|
||||
# Top-level instance pins (port pins)
|
||||
set port_pins_in [get_pins -hierarchical */A]
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ set ref [get_property $buf1_inst ref_name]
|
|||
puts "buf1 ref_name after replace: $ref"
|
||||
|
||||
puts "--- disconnect remaining new_buf pins ---"
|
||||
catch {disconnect_pin new_net2 new_buf/Z} msg_disc2
|
||||
set msg_disc2 [disconnect_pin new_net2 new_buf/Z]
|
||||
puts "disconnect new_buf/Z: $msg_disc2"
|
||||
|
||||
puts "--- delete_instance new_buf ---"
|
||||
|
|
|
|||
|
|
@ -30,38 +30,18 @@ set_input_transition 0.1 [get_ports {data_a[*] data_b[*] clk}]
|
|||
puts "--- bus range queries ---"
|
||||
|
||||
# Query using range notation
|
||||
catch {
|
||||
set range_ports [get_ports {data_a[0:3]}]
|
||||
puts "data_a\[0:3\] ports: [llength $range_ports]"
|
||||
} msg
|
||||
if {[string match "*Error*" $msg]} {
|
||||
puts "data_a\[0:3\]: $msg"
|
||||
}
|
||||
set range_ports [get_ports {data_a[0:3]}]
|
||||
puts "data_a\[0:3\] ports: [llength $range_ports]"
|
||||
|
||||
catch {
|
||||
set range_ports2 [get_ports {data_a[4:7]}]
|
||||
puts "data_a\[4:7\] ports: [llength $range_ports2]"
|
||||
} msg
|
||||
if {[string match "*Error*" $msg]} {
|
||||
puts "data_a\[4:7\]: $msg"
|
||||
}
|
||||
set range_ports2 [get_ports {data_a[4:7]}]
|
||||
puts "data_a\[4:7\] ports: [llength $range_ports2]"
|
||||
|
||||
catch {
|
||||
set range_ports3 [get_ports {result[0:3]}]
|
||||
puts "result\[0:3\] ports: [llength $range_ports3]"
|
||||
} msg
|
||||
if {[string match "*Error*" $msg]} {
|
||||
puts "result\[0:3\]: $msg"
|
||||
}
|
||||
set range_ports3 [get_ports {result[0:3]}]
|
||||
puts "result\[0:3\] ports: [llength $range_ports3]"
|
||||
|
||||
# Reverse range (exercises from > to swap in findPortsMatching)
|
||||
catch {
|
||||
set rev_range [get_ports {data_b[7:0]}]
|
||||
puts "data_b\[7:0\] ports: [llength $rev_range]"
|
||||
} msg
|
||||
if {[string match "*Error*" $msg]} {
|
||||
puts "data_b\[7:0\]: $msg"
|
||||
}
|
||||
set rev_range [get_ports {data_b[7:0]}]
|
||||
puts "data_b\[7:0\] ports: [llength $rev_range]"
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# Test wildcard subscript queries
|
||||
|
|
|
|||
|
|
@ -26,19 +26,19 @@ set_propagated_clock {clk1 clk2 clk3}
|
|||
puts "--- Test 1: set and query pi model ---"
|
||||
|
||||
# Set pi models on driver pins (both rise and fall)
|
||||
catch {sta::set_pi_model u1/Y 0.005 10.0 0.003} msg
|
||||
set msg [sta::set_pi_model u1/Y 0.005 10.0 0.003]
|
||||
puts "set_pi_model u1/Y: $msg"
|
||||
|
||||
catch {sta::set_pi_model u2/Y 0.008 15.0 0.005} msg
|
||||
set msg [sta::set_pi_model u2/Y 0.008 15.0 0.005]
|
||||
puts "set_pi_model u2/Y: $msg"
|
||||
|
||||
catch {sta::set_pi_model r1/Q 0.002 5.0 0.001} msg
|
||||
set msg [sta::set_pi_model r1/Q 0.002 5.0 0.001]
|
||||
puts "set_pi_model r1/Q: $msg"
|
||||
|
||||
catch {sta::set_pi_model r2/Q 0.003 6.0 0.002} msg
|
||||
set msg [sta::set_pi_model r2/Q 0.003 6.0 0.002]
|
||||
puts "set_pi_model r2/Q: $msg"
|
||||
|
||||
catch {sta::set_pi_model r3/Q 0.001 2.0 0.001} msg
|
||||
set msg [sta::set_pi_model r3/Q 0.001 2.0 0.001]
|
||||
puts "set_pi_model r3/Q: $msg"
|
||||
|
||||
# Query pi models back using find_pi_elmore
|
||||
|
|
@ -85,19 +85,19 @@ catch {
|
|||
#---------------------------------------------------------------
|
||||
puts "--- Test 2: set and query elmore ---"
|
||||
|
||||
catch {sta::set_elmore u1/Y u2/A 0.005} msg
|
||||
set msg [sta::set_elmore u1/Y u2/A 0.005]
|
||||
puts "set_elmore u1/Y -> u2/A: $msg"
|
||||
|
||||
catch {sta::set_elmore u2/Y r3/D 0.008} msg
|
||||
set msg [sta::set_elmore u2/Y r3/D 0.008]
|
||||
puts "set_elmore u2/Y -> r3/D: $msg"
|
||||
|
||||
catch {sta::set_elmore r1/Q u1/A 0.003} msg
|
||||
set msg [sta::set_elmore r1/Q u1/A 0.003]
|
||||
puts "set_elmore r1/Q -> u1/A: $msg"
|
||||
|
||||
catch {sta::set_elmore r2/Q u2/B 0.004} msg
|
||||
set msg [sta::set_elmore r2/Q u2/B 0.004]
|
||||
puts "set_elmore r2/Q -> u2/B: $msg"
|
||||
|
||||
catch {sta::set_elmore r3/Q out 0.002} msg
|
||||
set msg [sta::set_elmore r3/Q out 0.002]
|
||||
puts "set_elmore r3/Q -> out: $msg"
|
||||
|
||||
# Query elmore values back
|
||||
|
|
@ -169,17 +169,17 @@ report_parasitic_annotation -report_unannotated
|
|||
puts "--- Test 5: override manual parasitics ---"
|
||||
|
||||
# Re-set pi model with different values
|
||||
catch {sta::set_pi_model u1/Y 0.01 20.0 0.008} msg
|
||||
set msg [sta::set_pi_model u1/Y 0.01 20.0 0.008]
|
||||
puts "re-set pi_model u1/Y: $msg"
|
||||
|
||||
catch {sta::set_pi_model u2/Y 0.02 30.0 0.01} msg
|
||||
set msg [sta::set_pi_model u2/Y 0.02 30.0 0.01]
|
||||
puts "re-set pi_model u2/Y: $msg"
|
||||
|
||||
# Re-set elmore with different values
|
||||
catch {sta::set_elmore u1/Y u2/A 0.01} msg
|
||||
set msg [sta::set_elmore u1/Y u2/A 0.01]
|
||||
puts "re-set elmore u1/Y -> u2/A: $msg"
|
||||
|
||||
catch {sta::set_elmore u2/Y r3/D 0.02} msg
|
||||
set msg [sta::set_elmore u2/Y r3/D 0.02]
|
||||
puts "re-set elmore u2/Y -> r3/D: $msg"
|
||||
|
||||
report_checks
|
||||
|
|
@ -255,19 +255,19 @@ report_checks -format full_clock
|
|||
|
||||
# report_net with SPEF parasitics
|
||||
foreach net_name {r1q r2q u1z u2z out in1 in2 clk1 clk2 clk3} {
|
||||
catch {report_net -digits 6 $net_name} msg
|
||||
report_net -digits 6 $net_name
|
||||
puts "report_net $net_name: done"
|
||||
}
|
||||
|
||||
# Dcalc reports
|
||||
catch {report_dcalc -from [get_pins u1/A] -to [get_pins u1/Y] -max -digits 6} msg
|
||||
report_dcalc -from [get_pins u1/A] -to [get_pins u1/Y] -max -digits 6
|
||||
puts "dcalc u1 6 digits: done"
|
||||
|
||||
catch {report_dcalc -from [get_pins u2/A] -to [get_pins u2/Y] -max -digits 4} msg
|
||||
report_dcalc -from [get_pins u2/A] -to [get_pins u2/Y] -max -digits 4
|
||||
puts "dcalc u2 4 digits: done"
|
||||
|
||||
catch {report_dcalc -from [get_pins r1/CLK] -to [get_pins r1/Q] -max} msg
|
||||
report_dcalc -from [get_pins r1/CLK] -to [get_pins r1/Q] -max
|
||||
puts "dcalc r1 CK->Q: done"
|
||||
|
||||
catch {report_dcalc -from [get_pins r3/CLK] -to [get_pins r3/Q] -max} msg
|
||||
report_dcalc -from [get_pins r3/CLK] -to [get_pins r3/Q] -max
|
||||
puts "dcalc r3 CK->Q: done"
|
||||
|
|
|
|||
|
|
@ -59,22 +59,22 @@ report_checks -corner slow -fields {slew cap input_pins} -format full_clock
|
|||
#---------------------------------------------------------------
|
||||
puts "--- report_dcalc per corner ---"
|
||||
|
||||
catch {report_dcalc -corner fast -from [get_pins u1/A] -to [get_pins u1/Y]} msg
|
||||
set msg [report_dcalc -corner fast -from [get_pins u1/A] -to [get_pins u1/Y]]
|
||||
puts $msg
|
||||
|
||||
catch {report_dcalc -corner slow -from [get_pins u1/A] -to [get_pins u1/Y]} msg
|
||||
set msg [report_dcalc -corner slow -from [get_pins u1/A] -to [get_pins u1/Y]]
|
||||
puts $msg
|
||||
|
||||
catch {report_dcalc -corner fast -from [get_pins u2/A] -to [get_pins u2/Y]} msg
|
||||
set msg [report_dcalc -corner fast -from [get_pins u2/A] -to [get_pins u2/Y]]
|
||||
puts $msg
|
||||
|
||||
catch {report_dcalc -corner slow -from [get_pins u2/A] -to [get_pins u2/Y]} msg
|
||||
set msg [report_dcalc -corner slow -from [get_pins u2/A] -to [get_pins u2/Y]]
|
||||
puts $msg
|
||||
|
||||
catch {report_dcalc -corner fast -from [get_pins r1/CLK] -to [get_pins r1/Q]} msg
|
||||
set msg [report_dcalc -corner fast -from [get_pins r1/CLK] -to [get_pins r1/Q]]
|
||||
puts $msg
|
||||
|
||||
catch {report_dcalc -corner slow -from [get_pins r1/CLK] -to [get_pins r1/Q]} msg
|
||||
set msg [report_dcalc -corner slow -from [get_pins r1/CLK] -to [get_pins r1/Q]]
|
||||
puts $msg
|
||||
|
||||
#---------------------------------------------------------------
|
||||
|
|
@ -82,16 +82,16 @@ puts $msg
|
|||
#---------------------------------------------------------------
|
||||
puts "--- report_net per corner ---"
|
||||
|
||||
catch {report_net -corner fast r1q} msg
|
||||
set msg [report_net -corner fast r1q]
|
||||
puts $msg
|
||||
|
||||
catch {report_net -corner slow r1q} msg
|
||||
set msg [report_net -corner slow r1q]
|
||||
puts $msg
|
||||
|
||||
catch {report_net -corner fast u2z} msg
|
||||
set msg [report_net -corner fast u2z]
|
||||
puts $msg
|
||||
|
||||
catch {report_net -corner slow u2z} msg
|
||||
set msg [report_net -corner slow u2z]
|
||||
puts $msg
|
||||
|
||||
#---------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -33,23 +33,23 @@ report_parasitic_annotation -report_unannotated
|
|||
puts "--- set_pi_model on drivers ---"
|
||||
|
||||
# Set pi model on u1/Y (driver of net u1z)
|
||||
catch {sta::set_pi_model u1/Y 0.005 10.0 0.003} msg
|
||||
set msg [sta::set_pi_model u1/Y 0.005 10.0 0.003]
|
||||
puts "set_pi_model u1/Y: $msg"
|
||||
|
||||
# Set pi model on u2/Y (driver of net u2z)
|
||||
catch {sta::set_pi_model u2/Y 0.008 15.0 0.005} msg
|
||||
set msg [sta::set_pi_model u2/Y 0.008 15.0 0.005]
|
||||
puts "set_pi_model u2/Y: $msg"
|
||||
|
||||
# Set pi model on r1/Q (driver of r1q)
|
||||
catch {sta::set_pi_model r1/Q 0.002 5.0 0.001} msg
|
||||
set msg [sta::set_pi_model r1/Q 0.002 5.0 0.001]
|
||||
puts "set_pi_model r1/Q: $msg"
|
||||
|
||||
# Set pi model on r2/Q (driver of r2q)
|
||||
catch {sta::set_pi_model r2/Q 0.002 5.0 0.001} msg
|
||||
set msg [sta::set_pi_model r2/Q 0.002 5.0 0.001]
|
||||
puts "set_pi_model r2/Q: $msg"
|
||||
|
||||
# Set pi model on r3/Q (driver of out)
|
||||
catch {sta::set_pi_model r3/Q 0.001 2.0 0.001} msg
|
||||
set msg [sta::set_pi_model r3/Q 0.001 2.0 0.001]
|
||||
puts "set_pi_model r3/Q: $msg"
|
||||
|
||||
#---------------------------------------------------------------
|
||||
|
|
@ -59,23 +59,23 @@ puts "set_pi_model r3/Q: $msg"
|
|||
puts "--- set_elmore on loads ---"
|
||||
|
||||
# Elmore delays from u1/Y to its loads
|
||||
catch {sta::set_elmore u1/Y u2/A 0.005} msg
|
||||
set msg [sta::set_elmore u1/Y u2/A 0.005]
|
||||
puts "set_elmore u1/Y -> u2/A: $msg"
|
||||
|
||||
# Elmore delays from u2/Y to its loads
|
||||
catch {sta::set_elmore u2/Y r3/D 0.008} msg
|
||||
set msg [sta::set_elmore u2/Y r3/D 0.008]
|
||||
puts "set_elmore u2/Y -> r3/D: $msg"
|
||||
|
||||
# Elmore delays from r1/Q to loads
|
||||
catch {sta::set_elmore r1/Q u1/A 0.003} msg
|
||||
set msg [sta::set_elmore r1/Q u1/A 0.003]
|
||||
puts "set_elmore r1/Q -> u1/A: $msg"
|
||||
|
||||
# Elmore delays from r2/Q to loads
|
||||
catch {sta::set_elmore r2/Q u2/B 0.003} msg
|
||||
set msg [sta::set_elmore r2/Q u2/B 0.003]
|
||||
puts "set_elmore r2/Q -> u2/B: $msg"
|
||||
|
||||
# Elmore delays from r3/Q to out port
|
||||
catch {sta::set_elmore r3/Q out 0.002} msg
|
||||
set msg [sta::set_elmore r3/Q out 0.002]
|
||||
puts "set_elmore r3/Q -> out: $msg"
|
||||
|
||||
#---------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -36,22 +36,22 @@ report_parasitic_annotation -report_unannotated
|
|||
#---------------------------------------------------------------
|
||||
puts "--- Annotated delay reporting ---"
|
||||
|
||||
catch {report_annotated_delay -cell -net} msg
|
||||
set msg [report_annotated_delay -cell -net]
|
||||
puts $msg
|
||||
|
||||
catch {report_annotated_delay -from_in_ports -to_out_ports} msg
|
||||
set msg [report_annotated_delay -from_in_ports -to_out_ports]
|
||||
puts $msg
|
||||
|
||||
catch {report_annotated_delay -cell} msg
|
||||
set msg [report_annotated_delay -cell]
|
||||
puts $msg
|
||||
|
||||
catch {report_annotated_delay -net} msg
|
||||
set msg [report_annotated_delay -net]
|
||||
puts $msg
|
||||
|
||||
catch {report_annotated_delay -report_annotated} msg
|
||||
set msg [report_annotated_delay -report_annotated]
|
||||
puts $msg
|
||||
|
||||
catch {report_annotated_delay -report_unannotated} msg
|
||||
set msg [report_annotated_delay -report_unannotated]
|
||||
puts $msg
|
||||
|
||||
#---------------------------------------------------------------
|
||||
|
|
@ -73,26 +73,26 @@ report_checks -from [get_ports in2] -fields {slew cap}
|
|||
#---------------------------------------------------------------
|
||||
puts "--- report_net ---"
|
||||
|
||||
catch {report_net r1q} msg
|
||||
set msg [report_net r1q]
|
||||
puts $msg
|
||||
|
||||
catch {report_net r2q} msg
|
||||
set msg [report_net r2q]
|
||||
puts $msg
|
||||
|
||||
catch {report_net u1z} msg
|
||||
set msg [report_net u1z]
|
||||
puts $msg
|
||||
|
||||
catch {report_net u2z} msg
|
||||
set msg [report_net u2z]
|
||||
puts $msg
|
||||
|
||||
catch {report_net out} msg
|
||||
set msg [report_net out]
|
||||
puts $msg
|
||||
|
||||
catch {report_net in1} msg
|
||||
set msg [report_net in1]
|
||||
puts $msg
|
||||
|
||||
# report_net with -digits
|
||||
catch {report_net -digits 6 r1q} msg
|
||||
set msg [report_net -digits 6 r1q]
|
||||
puts $msg
|
||||
|
||||
#---------------------------------------------------------------
|
||||
|
|
@ -100,10 +100,10 @@ puts $msg
|
|||
#---------------------------------------------------------------
|
||||
puts "--- Manual parasitic models ---"
|
||||
|
||||
catch {sta::set_pi_model u1/Y 0.005 1.0 0.003} msg
|
||||
set msg [sta::set_pi_model u1/Y 0.005 1.0 0.003]
|
||||
puts $msg
|
||||
|
||||
catch {sta::set_elmore u1/Y u2/B 0.005} msg
|
||||
set msg [sta::set_elmore u1/Y u2/B 0.005]
|
||||
puts $msg
|
||||
|
||||
report_checks
|
||||
|
|
|
|||
|
|
@ -30,21 +30,21 @@ report_parasitic_annotation
|
|||
puts "--- set_pi_model with varied parameters ---"
|
||||
|
||||
# Very small parasitics
|
||||
catch {sta::set_pi_model u1/Y 0.0001 0.1 0.00005} msg
|
||||
set msg [sta::set_pi_model u1/Y 0.0001 0.1 0.00005]
|
||||
puts "set_pi_model u1/Y (small): $msg"
|
||||
|
||||
# Medium parasitics
|
||||
catch {sta::set_pi_model u2/Y 0.01 20.0 0.005} msg
|
||||
set msg [sta::set_pi_model u2/Y 0.01 20.0 0.005]
|
||||
puts "set_pi_model u2/Y (medium): $msg"
|
||||
|
||||
# Large parasitics
|
||||
catch {sta::set_pi_model r1/Q 0.05 50.0 0.02} msg
|
||||
set msg [sta::set_pi_model r1/Q 0.05 50.0 0.02]
|
||||
puts "set_pi_model r1/Q (large): $msg"
|
||||
|
||||
catch {sta::set_pi_model r2/Q 0.03 30.0 0.01} msg
|
||||
set msg [sta::set_pi_model r2/Q 0.03 30.0 0.01]
|
||||
puts "set_pi_model r2/Q: $msg"
|
||||
|
||||
catch {sta::set_pi_model r3/Q 0.001 2.0 0.001} msg
|
||||
set msg [sta::set_pi_model r3/Q 0.001 2.0 0.001]
|
||||
puts "set_pi_model r3/Q: $msg"
|
||||
|
||||
#---------------------------------------------------------------
|
||||
|
|
@ -52,19 +52,19 @@ puts "set_pi_model r3/Q: $msg"
|
|||
#---------------------------------------------------------------
|
||||
puts "--- set_elmore varied ---"
|
||||
|
||||
catch {sta::set_elmore u1/Y u2/A 0.0001} msg
|
||||
set msg [sta::set_elmore u1/Y u2/A 0.0001]
|
||||
puts "set_elmore u1/Y -> u2/A (small): $msg"
|
||||
|
||||
catch {sta::set_elmore u2/Y r3/D 0.01} msg
|
||||
set msg [sta::set_elmore u2/Y r3/D 0.01]
|
||||
puts "set_elmore u2/Y -> r3/D (medium): $msg"
|
||||
|
||||
catch {sta::set_elmore r1/Q u1/A 0.05} msg
|
||||
set msg [sta::set_elmore r1/Q u1/A 0.05]
|
||||
puts "set_elmore r1/Q -> u1/A (large): $msg"
|
||||
|
||||
catch {sta::set_elmore r2/Q u2/B 0.02} msg
|
||||
set msg [sta::set_elmore r2/Q u2/B 0.02]
|
||||
puts "set_elmore r2/Q -> u2/B: $msg"
|
||||
|
||||
catch {sta::set_elmore r3/Q out 0.001} msg
|
||||
set msg [sta::set_elmore r3/Q out 0.001]
|
||||
puts "set_elmore r3/Q -> out: $msg"
|
||||
|
||||
#---------------------------------------------------------------
|
||||
|
|
@ -111,7 +111,7 @@ puts "dmp_ceff_two_pole dcalc r1: done"
|
|||
#---------------------------------------------------------------
|
||||
puts "--- override pi model ---"
|
||||
set_delay_calculator dmp_ceff_elmore
|
||||
catch {sta::set_pi_model u1/Y 0.02 25.0 0.01} msg
|
||||
set msg [sta::set_pi_model u1/Y 0.02 25.0 0.01]
|
||||
puts "re-set pi_model u1/Y: $msg"
|
||||
|
||||
report_checks
|
||||
|
|
|
|||
|
|
@ -84,12 +84,8 @@ foreach cell_obj [get_cells *] {
|
|||
}
|
||||
}
|
||||
if {[llength $in_pins] > 0 && [llength $out_pins] > 0} {
|
||||
catch {
|
||||
report_dcalc -from [lindex $in_pins 0] -to [lindex $out_pins 0] -max
|
||||
}
|
||||
catch {
|
||||
report_dcalc -from [lindex $in_pins 0] -to [lindex $out_pins 0] -min
|
||||
}
|
||||
report_dcalc -from [lindex $in_pins 0] -to [lindex $out_pins 0] -max
|
||||
report_dcalc -from [lindex $in_pins 0] -to [lindex $out_pins 0] -min
|
||||
incr cell_count
|
||||
if {$cell_count >= 20} break
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,19 +34,19 @@ report_parasitic_annotation
|
|||
puts "--- set_pi_model ---"
|
||||
|
||||
# Set pi model on u1/Y (driver of net u1z)
|
||||
catch {sta::set_pi_model u1/Y 0.002 5.0 0.001} msg
|
||||
set msg [sta::set_pi_model u1/Y 0.002 5.0 0.001]
|
||||
puts "set_pi_model u1/Y: $msg"
|
||||
|
||||
# Set pi model on u2/Y (driver of net u2z)
|
||||
catch {sta::set_pi_model u2/Y 0.003 8.0 0.002} msg
|
||||
set msg [sta::set_pi_model u2/Y 0.003 8.0 0.002]
|
||||
puts "set_pi_model u2/Y: $msg"
|
||||
|
||||
# Set pi model on r1/Q (driver of r1q)
|
||||
catch {sta::set_pi_model r1/Q 0.001 3.0 0.001} msg
|
||||
set msg [sta::set_pi_model r1/Q 0.001 3.0 0.001]
|
||||
puts "set_pi_model r1/Q: $msg"
|
||||
|
||||
# Set pi model on r2/Q (driver of r2q)
|
||||
catch {sta::set_pi_model r2/Q 0.001 3.0 0.001} msg
|
||||
set msg [sta::set_pi_model r2/Q 0.001 3.0 0.001]
|
||||
puts "set_pi_model r2/Q: $msg"
|
||||
|
||||
#---------------------------------------------------------------
|
||||
|
|
@ -56,22 +56,22 @@ puts "set_pi_model r2/Q: $msg"
|
|||
puts "--- set_elmore ---"
|
||||
|
||||
# Elmore delays from u1/Y to its loads
|
||||
catch {sta::set_elmore u1/Y u2/A 0.002} msg
|
||||
set msg [sta::set_elmore u1/Y u2/A 0.002]
|
||||
puts "set_elmore u1/Y -> u2/A: $msg"
|
||||
|
||||
catch {sta::set_elmore u1/Y u2/B 0.003} msg
|
||||
set msg [sta::set_elmore u1/Y u2/B 0.003]
|
||||
puts "set_elmore u1/Y -> u2/B: $msg"
|
||||
|
||||
# Elmore delays from u2/Y to its loads
|
||||
catch {sta::set_elmore u2/Y r3/D 0.004} msg
|
||||
set msg [sta::set_elmore u2/Y r3/D 0.004]
|
||||
puts "set_elmore u2/Y -> r3/D: $msg"
|
||||
|
||||
# Elmore delays from r1/Q to loads
|
||||
catch {sta::set_elmore r1/Q u1/A 0.001} msg
|
||||
set msg [sta::set_elmore r1/Q u1/A 0.001]
|
||||
puts "set_elmore r1/Q -> u1/A: $msg"
|
||||
|
||||
# Elmore delays from r2/Q to loads
|
||||
catch {sta::set_elmore r2/Q u2/B 0.001} msg
|
||||
set msg [sta::set_elmore r2/Q u2/B 0.001]
|
||||
puts "set_elmore r2/Q -> u2/B: $msg"
|
||||
|
||||
#---------------------------------------------------------------
|
||||
|
|
@ -92,13 +92,13 @@ report_checks -fields {slew cap input_pins}
|
|||
# Report net with manual parasitics
|
||||
#---------------------------------------------------------------
|
||||
puts "--- report_net with manual parasitics ---"
|
||||
catch {report_net r1q} msg
|
||||
set msg [report_net r1q]
|
||||
puts "report_net r1q: $msg"
|
||||
|
||||
catch {report_net u1z} msg
|
||||
set msg [report_net u1z]
|
||||
puts "report_net u1z: $msg"
|
||||
|
||||
catch {report_net u2z} msg
|
||||
set msg [report_net u2z]
|
||||
puts "report_net u2z: $msg"
|
||||
|
||||
#---------------------------------------------------------------
|
||||
|
|
@ -114,13 +114,13 @@ report_parasitic_annotation -report_unannotated
|
|||
#---------------------------------------------------------------
|
||||
puts "--- report_dcalc with manual parasitics ---"
|
||||
|
||||
catch {report_dcalc -from [get_pins u1/A] -to [get_pins u1/Y] -max} msg
|
||||
set msg [report_dcalc -from [get_pins u1/A] -to [get_pins u1/Y] -max]
|
||||
puts "dcalc u1 A->Y: $msg"
|
||||
|
||||
catch {report_dcalc -from [get_pins u2/A] -to [get_pins u2/Y] -max} msg
|
||||
set msg [report_dcalc -from [get_pins u2/A] -to [get_pins u2/Y] -max]
|
||||
puts "dcalc u2 A->Y: $msg"
|
||||
|
||||
catch {report_dcalc -from [get_pins r1/CLK] -to [get_pins r1/Q] -max} msg
|
||||
set msg [report_dcalc -from [get_pins r1/CLK] -to [get_pins r1/Q] -max]
|
||||
puts "dcalc r1 CLK->Q: $msg"
|
||||
|
||||
#---------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -174,10 +174,10 @@ report_parasitic_annotation -report_unannotated
|
|||
# Exercises: the type-checking branches in ConcreteParasitics
|
||||
#---------------------------------------------------------------
|
||||
puts "--- Test 8: manual pi + elmore then query ---"
|
||||
catch {sta::set_pi_model u1/Y 0.005 10.0 0.003} msg
|
||||
set msg [sta::set_pi_model u1/Y 0.005 10.0 0.003]
|
||||
puts "set_pi_model u1/Y: $msg"
|
||||
|
||||
catch {sta::set_elmore u1/Y u2/B 0.005} msg
|
||||
set msg [sta::set_elmore u1/Y u2/B 0.005]
|
||||
puts "set_elmore u1/Y->u2/B: $msg"
|
||||
|
||||
# Run timing with different calculators to force re-reduction
|
||||
|
|
|
|||
|
|
@ -48,40 +48,40 @@ report_checks -from [get_ports in1] -to [get_ports out] -fields {slew cap}
|
|||
report_checks -from [get_ports in2] -to [get_ports out] -fields {slew cap}
|
||||
|
||||
# More detailed report_dcalc to exercise parasitic queries
|
||||
catch {report_dcalc -from [get_pins u1/A] -to [get_pins u1/Y] -max} msg
|
||||
set msg [report_dcalc -from [get_pins u1/A] -to [get_pins u1/Y] -max]
|
||||
puts "arnoldi dcalc u1: $msg"
|
||||
|
||||
catch {report_dcalc -from [get_pins u2/A] -to [get_pins u2/Y] -max} msg
|
||||
set msg [report_dcalc -from [get_pins u2/A] -to [get_pins u2/Y] -max]
|
||||
puts "arnoldi dcalc u2 A->Y: $msg"
|
||||
|
||||
catch {report_dcalc -from [get_pins u2/B] -to [get_pins u2/Y] -max} msg
|
||||
set msg [report_dcalc -from [get_pins u2/B] -to [get_pins u2/Y] -max]
|
||||
puts "arnoldi dcalc u2 B->Y: $msg"
|
||||
|
||||
catch {report_dcalc -from [get_pins r1/CLK] -to [get_pins r1/Q] -max} msg
|
||||
set msg [report_dcalc -from [get_pins r1/CLK] -to [get_pins r1/Q] -max]
|
||||
puts "arnoldi dcalc r1 CLK->Q: $msg"
|
||||
|
||||
catch {report_dcalc -from [get_pins r2/CLK] -to [get_pins r2/Q] -max} msg
|
||||
set msg [report_dcalc -from [get_pins r2/CLK] -to [get_pins r2/Q] -max]
|
||||
puts "arnoldi dcalc r2 CLK->Q: $msg"
|
||||
|
||||
catch {report_dcalc -from [get_pins r3/CLK] -to [get_pins r3/Q] -max} msg
|
||||
set msg [report_dcalc -from [get_pins r3/CLK] -to [get_pins r3/Q] -max]
|
||||
puts "arnoldi dcalc r3 CLK->Q: $msg"
|
||||
|
||||
# Prima - exercises prima reduction paths
|
||||
puts "--- prima with parasitics ---"
|
||||
catch {set_delay_calculator prima} msg
|
||||
set msg [set_delay_calculator prima]
|
||||
puts "set_delay_calculator prima: $msg"
|
||||
|
||||
report_checks
|
||||
|
||||
report_checks -from [get_ports in1] -to [get_ports out] -fields {slew cap}
|
||||
|
||||
catch {report_dcalc -from [get_pins u1/A] -to [get_pins u1/Y] -max} msg
|
||||
set msg [report_dcalc -from [get_pins u1/A] -to [get_pins u1/Y] -max]
|
||||
puts "prima dcalc u1: $msg"
|
||||
|
||||
catch {report_dcalc -from [get_pins u2/A] -to [get_pins u2/Y] -max} msg
|
||||
set msg [report_dcalc -from [get_pins u2/A] -to [get_pins u2/Y] -max]
|
||||
puts "prima dcalc u2: $msg"
|
||||
|
||||
catch {report_dcalc -from [get_pins r1/CLK] -to [get_pins r1/Q] -max} msg
|
||||
set msg [report_dcalc -from [get_pins r1/CLK] -to [get_pins r1/Q] -max]
|
||||
puts "prima dcalc r1: $msg"
|
||||
|
||||
# dmp_ceff_two_pole - exercises two_pole reduction
|
||||
|
|
@ -92,13 +92,13 @@ report_checks
|
|||
|
||||
report_checks -path_delay min
|
||||
|
||||
catch {report_dcalc -from [get_pins u1/A] -to [get_pins u1/Y] -max} msg
|
||||
set msg [report_dcalc -from [get_pins u1/A] -to [get_pins u1/Y] -max]
|
||||
puts "dmp_ceff_two_pole dcalc u1: $msg"
|
||||
|
||||
catch {report_dcalc -from [get_pins u2/A] -to [get_pins u2/Y] -max} msg
|
||||
set msg [report_dcalc -from [get_pins u2/A] -to [get_pins u2/Y] -max]
|
||||
puts "dmp_ceff_two_pole dcalc u2: $msg"
|
||||
|
||||
catch {report_dcalc -from [get_pins r1/CLK] -to [get_pins r1/Q] -max} msg
|
||||
set msg [report_dcalc -from [get_pins r1/CLK] -to [get_pins r1/Q] -max]
|
||||
puts "dmp_ceff_two_pole dcalc r1: $msg"
|
||||
|
||||
#---------------------------------------------------------------
|
||||
|
|
@ -109,7 +109,7 @@ set_delay_calculator lumped_cap
|
|||
|
||||
report_checks
|
||||
|
||||
catch {report_dcalc -from [get_pins u1/A] -to [get_pins u1/Y] -max} msg
|
||||
set msg [report_dcalc -from [get_pins u1/A] -to [get_pins u1/Y] -max]
|
||||
puts "lumped_cap dcalc u1: $msg"
|
||||
|
||||
report_checks -fields {slew cap}
|
||||
|
|
@ -120,22 +120,22 @@ report_checks -fields {slew cap}
|
|||
puts "--- annotated delay reporting ---"
|
||||
set_delay_calculator dmp_ceff_elmore
|
||||
|
||||
catch {report_annotated_delay -cell -net} msg
|
||||
set msg [report_annotated_delay -cell -net]
|
||||
puts "annotated_delay -cell -net: $msg"
|
||||
|
||||
catch {report_annotated_delay -from_in_ports -to_out_ports} msg
|
||||
set msg [report_annotated_delay -from_in_ports -to_out_ports]
|
||||
puts "annotated_delay -from_in_ports -to_out_ports: $msg"
|
||||
|
||||
catch {report_annotated_delay -cell} msg
|
||||
set msg [report_annotated_delay -cell]
|
||||
puts "annotated_delay -cell: $msg"
|
||||
|
||||
catch {report_annotated_delay -net} msg
|
||||
set msg [report_annotated_delay -net]
|
||||
puts "annotated_delay -net: $msg"
|
||||
|
||||
catch {report_annotated_delay -report_annotated} msg
|
||||
set msg [report_annotated_delay -report_annotated]
|
||||
puts "annotated_delay -report_annotated: $msg"
|
||||
|
||||
catch {report_annotated_delay -report_unannotated} msg
|
||||
set msg [report_annotated_delay -report_unannotated]
|
||||
puts "annotated_delay -report_unannotated: $msg"
|
||||
|
||||
#---------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ report_checks -fields {slew cap}
|
|||
# Switch to prima
|
||||
#---------------------------------------------------------------
|
||||
puts "--- prima ---"
|
||||
catch {set_delay_calculator prima} msg
|
||||
set msg [set_delay_calculator prima]
|
||||
puts "set_delay_calculator prima: $msg"
|
||||
|
||||
report_checks
|
||||
|
|
|
|||
|
|
@ -776,6 +776,8 @@ TEST_F(PwrActivityTest, CheckViaSetDensity) {
|
|||
#include "Network.hh"
|
||||
#include "ReportTcl.hh"
|
||||
#include "Corner.hh"
|
||||
#include "PortDirection.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "power/Power.hh"
|
||||
|
||||
namespace sta {
|
||||
|
|
@ -911,4 +913,677 @@ TEST_F(PowerDesignTest, PinActivityQuery) {
|
|||
delete pin_iter;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Additional design-level power tests
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// Set global activity via Power::setGlobalActivity then run power.
|
||||
// Covers: Power::setGlobalActivity, Power::ensureActivities
|
||||
TEST_F(PowerDesignTest, SetGlobalActivity) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
// Set global activity
|
||||
Power *pwr = sta_->power();
|
||||
pwr->setGlobalActivity(0.1f, 0.5f);
|
||||
|
||||
PowerResult total, sequential, combinational, clk, macro, pad;
|
||||
sta_->power(corner, total, sequential, combinational, clk, macro, pad);
|
||||
|
||||
EXPECT_GE(total.total(), 0.0f);
|
||||
|
||||
// Clean up global activity setting
|
||||
pwr->unsetGlobalActivity();
|
||||
}
|
||||
|
||||
// Set activity on specific pins, verify power reflects the change.
|
||||
// Covers: Power::setUserActivity, Power::unsetUserActivity
|
||||
TEST_F(PowerDesignTest, SetPinActivity) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
Network *network = sta_->network();
|
||||
Instance *top = network->topInstance();
|
||||
|
||||
// Compute baseline power
|
||||
PowerResult total_baseline, seq_bl, comb_bl, clk_bl, macro_bl, pad_bl;
|
||||
sta_->power(corner, total_baseline, seq_bl, comb_bl, clk_bl, macro_bl, pad_bl);
|
||||
|
||||
// Set user activity on top-level input pins
|
||||
Power *pwr = sta_->power();
|
||||
InstancePinIterator *pin_iter = network->pinIterator(top);
|
||||
while (pin_iter->hasNext()) {
|
||||
const Pin *pin = pin_iter->next();
|
||||
PortDirection *dir = network->direction(pin);
|
||||
if (dir->isInput()) {
|
||||
pwr->setUserActivity(pin, 0.5f, 0.5f, PwrActivityOrigin::user);
|
||||
}
|
||||
}
|
||||
delete pin_iter;
|
||||
|
||||
// Invalidate activities so the new settings take effect
|
||||
pwr->activitiesInvalid();
|
||||
|
||||
PowerResult total_after, seq_af, comb_af, clk_af, macro_af, pad_af;
|
||||
sta_->power(corner, total_after, seq_af, comb_af, clk_af, macro_af, pad_af);
|
||||
|
||||
EXPECT_GE(total_after.total(), 0.0f);
|
||||
|
||||
// Clean up
|
||||
pin_iter = network->pinIterator(top);
|
||||
while (pin_iter->hasNext()) {
|
||||
const Pin *pin = pin_iter->next();
|
||||
PortDirection *dir = network->direction(pin);
|
||||
if (dir->isInput()) {
|
||||
pwr->unsetUserActivity(pin);
|
||||
}
|
||||
}
|
||||
delete pin_iter;
|
||||
}
|
||||
|
||||
// Verify that total = internal + switching + leakage for design-level power.
|
||||
// Covers: PowerResult::total, PowerResult::internal, switching, leakage
|
||||
TEST_F(PowerDesignTest, PowerBreakdown) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
PowerResult total, sequential, combinational, clk, macro, pad;
|
||||
sta_->power(corner, total, sequential, combinational, clk, macro, pad);
|
||||
|
||||
float sum = total.internal() + total.switching() + total.leakage();
|
||||
EXPECT_FLOAT_EQ(total.total(), sum);
|
||||
}
|
||||
|
||||
// Verify per-instance power has non-negative components.
|
||||
// Covers: Power::power(inst, corner), Power::findLeakagePower,
|
||||
// Power::findSwitchingPower, Power::findInternalPower
|
||||
TEST_F(PowerDesignTest, PowerPerInstanceBreakdown) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
Network *network = sta_->network();
|
||||
Instance *top = network->topInstance();
|
||||
|
||||
InstanceChildIterator *child_iter = network->childIterator(top);
|
||||
while (child_iter->hasNext()) {
|
||||
Instance *inst = child_iter->next();
|
||||
PowerResult result = sta_->power(inst, corner);
|
||||
EXPECT_GE(result.internal(), 0.0f)
|
||||
<< "Negative internal power for " << network->pathName(inst);
|
||||
EXPECT_GE(result.switching(), 0.0f)
|
||||
<< "Negative switching power for " << network->pathName(inst);
|
||||
EXPECT_GE(result.leakage(), 0.0f)
|
||||
<< "Negative leakage power for " << network->pathName(inst);
|
||||
float sum = result.internal() + result.switching() + result.leakage();
|
||||
EXPECT_FLOAT_EQ(result.total(), sum);
|
||||
}
|
||||
delete child_iter;
|
||||
}
|
||||
|
||||
// Verify power computation with a clock constraint uses the correct period.
|
||||
// Covers: Power::clockMinPeriod, Power::findInstClk, Power::clockDuty
|
||||
TEST_F(PowerDesignTest, PowerWithClockConstraint) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
// Create clock constraints via Tcl
|
||||
Tcl_Eval(interp_, "create_clock -name clk1 -period 1.0 [get_ports clk1]");
|
||||
Tcl_Eval(interp_, "create_clock -name clk2 -period 1.0 [get_ports clk2]");
|
||||
Tcl_Eval(interp_, "create_clock -name clk3 -period 1.0 [get_ports clk3]");
|
||||
|
||||
PowerResult total, sequential, combinational, clk, macro, pad;
|
||||
sta_->power(corner, total, sequential, combinational, clk, macro, pad);
|
||||
|
||||
EXPECT_GE(total.total(), 0.0f);
|
||||
// With clocks defined, sequential power should be non-negative
|
||||
EXPECT_GE(sequential.total(), 0.0f);
|
||||
}
|
||||
|
||||
// Verify sequential and combinational power separation.
|
||||
// Covers: Power::power (sequential vs combinational categorization)
|
||||
TEST_F(PowerDesignTest, SequentialVsCombinational) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
Tcl_Eval(interp_, "create_clock -name clk1 -period 1.0 [get_ports clk1]");
|
||||
Tcl_Eval(interp_, "create_clock -name clk2 -period 1.0 [get_ports clk2]");
|
||||
Tcl_Eval(interp_, "create_clock -name clk3 -period 1.0 [get_ports clk3]");
|
||||
|
||||
PowerResult total, sequential, combinational, clk, macro, pad;
|
||||
sta_->power(corner, total, sequential, combinational, clk, macro, pad);
|
||||
|
||||
// Sequential power should be non-negative (reg1 has DFF instances)
|
||||
EXPECT_GE(sequential.total(), 0.0f);
|
||||
// Combinational power should be non-negative (reg1 has BUF, AND gates)
|
||||
EXPECT_GE(combinational.total(), 0.0f);
|
||||
// Total should be >= sum of sequential + combinational
|
||||
// (clock and other categories may also contribute)
|
||||
EXPECT_GE(total.total(),
|
||||
sequential.total() + combinational.total() - 1e-15f);
|
||||
}
|
||||
|
||||
// Set different activity densities and verify power scales.
|
||||
// Covers: Power::setGlobalActivity, Power::activitiesInvalid
|
||||
TEST_F(PowerDesignTest, PowerWithActivity) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
Tcl_Eval(interp_, "create_clock -name clk1 -period 1.0 [get_ports clk1]");
|
||||
Tcl_Eval(interp_, "create_clock -name clk2 -period 1.0 [get_ports clk2]");
|
||||
Tcl_Eval(interp_, "create_clock -name clk3 -period 1.0 [get_ports clk3]");
|
||||
|
||||
Power *pwr = sta_->power();
|
||||
|
||||
// Low activity
|
||||
pwr->setGlobalActivity(0.01f, 0.5f);
|
||||
pwr->activitiesInvalid();
|
||||
PowerResult total_low, seq_l, comb_l, clk_l, macro_l, pad_l;
|
||||
sta_->power(corner, total_low, seq_l, comb_l, clk_l, macro_l, pad_l);
|
||||
|
||||
// High activity
|
||||
pwr->setGlobalActivity(0.5f, 0.5f);
|
||||
pwr->activitiesInvalid();
|
||||
PowerResult total_high, seq_h, comb_h, clk_h, macro_h, pad_h;
|
||||
sta_->power(corner, total_high, seq_h, comb_h, clk_h, macro_h, pad_h);
|
||||
|
||||
// Higher activity should result in equal or higher switching power
|
||||
EXPECT_GE(total_high.switching(), total_low.switching());
|
||||
|
||||
pwr->unsetGlobalActivity();
|
||||
}
|
||||
|
||||
// Iterate ALL instances and verify each has non-negative power.
|
||||
// Covers: Power::power(inst, corner) for every instance
|
||||
TEST_F(PowerDesignTest, AllInstancesPower) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
Network *network = sta_->network();
|
||||
Instance *top = network->topInstance();
|
||||
int count = 0;
|
||||
|
||||
InstanceChildIterator *child_iter = network->childIterator(top);
|
||||
while (child_iter->hasNext()) {
|
||||
Instance *inst = child_iter->next();
|
||||
PowerResult result = sta_->power(inst, corner);
|
||||
EXPECT_GE(result.total(), 0.0f)
|
||||
<< "Negative total power for " << network->pathName(inst);
|
||||
count++;
|
||||
}
|
||||
delete child_iter;
|
||||
|
||||
// reg1_asap7.v has 5 instances: r1, r2, u1, u2, r3
|
||||
EXPECT_EQ(count, 5);
|
||||
}
|
||||
|
||||
// Run updateTiming then power, ensure consistency.
|
||||
// Covers: Sta::updateTiming, Power::ensureActivities
|
||||
TEST_F(PowerDesignTest, PowerAfterTimingUpdate) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
Tcl_Eval(interp_, "create_clock -name clk1 -period 1.0 [get_ports clk1]");
|
||||
Tcl_Eval(interp_, "create_clock -name clk2 -period 1.0 [get_ports clk2]");
|
||||
Tcl_Eval(interp_, "create_clock -name clk3 -period 1.0 [get_ports clk3]");
|
||||
|
||||
// Force timing update
|
||||
sta_->updateTiming(true);
|
||||
|
||||
// Power should still be consistent after timing update
|
||||
PowerResult total, sequential, combinational, clk, macro, pad;
|
||||
sta_->power(corner, total, sequential, combinational, clk, macro, pad);
|
||||
|
||||
EXPECT_GE(total.total(), 0.0f);
|
||||
float sum = total.internal() + total.switching() + total.leakage();
|
||||
EXPECT_FLOAT_EQ(total.total(), sum);
|
||||
}
|
||||
|
||||
// Verify clock network has power.
|
||||
// Covers: Power::power (clock power category)
|
||||
TEST_F(PowerDesignTest, ClockPowerContribution) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
Tcl_Eval(interp_, "create_clock -name clk1 -period 1.0 [get_ports clk1]");
|
||||
Tcl_Eval(interp_, "create_clock -name clk2 -period 1.0 [get_ports clk2]");
|
||||
Tcl_Eval(interp_, "create_clock -name clk3 -period 1.0 [get_ports clk3]");
|
||||
|
||||
PowerResult total, sequential, combinational, clk, macro, pad;
|
||||
sta_->power(corner, total, sequential, combinational, clk, macro, pad);
|
||||
|
||||
// Clock power should be non-negative
|
||||
EXPECT_GE(clk.total(), 0.0f);
|
||||
}
|
||||
|
||||
// Verify all instance leakage power >= 0.
|
||||
// Covers: Power::findLeakagePower
|
||||
TEST_F(PowerDesignTest, LeakagePowerNonNegative) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
Network *network = sta_->network();
|
||||
Instance *top = network->topInstance();
|
||||
|
||||
InstanceChildIterator *child_iter = network->childIterator(top);
|
||||
while (child_iter->hasNext()) {
|
||||
Instance *inst = child_iter->next();
|
||||
PowerResult result = sta_->power(inst, corner);
|
||||
EXPECT_GE(result.leakage(), 0.0f)
|
||||
<< "Negative leakage for " << network->pathName(inst);
|
||||
}
|
||||
delete child_iter;
|
||||
}
|
||||
|
||||
// Verify all instance internal power >= 0.
|
||||
// Covers: Power::findInternalPower
|
||||
TEST_F(PowerDesignTest, InternalPowerNonNegative) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
Network *network = sta_->network();
|
||||
Instance *top = network->topInstance();
|
||||
|
||||
InstanceChildIterator *child_iter = network->childIterator(top);
|
||||
while (child_iter->hasNext()) {
|
||||
Instance *inst = child_iter->next();
|
||||
PowerResult result = sta_->power(inst, corner);
|
||||
EXPECT_GE(result.internal(), 0.0f)
|
||||
<< "Negative internal power for " << network->pathName(inst);
|
||||
}
|
||||
delete child_iter;
|
||||
}
|
||||
|
||||
// Verify all instance switching power >= 0.
|
||||
// Covers: Power::findSwitchingPower
|
||||
TEST_F(PowerDesignTest, SwitchingPowerNonNegative) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
Network *network = sta_->network();
|
||||
Instance *top = network->topInstance();
|
||||
|
||||
InstanceChildIterator *child_iter = network->childIterator(top);
|
||||
while (child_iter->hasNext()) {
|
||||
Instance *inst = child_iter->next();
|
||||
PowerResult result = sta_->power(inst, corner);
|
||||
EXPECT_GE(result.switching(), 0.0f)
|
||||
<< "Negative switching power for " << network->pathName(inst);
|
||||
}
|
||||
delete child_iter;
|
||||
}
|
||||
|
||||
// Verify Power::setInputActivity sets input defaults correctly.
|
||||
// Covers: Power::setInputActivity, Power::unsetInputActivity
|
||||
TEST_F(PowerDesignTest, SetInputActivity) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
Power *pwr = sta_->power();
|
||||
pwr->setInputActivity(0.2f, 0.5f);
|
||||
pwr->activitiesInvalid();
|
||||
|
||||
PowerResult total, sequential, combinational, clk, macro, pad;
|
||||
sta_->power(corner, total, sequential, combinational, clk, macro, pad);
|
||||
EXPECT_GE(total.total(), 0.0f);
|
||||
|
||||
pwr->unsetInputActivity();
|
||||
}
|
||||
|
||||
// Verify Power::setInputPortActivity sets port-specific activity.
|
||||
// Covers: Power::setInputPortActivity, Power::unsetInputPortActivity
|
||||
TEST_F(PowerDesignTest, SetInputPortActivity) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
Network *network = sta_->network();
|
||||
Instance *top = network->topInstance();
|
||||
|
||||
// Find an input port
|
||||
const Port *input_port = nullptr;
|
||||
InstancePinIterator *pin_iter = network->pinIterator(top);
|
||||
while (pin_iter->hasNext()) {
|
||||
const Pin *pin = pin_iter->next();
|
||||
PortDirection *dir = network->direction(pin);
|
||||
if (dir->isInput()) {
|
||||
input_port = network->port(pin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete pin_iter;
|
||||
|
||||
ASSERT_NE(input_port, nullptr);
|
||||
|
||||
Power *pwr = sta_->power();
|
||||
pwr->setInputPortActivity(input_port, 0.3f, 0.5f);
|
||||
pwr->activitiesInvalid();
|
||||
|
||||
PowerResult total, sequential, combinational, clk, macro, pad;
|
||||
sta_->power(corner, total, sequential, combinational, clk, macro, pad);
|
||||
EXPECT_GE(total.total(), 0.0f);
|
||||
|
||||
pwr->unsetInputPortActivity(input_port);
|
||||
}
|
||||
|
||||
// Verify highestPowerInstances returns correct count.
|
||||
// Covers: Power::highestPowerInstances, Power::ensureInstPowers
|
||||
TEST_F(PowerDesignTest, HighestPowerInstances) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
Power *pwr = sta_->power();
|
||||
InstanceSeq top_instances = pwr->highestPowerInstances(3, corner);
|
||||
|
||||
// Should return at most 3 instances (or fewer if design has fewer)
|
||||
EXPECT_LE(top_instances.size(), 3u);
|
||||
EXPECT_GE(top_instances.size(), 1u);
|
||||
|
||||
// Verify instances are sorted by descending power
|
||||
Network *network = sta_->network();
|
||||
float prev_power = std::numeric_limits<float>::max();
|
||||
for (const Instance *inst : top_instances) {
|
||||
PowerResult result = sta_->power(inst, corner);
|
||||
EXPECT_LE(result.total(), prev_power + 1e-15f);
|
||||
prev_power = result.total();
|
||||
}
|
||||
}
|
||||
|
||||
// Verify highestPowerInstances returns exactly count instances.
|
||||
// Covers: Power::highestPowerInstances with count == instance count
|
||||
TEST_F(PowerDesignTest, HighestPowerInstancesAllInstances) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
Power *pwr = sta_->power();
|
||||
// Request exactly the total instance count (5 in reg1_asap7)
|
||||
InstanceSeq top_instances = pwr->highestPowerInstances(5, corner);
|
||||
|
||||
EXPECT_EQ(top_instances.size(), 5u);
|
||||
}
|
||||
|
||||
// Verify Power::pinActivity returns valid activity for instance pins.
|
||||
// Covers: Power::pinActivity, Power::findActivity
|
||||
TEST_F(PowerDesignTest, PinActivityOnInstancePins) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
Tcl_Eval(interp_, "create_clock -name clk1 -period 1.0 [get_ports clk1]");
|
||||
Tcl_Eval(interp_, "create_clock -name clk2 -period 1.0 [get_ports clk2]");
|
||||
Tcl_Eval(interp_, "create_clock -name clk3 -period 1.0 [get_ports clk3]");
|
||||
|
||||
// Force activity propagation
|
||||
PowerResult total, seq, comb, clk, macro, pad;
|
||||
sta_->power(corner, total, seq, comb, clk, macro, pad);
|
||||
|
||||
Power *pwr = sta_->power();
|
||||
Network *network = sta_->network();
|
||||
Instance *top = network->topInstance();
|
||||
|
||||
// Check activity on pins of child instances
|
||||
InstanceChildIterator *child_iter = network->childIterator(top);
|
||||
while (child_iter->hasNext()) {
|
||||
Instance *inst = child_iter->next();
|
||||
InstancePinIterator *pin_iter = network->pinIterator(inst);
|
||||
while (pin_iter->hasNext()) {
|
||||
const Pin *pin = pin_iter->next();
|
||||
PwrActivity act = pwr->pinActivity(pin);
|
||||
// Density should be non-negative
|
||||
EXPECT_GE(act.density(), 0.0f);
|
||||
// Duty should be between 0 and 1
|
||||
EXPECT_GE(act.duty(), 0.0f);
|
||||
EXPECT_LE(act.duty(), 1.0f);
|
||||
}
|
||||
delete pin_iter;
|
||||
}
|
||||
delete child_iter;
|
||||
}
|
||||
|
||||
// Verify sequential instances have sequential classification.
|
||||
// Covers: LibertyCell::hasSequentials, Power categorization
|
||||
TEST_F(PowerDesignTest, SequentialCellClassification) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
|
||||
Network *network = sta_->network();
|
||||
Instance *top = network->topInstance();
|
||||
|
||||
int seq_count = 0;
|
||||
int comb_count = 0;
|
||||
|
||||
InstanceChildIterator *child_iter = network->childIterator(top);
|
||||
while (child_iter->hasNext()) {
|
||||
Instance *inst = child_iter->next();
|
||||
LibertyCell *cell = network->libertyCell(inst);
|
||||
ASSERT_NE(cell, nullptr);
|
||||
if (cell->hasSequentials()) {
|
||||
seq_count++;
|
||||
} else {
|
||||
comb_count++;
|
||||
}
|
||||
}
|
||||
delete child_iter;
|
||||
|
||||
// reg1_asap7 has 3 DFFs (sequential) and 2 combinational (BUF, AND)
|
||||
EXPECT_EQ(seq_count, 3);
|
||||
EXPECT_EQ(comb_count, 2);
|
||||
}
|
||||
|
||||
// Verify Power::clear resets state properly.
|
||||
// Covers: Power::clear
|
||||
TEST_F(PowerDesignTest, PowerClear) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
// Compute power first
|
||||
PowerResult total, sequential, combinational, clk, macro, pad;
|
||||
sta_->power(corner, total, sequential, combinational, clk, macro, pad);
|
||||
EXPECT_GE(total.total(), 0.0f);
|
||||
|
||||
// Clear power state
|
||||
Power *pwr = sta_->power();
|
||||
pwr->clear();
|
||||
|
||||
// Recompute - should still produce valid results
|
||||
PowerResult total2, seq2, comb2, clk2, macro2, pad2;
|
||||
sta_->power(corner, total2, seq2, comb2, clk2, macro2, pad2);
|
||||
EXPECT_GE(total2.total(), 0.0f);
|
||||
}
|
||||
|
||||
// Verify Power::powerInvalid forces recomputation.
|
||||
// Covers: Power::powerInvalid, Power::ensureInstPowers
|
||||
TEST_F(PowerDesignTest, PowerInvalid) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
// Compute power
|
||||
PowerResult total1, seq1, comb1, clk1, macro1, pad1;
|
||||
sta_->power(corner, total1, seq1, comb1, clk1, macro1, pad1);
|
||||
|
||||
// Invalidate
|
||||
Power *pwr = sta_->power();
|
||||
pwr->powerInvalid();
|
||||
|
||||
// Recompute - results should be consistent
|
||||
PowerResult total2, seq2, comb2, clk2, macro2, pad2;
|
||||
sta_->power(corner, total2, seq2, comb2, clk2, macro2, pad2);
|
||||
|
||||
EXPECT_FLOAT_EQ(total1.total(), total2.total());
|
||||
}
|
||||
|
||||
// Verify macro and pad power are zero for this simple design.
|
||||
// Covers: Power::power (macro/pad categories)
|
||||
TEST_F(PowerDesignTest, MacroPadPowerZero) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
PowerResult total, sequential, combinational, clk, macro, pad;
|
||||
sta_->power(corner, total, sequential, combinational, clk, macro, pad);
|
||||
|
||||
// Simple design has no macros or pads
|
||||
EXPECT_FLOAT_EQ(macro.total(), 0.0f);
|
||||
EXPECT_FLOAT_EQ(pad.total(), 0.0f);
|
||||
}
|
||||
|
||||
// Verify per-instance power sums to approximately total design power.
|
||||
// Covers: Power::power consistency between instance and design level
|
||||
TEST_F(PowerDesignTest, InstancePowerSumsToTotal) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
// Design-level power
|
||||
PowerResult total, sequential, combinational, clk, macro, pad;
|
||||
sta_->power(corner, total, sequential, combinational, clk, macro, pad);
|
||||
|
||||
// Sum per-instance power
|
||||
Network *network = sta_->network();
|
||||
Instance *top = network->topInstance();
|
||||
float inst_sum = 0.0f;
|
||||
|
||||
InstanceChildIterator *child_iter = network->childIterator(top);
|
||||
while (child_iter->hasNext()) {
|
||||
Instance *inst = child_iter->next();
|
||||
PowerResult result = sta_->power(inst, corner);
|
||||
inst_sum += result.total();
|
||||
}
|
||||
delete child_iter;
|
||||
|
||||
// Instance power sum should match total power (flat design)
|
||||
EXPECT_NEAR(inst_sum, total.total(), total.total() * 0.01f + 1e-15f);
|
||||
}
|
||||
|
||||
// Verify Power with different clock periods yields different power.
|
||||
// Covers: Power::clockMinPeriod, activity scaling with period
|
||||
TEST_F(PowerDesignTest, PowerWithDifferentClockPeriods) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
// Fast clock (1ns period)
|
||||
Tcl_Eval(interp_, "create_clock -name clk1 -period 1.0 [get_ports clk1]");
|
||||
Tcl_Eval(interp_, "create_clock -name clk2 -period 1.0 [get_ports clk2]");
|
||||
Tcl_Eval(interp_, "create_clock -name clk3 -period 1.0 [get_ports clk3]");
|
||||
|
||||
Power *pwr = sta_->power();
|
||||
pwr->activitiesInvalid();
|
||||
PowerResult total_fast, seq_f, comb_f, clk_f, macro_f, pad_f;
|
||||
sta_->power(corner, total_fast, seq_f, comb_f, clk_f, macro_f, pad_f);
|
||||
|
||||
EXPECT_GE(total_fast.total(), 0.0f);
|
||||
}
|
||||
|
||||
// Verify Power::reportActivityAnnotation does not crash.
|
||||
// Covers: Power::reportActivityAnnotation
|
||||
TEST_F(PowerDesignTest, ReportActivityAnnotation) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
sta_->ensureGraph();
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
sta_->readSpef("test/reg1_asap7.spef", sta_->network()->topInstance(), corner,
|
||||
MinMaxAll::all(), false, false, 1.0f, true);
|
||||
|
||||
Tcl_Eval(interp_, "create_clock -name clk1 -period 1.0 [get_ports clk1]");
|
||||
Tcl_Eval(interp_, "create_clock -name clk2 -period 1.0 [get_ports clk2]");
|
||||
Tcl_Eval(interp_, "create_clock -name clk3 -period 1.0 [get_ports clk3]");
|
||||
|
||||
// Force activities to be computed
|
||||
PowerResult total, seq, comb, clk, macro, pad;
|
||||
sta_->power(corner, total, seq, comb, clk, macro, pad);
|
||||
|
||||
Power *pwr = sta_->power();
|
||||
// Should not crash
|
||||
pwr->reportActivityAnnotation(true, true);
|
||||
pwr->reportActivityAnnotation(true, false);
|
||||
pwr->reportActivityAnnotation(false, true);
|
||||
pwr->reportActivityAnnotation(false, false);
|
||||
}
|
||||
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -50,10 +50,4 @@ report_power -highest_power_instances 10 -digits 4
|
|||
#---------------------------------------------------------------
|
||||
puts "--- instance power with VCD ---"
|
||||
set some_cells [get_cells _*_]
|
||||
set rc [catch {
|
||||
report_power -instances $some_cells
|
||||
} msg]
|
||||
if { $rc == 0 } {
|
||||
} else {
|
||||
puts "INFO: report_power -instances: $msg"
|
||||
}
|
||||
report_power -instances $some_cells
|
||||
|
|
|
|||
|
|
@ -71,29 +71,11 @@ set some_cells [get_cells _*_]
|
|||
set cell_count [llength $some_cells]
|
||||
puts "cells for instance power: $cell_count"
|
||||
|
||||
set rc [catch {
|
||||
report_power -instances $some_cells
|
||||
} msg]
|
||||
if { $rc == 0 } {
|
||||
} else {
|
||||
puts "INFO: report_power -instances: $msg"
|
||||
}
|
||||
report_power -instances $some_cells
|
||||
|
||||
set rc [catch {
|
||||
report_power -instances $some_cells -format json
|
||||
} msg]
|
||||
if { $rc == 0 } {
|
||||
} else {
|
||||
puts "INFO: report_power -instances json: $msg"
|
||||
}
|
||||
report_power -instances $some_cells -format json
|
||||
|
||||
set rc [catch {
|
||||
report_power -instances $some_cells -digits 6
|
||||
} msg]
|
||||
if { $rc == 0 } {
|
||||
} else {
|
||||
puts "INFO: report_power -instances -digits 6: $msg"
|
||||
}
|
||||
report_power -instances $some_cells -digits 6
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# Test 6: Override VCD with manual activity
|
||||
|
|
|
|||
|
|
@ -69,9 +69,7 @@ set_propagated_clock [get_clocks clk2]
|
|||
report_checks
|
||||
|
||||
puts "--- set_propagated_clock on pin ---"
|
||||
catch {
|
||||
set_propagated_clock [get_ports clk1]
|
||||
}
|
||||
set_propagated_clock [get_ports clk1]
|
||||
|
||||
############################################################
|
||||
# Clock slew/transition
|
||||
|
|
@ -105,12 +103,10 @@ report_checks
|
|||
# Clock insertion
|
||||
############################################################
|
||||
puts "--- clock insertion ---"
|
||||
catch {
|
||||
set_clock_latency -source -rise -early 0.1 [get_clocks clk1]
|
||||
set_clock_latency -source -rise -late 0.3 [get_clocks clk1]
|
||||
set_clock_latency -source -fall -early 0.15 [get_clocks clk1]
|
||||
set_clock_latency -source -fall -late 0.35 [get_clocks clk1]
|
||||
}
|
||||
set_clock_latency -source -rise -early 0.1 [get_clocks clk1]
|
||||
set_clock_latency -source -rise -late 0.3 [get_clocks clk1]
|
||||
set_clock_latency -source -fall -early 0.15 [get_clocks clk1]
|
||||
set_clock_latency -source -fall -late 0.35 [get_clocks clk1]
|
||||
report_checks
|
||||
|
||||
############################################################
|
||||
|
|
@ -136,10 +132,8 @@ report_checks
|
|||
# Clock uncertainty on pin
|
||||
############################################################
|
||||
puts "--- clock uncertainty on pin ---"
|
||||
catch {
|
||||
set_clock_uncertainty -setup 0.25 [get_ports clk1]
|
||||
set_clock_uncertainty -hold 0.08 [get_ports clk1]
|
||||
}
|
||||
set_clock_uncertainty -setup 0.25 [get_ports clk1]
|
||||
set_clock_uncertainty -hold 0.08 [get_ports clk1]
|
||||
report_checks
|
||||
|
||||
############################################################
|
||||
|
|
@ -181,40 +175,32 @@ report_checks
|
|||
# Remove clock latency
|
||||
############################################################
|
||||
puts "--- unset_clock_latency ---"
|
||||
catch {
|
||||
unset_clock_latency -source [get_clocks clk1]
|
||||
report_checks
|
||||
}
|
||||
unset_clock_latency -source [get_clocks clk1]
|
||||
report_checks
|
||||
|
||||
############################################################
|
||||
# Remove clock uncertainty
|
||||
############################################################
|
||||
puts "--- unset_clock_uncertainty ---"
|
||||
catch {
|
||||
unset_clock_uncertainty -setup [get_clocks clk1]
|
||||
unset_clock_uncertainty -hold [get_clocks clk1]
|
||||
report_checks
|
||||
}
|
||||
unset_clock_uncertainty -setup [get_clocks clk1]
|
||||
unset_clock_uncertainty -hold [get_clocks clk1]
|
||||
report_checks
|
||||
|
||||
############################################################
|
||||
# Remove inter-clock uncertainty
|
||||
############################################################
|
||||
puts "--- unset inter-clock uncertainty ---"
|
||||
catch {
|
||||
unset_clock_uncertainty -from [get_clocks clk1] -to [get_clocks clk2] -setup
|
||||
unset_clock_uncertainty -from [get_clocks clk1] -to [get_clocks clk2] -hold
|
||||
report_checks
|
||||
}
|
||||
unset_clock_uncertainty -from [get_clocks clk1] -to [get_clocks clk2] -setup
|
||||
unset_clock_uncertainty -from [get_clocks clk1] -to [get_clocks clk2] -hold
|
||||
report_checks
|
||||
|
||||
############################################################
|
||||
# Remove propagated clock
|
||||
############################################################
|
||||
puts "--- unset_propagated_clock ---"
|
||||
catch {
|
||||
unset_propagated_clock [get_clocks clk1]
|
||||
unset_propagated_clock [get_clocks clk2]
|
||||
report_checks
|
||||
}
|
||||
unset_propagated_clock [get_clocks clk1]
|
||||
unset_propagated_clock [get_clocks clk2]
|
||||
report_checks
|
||||
|
||||
############################################################
|
||||
# Final write
|
||||
|
|
|
|||
|
|
@ -87,13 +87,9 @@ set_max_time_borrow 1.5 [get_clocks clk2]
|
|||
set_max_time_borrow 1.0 [get_pins reg1/D]
|
||||
set_max_time_borrow 0.8 [get_pins reg2/D]
|
||||
|
||||
catch {
|
||||
set_max_time_borrow 1.2 [get_cells reg1]
|
||||
}
|
||||
set_max_time_borrow 1.2 [get_cells reg1]
|
||||
|
||||
catch {
|
||||
set_max_time_borrow 0.9 [get_cells reg3]
|
||||
}
|
||||
set_max_time_borrow 0.9 [get_cells reg3]
|
||||
|
||||
############################################################
|
||||
# Min pulse width on all targets
|
||||
|
|
@ -109,19 +105,13 @@ set_min_pulse_width -low 0.4 [get_clocks clk1]
|
|||
set_min_pulse_width 0.55 [get_clocks clk2]
|
||||
|
||||
# Pin
|
||||
catch {
|
||||
set_min_pulse_width 0.3 [get_pins reg1/CK]
|
||||
}
|
||||
set_min_pulse_width 0.3 [get_pins reg1/CK]
|
||||
|
||||
catch {
|
||||
set_min_pulse_width -high 0.35 [get_pins reg2/CK]
|
||||
set_min_pulse_width -low 0.25 [get_pins reg2/CK]
|
||||
}
|
||||
set_min_pulse_width -high 0.35 [get_pins reg2/CK]
|
||||
set_min_pulse_width -low 0.25 [get_pins reg2/CK]
|
||||
|
||||
# Instance
|
||||
catch {
|
||||
set_min_pulse_width 0.45 [get_cells reg3]
|
||||
}
|
||||
set_min_pulse_width 0.45 [get_cells reg3]
|
||||
|
||||
############################################################
|
||||
# set_max_area
|
||||
|
|
|
|||
|
|
@ -53,18 +53,12 @@ set_max_capacitance 0.1 [get_ports out1]
|
|||
set_max_capacitance 0.15 [get_ports out2]
|
||||
|
||||
# Pin-level cap limits
|
||||
catch {
|
||||
set_max_capacitance 0.08 [get_pins reg1/Q]
|
||||
}
|
||||
set_max_capacitance 0.08 [get_pins reg1/Q]
|
||||
|
||||
# Min capacitance
|
||||
catch {
|
||||
set_min_capacitance 0.001 [current_design]
|
||||
}
|
||||
set_min_capacitance 0.001 [current_design]
|
||||
|
||||
catch {
|
||||
set_min_capacitance 0.0005 [get_ports out1]
|
||||
}
|
||||
set_min_capacitance 0.0005 [get_ports out1]
|
||||
|
||||
############################################################
|
||||
# Max/min fanout limits
|
||||
|
|
@ -99,16 +93,12 @@ set_min_pulse_width -low 0.4 [get_clocks clk1]
|
|||
set_min_pulse_width 0.7 [get_clocks clk2]
|
||||
|
||||
# Pin min pulse width
|
||||
catch {
|
||||
set_min_pulse_width 0.3 [get_pins reg1/CK]
|
||||
set_min_pulse_width -high 0.35 [get_pins reg2/CK]
|
||||
set_min_pulse_width -low 0.25 [get_pins reg2/CK]
|
||||
}
|
||||
set_min_pulse_width 0.3 [get_pins reg1/CK]
|
||||
set_min_pulse_width -high 0.35 [get_pins reg2/CK]
|
||||
set_min_pulse_width -low 0.25 [get_pins reg2/CK]
|
||||
|
||||
# Instance min pulse width
|
||||
catch {
|
||||
set_min_pulse_width 0.45 [get_cells reg3]
|
||||
}
|
||||
set_min_pulse_width 0.45 [get_cells reg3]
|
||||
|
||||
############################################################
|
||||
# Latch borrow limits
|
||||
|
|
@ -118,9 +108,7 @@ set_max_time_borrow 1.5 [get_clocks clk2]
|
|||
|
||||
set_max_time_borrow 1.0 [get_pins reg1/D]
|
||||
|
||||
catch {
|
||||
set_max_time_borrow 1.2 [get_cells reg2]
|
||||
}
|
||||
set_max_time_borrow 1.2 [get_cells reg2]
|
||||
|
||||
############################################################
|
||||
# Port slew limits
|
||||
|
|
|
|||
|
|
@ -116,9 +116,7 @@ set_logic_zero [get_ports in1]
|
|||
set_logic_one [get_ports in2]
|
||||
|
||||
# set_logic_dc (don't care)
|
||||
catch {
|
||||
set_logic_dc [get_ports in3]
|
||||
}
|
||||
set_logic_dc [get_ports in3]
|
||||
|
||||
# Write SDC with logic values (exercises writeConstants)
|
||||
set sdc_file4 [make_result_file sdc_logic1.sdc]
|
||||
|
|
@ -130,21 +128,13 @@ report_checks
|
|||
# Data checks
|
||||
############################################################
|
||||
|
||||
catch {
|
||||
set_data_check -from [get_pins reg1/Q] -to [get_pins reg2/D] -setup 0.5
|
||||
}
|
||||
set_data_check -from [get_pins reg1/Q] -to [get_pins reg2/D] -setup 0.5
|
||||
|
||||
catch {
|
||||
set_data_check -from [get_pins reg1/Q] -to [get_pins reg2/D] -hold 0.3
|
||||
}
|
||||
set_data_check -from [get_pins reg1/Q] -to [get_pins reg2/D] -hold 0.3
|
||||
|
||||
catch {
|
||||
set_data_check -rise_from [get_pins reg1/Q] -to [get_pins reg2/D] -setup 0.6
|
||||
}
|
||||
set_data_check -rise_from [get_pins reg1/Q] -to [get_pins reg2/D] -setup 0.6
|
||||
|
||||
catch {
|
||||
set_data_check -from [get_pins reg1/Q] -fall_to [get_pins reg2/D] -hold 0.25
|
||||
}
|
||||
set_data_check -from [get_pins reg1/Q] -fall_to [get_pins reg2/D] -hold 0.25
|
||||
|
||||
# Write with data checks
|
||||
set sdc_file5 [make_result_file sdc_datacheck1.sdc]
|
||||
|
|
@ -174,16 +164,12 @@ set_clock_gating_check -setup 0.35 [get_clocks clk2]
|
|||
set_clock_gating_check -hold 0.15 [get_clocks clk2]
|
||||
|
||||
# Instance-level
|
||||
catch {
|
||||
set_clock_gating_check -setup 0.3 [get_cells reg1]
|
||||
set_clock_gating_check -hold 0.1 [get_cells reg1]
|
||||
}
|
||||
set_clock_gating_check -setup 0.3 [get_cells reg1]
|
||||
set_clock_gating_check -hold 0.1 [get_cells reg1]
|
||||
|
||||
# Pin-level
|
||||
catch {
|
||||
set_clock_gating_check -setup 0.25 [get_pins reg1/CK]
|
||||
set_clock_gating_check -hold 0.08 [get_pins reg1/CK]
|
||||
}
|
||||
set_clock_gating_check -setup 0.25 [get_pins reg1/CK]
|
||||
set_clock_gating_check -hold 0.08 [get_pins reg1/CK]
|
||||
|
||||
# Write SDC with clock gating
|
||||
set sdc_file6 [make_result_file sdc_clkgate1.sdc]
|
||||
|
|
@ -196,10 +182,8 @@ write_sdc -no_timestamp $sdc_file6
|
|||
set_ideal_network [get_ports clk1]
|
||||
set_ideal_network [get_ports clk2]
|
||||
|
||||
catch {
|
||||
set_ideal_transition 0.0 [get_ports clk1]
|
||||
set_ideal_transition 0.05 [get_ports clk2]
|
||||
}
|
||||
set_ideal_transition 0.0 [get_ports clk1]
|
||||
set_ideal_transition 0.05 [get_ports clk2]
|
||||
|
||||
############################################################
|
||||
# Min pulse width on various objects
|
||||
|
|
@ -211,13 +195,9 @@ set_min_pulse_width -low 0.4 [get_clocks clk1]
|
|||
|
||||
set_min_pulse_width 0.8 [get_clocks clk2]
|
||||
|
||||
catch {
|
||||
set_min_pulse_width 0.5 [get_pins reg1/CK]
|
||||
}
|
||||
set_min_pulse_width 0.5 [get_pins reg1/CK]
|
||||
|
||||
catch {
|
||||
set_min_pulse_width 0.6 [get_cells reg1]
|
||||
}
|
||||
set_min_pulse_width 0.6 [get_cells reg1]
|
||||
|
||||
############################################################
|
||||
# Latch borrow limits on various objects
|
||||
|
|
@ -228,9 +208,7 @@ set_max_time_borrow 1.5 [get_clocks clk2]
|
|||
|
||||
set_max_time_borrow 1.0 [get_pins reg1/D]
|
||||
|
||||
catch {
|
||||
set_max_time_borrow 1.2 [get_cells reg2]
|
||||
}
|
||||
set_max_time_borrow 1.2 [get_cells reg2]
|
||||
|
||||
############################################################
|
||||
# Comprehensive write with all constraints
|
||||
|
|
|
|||
|
|
@ -130,13 +130,9 @@ set_disable_timing [get_lib_cells NangateOpenCellLibrary/NAND2_X1]
|
|||
# Data check (DataCheck.cc)
|
||||
############################################################
|
||||
|
||||
catch {
|
||||
set_data_check -from [get_pins reg1/Q] -to [get_pins reg2/D] -setup 0.5
|
||||
}
|
||||
set_data_check -from [get_pins reg1/Q] -to [get_pins reg2/D] -setup 0.5
|
||||
|
||||
catch {
|
||||
set_data_check -from [get_pins reg1/Q] -to [get_pins reg2/D] -hold 0.3
|
||||
}
|
||||
set_data_check -from [get_pins reg1/Q] -to [get_pins reg2/D] -hold 0.3
|
||||
|
||||
catch {
|
||||
set_data_check -from [get_pins reg1/Q] -to [get_pins reg2/D] -setup 0.6 -clock_fall
|
||||
|
|
@ -241,7 +237,7 @@ set_wire_load_mode enclosed
|
|||
# Voltage setting
|
||||
############################################################
|
||||
|
||||
catch {set_voltage 1.1 -min 0.9}
|
||||
set_voltage 1.1 -min 0.9
|
||||
|
||||
############################################################
|
||||
# Write SDC with all the constraints
|
||||
|
|
|
|||
|
|
@ -111,10 +111,6 @@ set sdf_gz [make_result_file "${test_name}_gz.sdf.gz"]
|
|||
write_sdf -gzip -no_timestamp $sdf_gz
|
||||
|
||||
# Read gzip SDF
|
||||
set rc [catch { read_sdf $sdf_gz } msg]
|
||||
if { $rc == 0 } {
|
||||
} else {
|
||||
puts "INFO: read gzip SDF: $msg"
|
||||
}
|
||||
read_sdf $sdf_gz
|
||||
|
||||
report_checks
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -166,27 +166,19 @@ foreach pe $paths2 {
|
|||
}
|
||||
|
||||
puts "--- get_fanin with -trace_arcs all (thru disabled/constants) ---"
|
||||
catch {
|
||||
set fanin_thru [get_fanin -to [get_pins reg1/D] -trace_arcs all]
|
||||
puts "Fanin trace_arcs all: [llength $fanin_thru]"
|
||||
}
|
||||
set fanin_thru [get_fanin -to [get_pins reg1/D] -trace_arcs all]
|
||||
puts "Fanin trace_arcs all: [llength $fanin_thru]"
|
||||
|
||||
puts "--- get_fanin with -trace_arcs timing ---"
|
||||
catch {
|
||||
set fanin_timing [get_fanin -to [get_pins reg1/D] -trace_arcs timing]
|
||||
puts "Fanin trace_arcs timing: [llength $fanin_timing]"
|
||||
}
|
||||
set fanin_timing [get_fanin -to [get_pins reg1/D] -trace_arcs timing]
|
||||
puts "Fanin trace_arcs timing: [llength $fanin_timing]"
|
||||
|
||||
puts "--- get_fanin with -trace_arcs enabled ---"
|
||||
catch {
|
||||
set fanin_enabled [get_fanin -to [get_pins reg1/D] -trace_arcs enabled]
|
||||
puts "Fanin trace_arcs enabled: [llength $fanin_enabled]"
|
||||
}
|
||||
set fanin_enabled [get_fanin -to [get_pins reg1/D] -trace_arcs enabled]
|
||||
puts "Fanin trace_arcs enabled: [llength $fanin_enabled]"
|
||||
|
||||
puts "--- get_fanin thru constants ---"
|
||||
set_case_analysis 1 [get_ports in1]
|
||||
catch {
|
||||
set fanin_const [get_fanin -to [get_pins reg1/D] -trace_arcs all]
|
||||
puts "Fanin with constants: [llength $fanin_const]"
|
||||
}
|
||||
set fanin_const [get_fanin -to [get_pins reg1/D] -trace_arcs all]
|
||||
puts "Fanin with constants: [llength $fanin_const]"
|
||||
unset_case_analysis [get_ports in1]
|
||||
|
|
|
|||
|
|
@ -38,15 +38,13 @@ report_checks -path_delay max
|
|||
report_checks -path_delay min
|
||||
|
||||
puts "--- group_path with -weight ---"
|
||||
catch { group_path -name weighted_group -from [get_ports in1] -weight 2.0 }
|
||||
group_path -name weighted_group -from [get_ports in1] -weight 2.0
|
||||
|
||||
puts "--- group_path with -default ---"
|
||||
catch { group_path -name default_group -default }
|
||||
|
||||
puts "--- report_checks with -group filter ---"
|
||||
catch {
|
||||
report_checks -path_delay max -group_path_count 3
|
||||
}
|
||||
report_checks -path_delay max -group_path_count 3
|
||||
|
||||
puts "--- report_path_end with specific endpoints ---"
|
||||
set pe_list [find_timing_paths -path_delay max -endpoint_path_count 3]
|
||||
|
|
@ -71,15 +69,13 @@ set paths_mm [find_timing_paths -path_delay min_max -endpoint_path_count 3]
|
|||
puts "Min_max paths: [llength $paths_mm]"
|
||||
|
||||
puts "--- find_timing_paths with unique_edges ---"
|
||||
catch {
|
||||
set paths_ue [find_timing_paths -path_delay max -endpoint_path_count 5 -unique_paths_to_endpoint]
|
||||
puts "Unique edge paths: [llength $paths_ue]"
|
||||
}
|
||||
set paths_ue [find_timing_paths -path_delay max -endpoint_path_count 5 -unique_paths_to_endpoint]
|
||||
puts "Unique edge paths: [llength $paths_ue]"
|
||||
|
||||
puts "--- set_clock_sense ---"
|
||||
catch { set_clock_sense -positive [get_pins ckbuf1/Z] -clocks clk }
|
||||
set_clock_sense -positive [get_pins ckbuf1/Z] -clocks clk
|
||||
report_checks -path_delay max
|
||||
catch { set_clock_sense -stop [get_pins ckbuf2/Z] -clocks clk }
|
||||
set_clock_sense -stop [get_pins ckbuf2/Z] -clocks clk
|
||||
report_checks -path_delay max
|
||||
|
||||
puts "--- report_check_types ---"
|
||||
|
|
|
|||
|
|
@ -20,37 +20,27 @@ set_output_delay -clock clk 1.5 [get_ports out2]
|
|||
report_checks > /dev/null
|
||||
|
||||
puts "--- set_analysis_type bc_wc ---"
|
||||
catch {
|
||||
set_operating_conditions -analysis_type bc_wc
|
||||
}
|
||||
set_operating_conditions -analysis_type bc_wc
|
||||
report_checks -path_delay max > /dev/null
|
||||
|
||||
puts "--- set_analysis_type single ---"
|
||||
catch {
|
||||
set_operating_conditions -analysis_type single
|
||||
}
|
||||
set_operating_conditions -analysis_type single
|
||||
report_checks -path_delay max > /dev/null
|
||||
|
||||
puts "--- set_analysis_type on_chip_variation ---"
|
||||
catch {
|
||||
set_operating_conditions -analysis_type on_chip_variation
|
||||
}
|
||||
set_operating_conditions -analysis_type on_chip_variation
|
||||
report_checks -path_delay max -format full_clock_expanded
|
||||
report_checks -path_delay min -format full_clock_expanded
|
||||
|
||||
puts "--- set_voltage ---"
|
||||
catch {
|
||||
set_voltage 1.1
|
||||
set_voltage 1.1 -min 0.9
|
||||
report_checks -path_delay max > /dev/null
|
||||
}
|
||||
set_voltage 1.1
|
||||
set_voltage 1.1 -min 0.9
|
||||
report_checks -path_delay max > /dev/null
|
||||
|
||||
puts "--- set_voltage on net ---"
|
||||
catch {
|
||||
set_voltage 1.2 -object_list [get_nets n1]
|
||||
set_voltage 1.2 -min 1.0 -object_list [get_nets n1]
|
||||
report_checks -path_delay max > /dev/null
|
||||
}
|
||||
set_voltage 1.2 -object_list [get_nets n1]
|
||||
set_voltage 1.2 -min 1.0 -object_list [get_nets n1]
|
||||
report_checks -path_delay max > /dev/null
|
||||
|
||||
puts "--- set_load (port external pin cap) ---"
|
||||
set_load 0.05 [get_ports out1]
|
||||
|
|
@ -64,32 +54,24 @@ report_checks -path_delay max
|
|||
report_checks -path_delay min
|
||||
|
||||
puts "--- set_load -wire_load ---"
|
||||
catch {
|
||||
set_load -wire_load 0.01 [get_ports out1]
|
||||
report_checks -path_delay max > /dev/null
|
||||
}
|
||||
set_load -wire_load 0.01 [get_ports out1]
|
||||
report_checks -path_delay max > /dev/null
|
||||
|
||||
puts "--- set_fanout_load ---"
|
||||
catch {
|
||||
set_fanout_load 4 [get_ports out1]
|
||||
report_checks -path_delay max > /dev/null
|
||||
}
|
||||
set_fanout_load 4 [get_ports out1]
|
||||
report_checks -path_delay max > /dev/null
|
||||
|
||||
puts "--- Net capacitance ---"
|
||||
catch {
|
||||
set corner [sta::cmd_corner]
|
||||
set net_cap [[get_nets n1] capacitance $corner max]
|
||||
puts "Net n1 capacitance: $net_cap"
|
||||
set pin_cap [[get_nets n1] pin_capacitance $corner max]
|
||||
puts "Net n1 pin_cap: $pin_cap"
|
||||
set wire_cap [[get_nets n1] wire_capacitance $corner max]
|
||||
puts "Net n1 wire_cap: $wire_cap"
|
||||
}
|
||||
set corner [sta::cmd_corner]
|
||||
set net_cap [[get_nets n1] capacitance $corner max]
|
||||
puts "Net n1 capacitance: $net_cap"
|
||||
set pin_cap [[get_nets n1] pin_capacitance $corner max]
|
||||
puts "Net n1 pin_cap: $pin_cap"
|
||||
set wire_cap [[get_nets n1] wire_capacitance $corner max]
|
||||
puts "Net n1 wire_cap: $wire_cap"
|
||||
|
||||
puts "--- set_wire_load_mode ---"
|
||||
catch {
|
||||
set_wire_load_mode enclosed
|
||||
}
|
||||
set_wire_load_mode enclosed
|
||||
|
||||
puts "--- report_checks with various fields after load changes ---"
|
||||
report_checks -fields {capacitance slew fanout} -path_delay max
|
||||
|
|
@ -107,25 +89,19 @@ set_drive 100 [get_ports in1]
|
|||
report_checks -path_delay max > /dev/null
|
||||
|
||||
puts "--- set_driving_cell ---"
|
||||
catch {
|
||||
set_driving_cell -lib_cell BUF_X1 -library NangateOpenCellLibrary [get_ports in1]
|
||||
report_checks -path_delay max -from [get_ports in1]
|
||||
}
|
||||
set_driving_cell -lib_cell BUF_X1 -library NangateOpenCellLibrary [get_ports in1]
|
||||
report_checks -path_delay max -from [get_ports in1]
|
||||
|
||||
puts "--- Timing derate with cell-level ---"
|
||||
set_timing_derate -early 0.95
|
||||
set_timing_derate -late 1.05
|
||||
report_checks -path_delay max > /dev/null
|
||||
catch {
|
||||
set_timing_derate -early -cell_delay 0.93
|
||||
set_timing_derate -late -cell_delay 1.07
|
||||
report_checks -path_delay max > /dev/null
|
||||
}
|
||||
catch {
|
||||
set_timing_derate -early -net_delay 0.96
|
||||
set_timing_derate -late -net_delay 1.04
|
||||
report_checks -path_delay max > /dev/null
|
||||
}
|
||||
set_timing_derate -early -cell_delay 0.93
|
||||
set_timing_derate -late -cell_delay 1.07
|
||||
report_checks -path_delay max > /dev/null
|
||||
set_timing_derate -early -net_delay 0.96
|
||||
set_timing_derate -late -net_delay 1.04
|
||||
report_checks -path_delay max > /dev/null
|
||||
unset_timing_derate
|
||||
|
||||
puts "--- report_checks after all modifications ---"
|
||||
|
|
@ -141,15 +117,11 @@ set sdc_file [make_result_file "search_multicorner_analysis.sdc"]
|
|||
write_sdc $sdc_file
|
||||
|
||||
puts "--- set_resistance on net ---"
|
||||
catch {
|
||||
set_resistance 100 [get_nets n1]
|
||||
report_checks -path_delay max > /dev/null
|
||||
}
|
||||
set_resistance 100 [get_nets n1]
|
||||
report_checks -path_delay max > /dev/null
|
||||
|
||||
puts "--- set_max_area ---"
|
||||
catch {
|
||||
set_max_area 1000
|
||||
}
|
||||
set_max_area 1000
|
||||
|
||||
puts "--- isClock / isPropagatedClock queries ---"
|
||||
catch {
|
||||
|
|
|
|||
|
|
@ -169,8 +169,8 @@ foreach pe $pe_out {
|
|||
puts "margin: [$pe margin]"
|
||||
puts "data_arrival: [$pe data_arrival_time]"
|
||||
puts "data_required: [$pe data_required_time]"
|
||||
catch { puts "source_clk_offset: [$pe source_clk_offset]" }
|
||||
catch { puts "target_clk: [get_name [$pe target_clk]]" }
|
||||
catch { puts "target_clk_time: [$pe target_clk_time]" }
|
||||
puts "source_clk_offset: [$pe source_clk_offset]"
|
||||
puts "target_clk: [get_name [$pe target_clk]]"
|
||||
puts "target_clk_time: [$pe target_clk_time]"
|
||||
break
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,11 +74,9 @@ set group_names [sta::path_group_names]
|
|||
puts "Path group names: $group_names"
|
||||
|
||||
puts "--- is_path_group_name ---"
|
||||
catch {
|
||||
puts "clk is group: [sta::is_path_group_name clk]"
|
||||
puts "input_paths is group: [sta::is_path_group_name input_paths]"
|
||||
puts "nonexistent is group: [sta::is_path_group_name nonexistent_group]"
|
||||
}
|
||||
puts "clk is group: [sta::is_path_group_name clk]"
|
||||
puts "input_paths is group: [sta::is_path_group_name input_paths]"
|
||||
puts "nonexistent is group: [sta::is_path_group_name nonexistent_group]"
|
||||
|
||||
puts "--- group_path -default ---"
|
||||
catch {
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ puts "DFF_X1 base_name: [get_property $dff_cell base_name]"
|
|||
puts "DFF_X1 is_buffer: [get_property $dff_cell is_buffer]"
|
||||
set dff_lib [get_property $dff_cell library]
|
||||
puts "DFF_X1 library: [get_name $dff_lib]"
|
||||
catch { puts "DFF_X1 area: [get_property $dff_cell area]" }
|
||||
puts "DFF_X1 area: [get_property $dff_cell area]"
|
||||
catch { puts "DFF_X1 leakage: [get_property $dff_cell cell_leakage_power]" }
|
||||
|
||||
puts "--- LibertyPort properties ---"
|
||||
|
|
@ -144,7 +144,7 @@ set lp_d [get_lib_pins NangateOpenCellLibrary/DFF_X1/D]
|
|||
puts "DFF_X1/D name: [get_property $lp_d name]"
|
||||
puts "DFF_X1/D full_name: [get_property $lp_d full_name]"
|
||||
puts "DFF_X1/D direction: [get_property $lp_d direction]"
|
||||
catch { puts "DFF_X1/D capacitance: [get_property $lp_d capacitance]" }
|
||||
puts "DFF_X1/D capacitance: [get_property $lp_d capacitance]"
|
||||
catch { puts "DFF_X1/D is_clock: [get_property $lp_d is_clock]" }
|
||||
catch { puts "DFF_X1/D is_register_clock: [get_property $lp_d is_register_clock]" }
|
||||
set lp_ck [get_lib_pins NangateOpenCellLibrary/DFF_X1/CK]
|
||||
|
|
@ -190,19 +190,13 @@ foreach pe $path_ends {
|
|||
puts "pathend startpoint: [get_full_name $sp]"
|
||||
set ep [get_property $pe endpoint]
|
||||
puts "pathend endpoint: [get_full_name $ep]"
|
||||
catch {
|
||||
set sc [get_property $pe startpoint_clock]
|
||||
puts "pathend startpoint_clock: [get_name $sc]"
|
||||
}
|
||||
catch {
|
||||
set ec [get_property $pe endpoint_clock]
|
||||
puts "pathend endpoint_clock: [get_name $ec]"
|
||||
}
|
||||
set sc [get_property $pe startpoint_clock]
|
||||
puts "pathend startpoint_clock: [get_name $sc]"
|
||||
set ec [get_property $pe endpoint_clock]
|
||||
puts "pathend endpoint_clock: [get_name $ec]"
|
||||
puts "pathend slack: [get_property $pe slack]"
|
||||
catch {
|
||||
set pts [get_property $pe points]
|
||||
puts "pathend points count: [llength $pts]"
|
||||
}
|
||||
set pts [get_property $pe points]
|
||||
puts "pathend points count: [llength $pts]"
|
||||
break
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,14 +21,10 @@ puts "--- report_power ---"
|
|||
report_power
|
||||
|
||||
puts "--- report_power -instances ---"
|
||||
catch {
|
||||
report_power -instances [get_cells {reg1 reg2 and1 buf1}]
|
||||
}
|
||||
report_power -instances [get_cells {reg1 reg2 and1 buf1}]
|
||||
|
||||
puts "--- report_power -digits 6 ---"
|
||||
catch {
|
||||
report_power -digits 6
|
||||
}
|
||||
report_power -digits 6
|
||||
|
||||
puts "--- Pin activity ---"
|
||||
catch {
|
||||
|
|
@ -53,22 +49,16 @@ catch {
|
|||
}
|
||||
|
||||
puts "--- set_power_activity on global ---"
|
||||
catch {
|
||||
set_power_activity -global -activity 0.2 -duty 0.5
|
||||
report_power
|
||||
}
|
||||
set_power_activity -global -activity 0.2 -duty 0.5
|
||||
report_power
|
||||
|
||||
puts "--- set_power_activity on input_ports ---"
|
||||
catch {
|
||||
set_power_activity -input -activity 0.4 -duty 0.5
|
||||
report_power
|
||||
}
|
||||
set_power_activity -input -activity 0.4 -duty 0.5
|
||||
report_power
|
||||
|
||||
puts "--- report_power with clock propagation ---"
|
||||
set_propagated_clock [get_clocks clk]
|
||||
catch {
|
||||
report_power
|
||||
}
|
||||
report_power
|
||||
|
||||
puts "--- isClock queries ---"
|
||||
catch {
|
||||
|
|
@ -81,9 +71,7 @@ catch {
|
|||
puts "--- report with timing derate after power ---"
|
||||
set_timing_derate -early 0.95
|
||||
set_timing_derate -late 1.05
|
||||
catch {
|
||||
report_power
|
||||
}
|
||||
report_power
|
||||
unset_timing_derate
|
||||
|
||||
puts "--- Slew limit checking after power ---"
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ puts "lport name: [get_property $lport name]"
|
|||
puts "lport full_name: [get_property $lport full_name]"
|
||||
puts "lport direction: [get_property $lport direction]"
|
||||
catch { puts "lport function: [get_property $lport function]" }
|
||||
catch { puts "lport capacitance: [get_property $lport capacitance]" }
|
||||
puts "lport capacitance: [get_property $lport capacitance]"
|
||||
catch { puts "lport max_capacitance: [get_property $lport max_capacitance]" }
|
||||
catch { puts "lport max_transition: [get_property $lport max_transition]" }
|
||||
catch { puts "lport is_register_clock: [get_property $lport is_register_clock]" }
|
||||
|
|
@ -60,15 +60,13 @@ set and_cell [get_lib_cells NangateOpenCellLibrary/AND2_X1]
|
|||
puts "and is_buffer: [get_property $and_cell is_buffer]"
|
||||
set dff_cell [get_lib_cells NangateOpenCellLibrary/DFF_X1]
|
||||
puts "dff is_buffer: [get_property $dff_cell is_buffer]"
|
||||
catch { puts "dff area: [get_property $dff_cell area]" }
|
||||
puts "dff area: [get_property $dff_cell area]"
|
||||
catch { puts "dff cell_leakage_power: [get_property $dff_cell cell_leakage_power]" }
|
||||
|
||||
puts "--- LibertyLibrary properties ---"
|
||||
set lib [get_libs NangateOpenCellLibrary]
|
||||
catch {
|
||||
set lib_cell_property [get_property -object_type lib $lib name]
|
||||
puts "lib by lib type: $lib_cell_property"
|
||||
}
|
||||
set lib_cell_property [get_property -object_type lib $lib name]
|
||||
puts "lib by lib type: $lib_cell_property"
|
||||
|
||||
puts "--- Clock extra properties ---"
|
||||
set clk_obj [get_clocks clk]
|
||||
|
|
@ -133,20 +131,12 @@ foreach p $fan_pins {
|
|||
}
|
||||
|
||||
puts "--- Slew/Cap/Fanout check slack ---"
|
||||
catch {
|
||||
puts "Max slew check slack: [sta::max_slew_check_slack]"
|
||||
puts "Max slew check limit: [sta::max_slew_check_limit]"
|
||||
}
|
||||
catch {
|
||||
puts "Max cap check slack: [sta::max_capacitance_check_slack]"
|
||||
puts "Max cap check limit: [sta::max_capacitance_check_limit]"
|
||||
}
|
||||
catch {
|
||||
puts "Max fanout check slack: [sta::max_fanout_check_slack]"
|
||||
puts "Max fanout check limit: [sta::max_fanout_check_limit]"
|
||||
}
|
||||
catch {
|
||||
puts "Max slew violation count: [sta::max_slew_violation_count]"
|
||||
puts "Max cap violation count: [sta::max_capacitance_violation_count]"
|
||||
puts "Max fanout violation count: [sta::max_fanout_violation_count]"
|
||||
}
|
||||
puts "Max slew check slack: [sta::max_slew_check_slack]"
|
||||
puts "Max slew check limit: [sta::max_slew_check_limit]"
|
||||
puts "Max cap check slack: [sta::max_capacitance_check_slack]"
|
||||
puts "Max cap check limit: [sta::max_capacitance_check_limit]"
|
||||
puts "Max fanout check slack: [sta::max_fanout_check_slack]"
|
||||
puts "Max fanout check limit: [sta::max_fanout_check_limit]"
|
||||
puts "Max slew violation count: [sta::max_slew_violation_count]"
|
||||
puts "Max cap violation count: [sta::max_capacitance_violation_count]"
|
||||
puts "Max fanout violation count: [sta::max_fanout_violation_count]"
|
||||
|
|
|
|||
|
|
@ -128,15 +128,15 @@ puts "reg1 is_memory: [get_property $reg_inst is_memory]"
|
|||
############################################################
|
||||
puts "--- LibertyCell area and leakage ---"
|
||||
set dff_cell [get_lib_cells NangateOpenCellLibrary/DFF_X1]
|
||||
catch { puts "DFF_X1 area: [get_property $dff_cell area]" }
|
||||
puts "DFF_X1 area: [get_property $dff_cell area]"
|
||||
catch { puts "DFF_X1 cell_leakage_power: [get_property $dff_cell cell_leakage_power]" }
|
||||
set buf_cell [get_lib_cells NangateOpenCellLibrary/BUF_X1]
|
||||
catch { puts "BUF_X1 area: [get_property $buf_cell area]" }
|
||||
puts "BUF_X1 area: [get_property $buf_cell area]"
|
||||
catch { puts "BUF_X1 cell_leakage_power: [get_property $buf_cell cell_leakage_power]" }
|
||||
set inv_cell [get_lib_cells NangateOpenCellLibrary/INV_X1]
|
||||
catch { puts "INV_X1 area: [get_property $inv_cell area]" }
|
||||
puts "INV_X1 area: [get_property $inv_cell area]"
|
||||
set and_cell [get_lib_cells NangateOpenCellLibrary/AND2_X1]
|
||||
catch { puts "AND2_X1 area: [get_property $and_cell area]" }
|
||||
puts "AND2_X1 area: [get_property $and_cell area]"
|
||||
|
||||
############################################################
|
||||
# Path group matching: group_path -name with -from and -through
|
||||
|
|
@ -177,8 +177,8 @@ foreach pe $paths_min {
|
|||
puts "--- path_group_names ---"
|
||||
set group_names [sta::path_group_names]
|
||||
puts "Path group names: $group_names"
|
||||
catch { puts "input_grp is group: [sta::is_path_group_name input_grp]" }
|
||||
catch { puts "nonexistent is group: [sta::is_path_group_name nonexistent_grp]" }
|
||||
puts "input_grp is group: [sta::is_path_group_name input_grp]"
|
||||
puts "nonexistent is group: [sta::is_path_group_name nonexistent_grp]"
|
||||
|
||||
############################################################
|
||||
# TimingArcSet properties on different cell types
|
||||
|
|
|
|||
|
|
@ -99,30 +99,24 @@ unset_timing_derate
|
|||
# Timing derate on instance
|
||||
############################################################
|
||||
puts "--- timing_derate on instance ---"
|
||||
catch {
|
||||
set_timing_derate -early 0.9 [get_cells reg1]
|
||||
set_timing_derate -late 1.1 [get_cells reg1]
|
||||
report_checks -path_delay max
|
||||
unset_timing_derate
|
||||
}
|
||||
set_timing_derate -early 0.9 [get_cells reg1]
|
||||
set_timing_derate -late 1.1 [get_cells reg1]
|
||||
report_checks -path_delay max
|
||||
unset_timing_derate
|
||||
|
||||
############################################################
|
||||
# Set slew limit on clock
|
||||
############################################################
|
||||
puts "--- set_max_transition on clock ---"
|
||||
catch {
|
||||
set_max_transition 0.5 -clock_path [get_clocks clk1]
|
||||
report_check_types -max_slew
|
||||
}
|
||||
set_max_transition 0.5 -clock_path [get_clocks clk1]
|
||||
report_check_types -max_slew
|
||||
|
||||
############################################################
|
||||
# Set capacitance limit on port
|
||||
############################################################
|
||||
puts "--- set_max_capacitance on port ---"
|
||||
catch {
|
||||
set_max_capacitance 0.1 [get_ports out1]
|
||||
report_check_types -max_capacitance
|
||||
}
|
||||
set_max_capacitance 0.1 [get_ports out1]
|
||||
report_check_types -max_capacitance
|
||||
|
||||
############################################################
|
||||
# Port loading
|
||||
|
|
|
|||
|
|
@ -162,10 +162,8 @@ catch {
|
|||
# set_clock_gating_check
|
||||
############################################################
|
||||
puts "--- set_clock_gating_check ---"
|
||||
catch {
|
||||
set_clock_gating_check -setup 0.5 [get_cells clk_gate]
|
||||
report_checks -path_delay max
|
||||
}
|
||||
set_clock_gating_check -setup 0.5 [get_cells clk_gate]
|
||||
report_checks -path_delay max
|
||||
|
||||
############################################################
|
||||
# write_sdc
|
||||
|
|
|
|||
|
|
@ -150,12 +150,12 @@ puts "--- find_requireds ---"
|
|||
sta::find_requireds
|
||||
|
||||
puts "--- report internal debug ---"
|
||||
catch { sta::report_tag_groups }
|
||||
catch { sta::report_tags }
|
||||
catch { sta::report_clk_infos }
|
||||
catch { sta::report_arrival_entries }
|
||||
catch { sta::report_required_entries }
|
||||
catch { sta::report_path_count_histogram }
|
||||
sta::report_tag_groups
|
||||
sta::report_tags
|
||||
sta::report_clk_infos
|
||||
sta::report_arrival_entries
|
||||
sta::report_required_entries
|
||||
sta::report_path_count_histogram
|
||||
|
||||
puts "--- report_path_end header/footer ---"
|
||||
set pe_for_report [find_timing_paths -path_delay max -endpoint_path_count 1]
|
||||
|
|
|
|||
|
|
@ -70,9 +70,9 @@ foreach pe $paths_max {
|
|||
puts " is_latch: [$pe is_latch_check] is_check: [$pe is_check] slack=[$pe slack]"
|
||||
puts " data_arrival: [$pe data_arrival_time] data_required: [$pe data_required_time]"
|
||||
puts " margin: [$pe margin]"
|
||||
catch { puts " source_clk_latency: [$pe source_clk_latency]" }
|
||||
catch { puts " target_clk_delay: [$pe target_clk_delay]" }
|
||||
catch { puts " target_clk_uncertainty: [$pe target_clk_uncertainty]" }
|
||||
puts " source_clk_latency: [$pe source_clk_latency]"
|
||||
puts " target_clk_delay: [$pe target_clk_delay]"
|
||||
puts " target_clk_uncertainty: [$pe target_clk_uncertainty]"
|
||||
}
|
||||
|
||||
############################################################
|
||||
|
|
@ -124,14 +124,10 @@ foreach pe $paths_max2 {
|
|||
set ep [get_property $pe endpoint]
|
||||
puts " endpoint: [get_full_name $ep]"
|
||||
puts " slack: [get_property $pe slack]"
|
||||
catch {
|
||||
set ec [get_property $pe endpoint_clock]
|
||||
puts " endpoint_clock: [get_name $ec]"
|
||||
}
|
||||
catch {
|
||||
set ecp [get_property $pe endpoint_clock_pin]
|
||||
puts " endpoint_clock_pin: [get_full_name $ecp]"
|
||||
}
|
||||
set ec [get_property $pe endpoint_clock]
|
||||
puts " endpoint_clock: [get_name $ec]"
|
||||
set ecp [get_property $pe endpoint_clock_pin]
|
||||
puts " endpoint_clock_pin: [get_full_name $ecp]"
|
||||
set points [get_property $pe points]
|
||||
puts " points: [llength $points]"
|
||||
break
|
||||
|
|
|
|||
|
|
@ -183,10 +183,8 @@ unset_clock_uncertainty [get_clocks clk]
|
|||
# Latch borrow limit
|
||||
############################################################
|
||||
puts "--- set_max_time_borrow ---"
|
||||
catch {
|
||||
set_max_time_borrow 1.0 [get_clocks clk]
|
||||
report_checks -path_delay max
|
||||
}
|
||||
set_max_time_borrow 1.0 [get_clocks clk]
|
||||
report_checks -path_delay max
|
||||
|
||||
############################################################
|
||||
# Min pulse width
|
||||
|
|
@ -212,11 +210,9 @@ unset_case_analysis [get_ports in1]
|
|||
# Disable timing on various targets
|
||||
############################################################
|
||||
puts "--- set_disable_timing port ---"
|
||||
catch {
|
||||
set_disable_timing [get_ports in1]
|
||||
report_checks -path_delay max
|
||||
unset_disable_timing [get_ports in1]
|
||||
}
|
||||
set_disable_timing [get_ports in1]
|
||||
report_checks -path_delay max
|
||||
unset_disable_timing [get_ports in1]
|
||||
|
||||
puts "--- set_disable_timing instance ---"
|
||||
set_disable_timing [get_cells buf1]
|
||||
|
|
@ -270,14 +266,12 @@ unset_timing_derate
|
|||
# Tag/group reporting (for Tag.cc coverage)
|
||||
############################################################
|
||||
puts "--- tag/group reporting ---"
|
||||
catch {
|
||||
puts "tag_count: [sta::tag_count]"
|
||||
puts "tag_group_count: [sta::tag_group_count]"
|
||||
puts "clk_info_count: [sta::clk_info_count]"
|
||||
puts "path_count: [sta::path_count]"
|
||||
}
|
||||
puts "tag_count: [sta::tag_count]"
|
||||
puts "tag_group_count: [sta::tag_group_count]"
|
||||
puts "clk_info_count: [sta::clk_info_count]"
|
||||
puts "path_count: [sta::path_count]"
|
||||
|
||||
puts "--- report internal ---"
|
||||
catch { sta::report_tags }
|
||||
catch { sta::report_clk_infos }
|
||||
catch { sta::report_tag_groups }
|
||||
sta::report_tags
|
||||
sta::report_clk_infos
|
||||
sta::report_tag_groups
|
||||
|
|
|
|||
|
|
@ -157,9 +157,7 @@ report_clock_skew -hold
|
|||
############################################################
|
||||
puts "--- clock min period ---"
|
||||
report_clock_min_period
|
||||
catch {
|
||||
report_clock_min_period -include_port_paths
|
||||
}
|
||||
report_clock_min_period -include_port_paths
|
||||
|
||||
############################################################
|
||||
# Clock latency reporting
|
||||
|
|
@ -167,9 +165,7 @@ catch {
|
|||
puts "--- clock latency report ---"
|
||||
set_propagated_clock [get_clocks clk]
|
||||
report_clock_latency
|
||||
catch {
|
||||
report_clock_latency -include_internal_latency
|
||||
}
|
||||
report_clock_latency -include_internal_latency
|
||||
report_clock_latency -digits 6
|
||||
unset_propagated_clock [get_clocks clk]
|
||||
|
||||
|
|
@ -194,49 +190,37 @@ report_checks -through [get_pins clk_gate/ZN] -path_delay min
|
|||
# Various bidirectional/tristate enable flags
|
||||
############################################################
|
||||
puts "--- bidirect inst paths ---"
|
||||
catch {
|
||||
sta::set_bidirect_inst_paths_enabled 1
|
||||
report_checks -path_delay max
|
||||
sta::set_bidirect_inst_paths_enabled 0
|
||||
report_checks -path_delay max
|
||||
}
|
||||
sta::set_bidirect_inst_paths_enabled 1
|
||||
report_checks -path_delay max
|
||||
sta::set_bidirect_inst_paths_enabled 0
|
||||
report_checks -path_delay max
|
||||
|
||||
puts "--- bidirect net paths ---"
|
||||
catch {
|
||||
sta::set_bidirect_net_paths_enabled 1
|
||||
report_checks -path_delay max
|
||||
sta::set_bidirect_net_paths_enabled 0
|
||||
report_checks -path_delay max
|
||||
}
|
||||
sta::set_bidirect_net_paths_enabled 1
|
||||
report_checks -path_delay max
|
||||
sta::set_bidirect_net_paths_enabled 0
|
||||
report_checks -path_delay max
|
||||
|
||||
puts "--- clk thru tristate ---"
|
||||
catch {
|
||||
sta::set_clk_thru_tristate_enabled 1
|
||||
report_checks -path_delay max
|
||||
sta::set_clk_thru_tristate_enabled 0
|
||||
report_checks -path_delay max
|
||||
}
|
||||
sta::set_clk_thru_tristate_enabled 1
|
||||
report_checks -path_delay max
|
||||
sta::set_clk_thru_tristate_enabled 0
|
||||
report_checks -path_delay max
|
||||
|
||||
puts "--- dynamic loop breaking ---"
|
||||
catch {
|
||||
sta::set_dynamic_loop_breaking 1
|
||||
report_checks -path_delay max
|
||||
sta::set_dynamic_loop_breaking 0
|
||||
report_checks -path_delay max
|
||||
}
|
||||
sta::set_dynamic_loop_breaking 1
|
||||
report_checks -path_delay max
|
||||
sta::set_dynamic_loop_breaking 0
|
||||
report_checks -path_delay max
|
||||
|
||||
puts "--- use default arrival clock ---"
|
||||
catch {
|
||||
sta::set_use_default_arrival_clock 1
|
||||
report_checks -path_delay max
|
||||
sta::set_use_default_arrival_clock 0
|
||||
report_checks -path_delay max
|
||||
}
|
||||
sta::set_use_default_arrival_clock 1
|
||||
report_checks -path_delay max
|
||||
sta::set_use_default_arrival_clock 0
|
||||
report_checks -path_delay max
|
||||
|
||||
puts "--- propagate all clocks ---"
|
||||
catch {
|
||||
sta::set_propagate_all_clocks 1
|
||||
report_checks -path_delay max
|
||||
sta::set_propagate_all_clocks 0
|
||||
report_checks -path_delay max
|
||||
}
|
||||
sta::set_propagate_all_clocks 1
|
||||
report_checks -path_delay max
|
||||
sta::set_propagate_all_clocks 0
|
||||
report_checks -path_delay max
|
||||
|
|
|
|||
|
|
@ -29,10 +29,8 @@ foreach pe $paths2 {
|
|||
sta::set_report_path_format full
|
||||
|
||||
puts "--- worstSlack single-arg form ---"
|
||||
catch {
|
||||
set ws [sta::worst_slack_cmd max]
|
||||
puts "worst_slack: $ws"
|
||||
}
|
||||
set ws [sta::worst_slack_cmd max]
|
||||
puts "worst_slack: $ws"
|
||||
|
||||
puts "--- checkFanout via report_check_types ---"
|
||||
set_max_fanout 2 [current_design]
|
||||
|
|
@ -52,30 +50,28 @@ report_checks -slack_min -10 -path_delay max
|
|||
report_checks -slack_max 100 -slack_min -100 -path_delay max
|
||||
|
||||
puts "--- set_report_path_field_properties ---"
|
||||
catch { sta::set_report_path_field_properties "delay" "Delay" 10 0 }
|
||||
catch { sta::set_report_path_field_width "delay" 12 }
|
||||
sta::set_report_path_field_properties "delay" "Delay" 10 0
|
||||
sta::set_report_path_field_width "delay" 12
|
||||
report_checks -path_delay max
|
||||
|
||||
puts "--- set_report_path_sigmas ---"
|
||||
catch { sta::set_report_path_sigmas 1 }
|
||||
sta::set_report_path_sigmas 1
|
||||
report_checks -path_delay max
|
||||
catch { sta::set_report_path_sigmas 0 }
|
||||
sta::set_report_path_sigmas 0
|
||||
|
||||
puts "--- find_timing_paths with recovery/removal/gating_setup/gating_hold ---"
|
||||
catch {
|
||||
sta::set_recovery_removal_checks_enabled 1
|
||||
sta::set_gated_clk_checks_enabled 1
|
||||
set paths_all [find_timing_paths -path_delay max -endpoint_path_count 5 -group_path_count 5]
|
||||
puts "Paths: [llength $paths_all]"
|
||||
sta::set_recovery_removal_checks_enabled 0
|
||||
sta::set_gated_clk_checks_enabled 0
|
||||
}
|
||||
sta::set_recovery_removal_checks_enabled 1
|
||||
sta::set_gated_clk_checks_enabled 1
|
||||
set paths_all [find_timing_paths -path_delay max -endpoint_path_count 5 -group_path_count 5]
|
||||
puts "Paths: [llength $paths_all]"
|
||||
sta::set_recovery_removal_checks_enabled 0
|
||||
sta::set_gated_clk_checks_enabled 0
|
||||
|
||||
puts "--- report_annotated_delay ---"
|
||||
catch { report_annotated_delay }
|
||||
report_annotated_delay
|
||||
|
||||
puts "--- report_annotated_check ---"
|
||||
catch { report_annotated_check }
|
||||
report_annotated_check
|
||||
|
||||
puts "--- report_checks with -path_delay max_rise/max_fall/min_rise/min_fall ---"
|
||||
report_checks -path_delay max_rise -format end
|
||||
|
|
@ -139,19 +135,15 @@ foreach pe $paths_v {
|
|||
}
|
||||
|
||||
puts "--- vertex_worst_arrival_path ---"
|
||||
catch {
|
||||
set warr [sta::vertex_worst_arrival_path $wv max]
|
||||
if { $warr != "NULL" } {
|
||||
puts "worst_arrival_path pin: [get_full_name [$warr pin]]"
|
||||
}
|
||||
set warr [sta::vertex_worst_arrival_path $wv max]
|
||||
if { $warr != "NULL" } {
|
||||
puts "worst_arrival_path pin: [get_full_name [$warr pin]]"
|
||||
}
|
||||
|
||||
puts "--- vertex_worst_slack_path ---"
|
||||
catch {
|
||||
set wslk [sta::vertex_worst_slack_path $wv max]
|
||||
if { $wslk != "NULL" } {
|
||||
puts "worst_slack_path pin: [get_full_name [$wslk pin]]"
|
||||
}
|
||||
set wslk [sta::vertex_worst_slack_path $wv max]
|
||||
if { $wslk != "NULL" } {
|
||||
puts "worst_slack_path pin: [get_full_name [$wslk pin]]"
|
||||
}
|
||||
|
||||
puts "--- report_path_end with prev_end ---"
|
||||
|
|
@ -165,17 +157,15 @@ foreach pe $paths3 {
|
|||
}
|
||||
|
||||
puts "--- make_instance ---"
|
||||
catch {
|
||||
set and_cell2 [get_lib_cells NangateOpenCellLibrary/AND2_X1]
|
||||
sta::make_instance new_inst $and_cell2
|
||||
puts "make_instance: done"
|
||||
}
|
||||
set and_cell2 [get_lib_cells NangateOpenCellLibrary/AND2_X1]
|
||||
sta::make_instance new_inst $and_cell2
|
||||
puts "make_instance: done"
|
||||
|
||||
puts "--- pocv_enabled ---"
|
||||
catch { puts "pocv_enabled: [sta::pocv_enabled]" }
|
||||
puts "pocv_enabled: [sta::pocv_enabled]"
|
||||
|
||||
puts "--- report_checks -summary format ---"
|
||||
report_checks -path_delay max -format summary
|
||||
|
||||
puts "--- clear_sta ---"
|
||||
catch { sta::clear_sta }
|
||||
sta::clear_sta
|
||||
|
|
|
|||
|
|
@ -73,23 +73,19 @@ if { $wv_min != "NULL" } {
|
|||
|
||||
puts "--- vertex_worst_arrival_path ---"
|
||||
if { $wv_max != "NULL" } {
|
||||
catch {
|
||||
set warr [sta::vertex_worst_arrival_path $wv_max max]
|
||||
if { $warr != "NULL" } {
|
||||
puts "worst_arrival_path pin: [get_full_name [$warr pin]]"
|
||||
puts "worst_arrival_path arrival: [$warr arrival]"
|
||||
}
|
||||
set warr [sta::vertex_worst_arrival_path $wv_max max]
|
||||
if { $warr != "NULL" } {
|
||||
puts "worst_arrival_path pin: [get_full_name [$warr pin]]"
|
||||
puts "worst_arrival_path arrival: [$warr arrival]"
|
||||
}
|
||||
}
|
||||
|
||||
puts "--- vertex_worst_slack_path ---"
|
||||
if { $wv_max != "NULL" } {
|
||||
catch {
|
||||
set wslk [sta::vertex_worst_slack_path $wv_max max]
|
||||
if { $wslk != "NULL" } {
|
||||
puts "worst_slack_path pin: [get_full_name [$wslk pin]]"
|
||||
puts "worst_slack_path slack: [$wslk slack]"
|
||||
}
|
||||
set wslk [sta::vertex_worst_slack_path $wv_max max]
|
||||
if { $wslk != "NULL" } {
|
||||
puts "worst_slack_path pin: [get_full_name [$wslk pin]]"
|
||||
puts "worst_slack_path slack: [$wslk slack]"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -147,15 +143,15 @@ catch {
|
|||
}
|
||||
|
||||
puts "--- set_report_path_field_properties ---"
|
||||
catch { sta::set_report_path_field_properties "delay" "Dly" 10 0 }
|
||||
sta::set_report_path_field_properties "delay" "Dly" 10 0
|
||||
report_checks -path_delay max > /dev/null
|
||||
catch { sta::set_report_path_field_width "delay" 12 }
|
||||
sta::set_report_path_field_width "delay" 12
|
||||
report_checks -path_delay max > /dev/null
|
||||
|
||||
puts "--- set_report_path_sigmas ---"
|
||||
catch { sta::set_report_path_sigmas 1 }
|
||||
sta::set_report_path_sigmas 1
|
||||
report_checks -path_delay max > /dev/null
|
||||
catch { sta::set_report_path_sigmas 0 }
|
||||
sta::set_report_path_sigmas 0
|
||||
|
||||
puts "--- set_report_path_no_split ---"
|
||||
sta::set_report_path_no_split 1
|
||||
|
|
@ -169,10 +165,10 @@ catch {
|
|||
}
|
||||
|
||||
puts "--- pocv ---"
|
||||
catch { puts "pocv_enabled: [sta::pocv_enabled]" }
|
||||
puts "pocv_enabled: [sta::pocv_enabled]"
|
||||
|
||||
puts "--- report_annotated_delay ---"
|
||||
catch { report_annotated_delay }
|
||||
report_annotated_delay
|
||||
|
||||
puts "--- report_annotated_check ---"
|
||||
catch { report_annotated_check }
|
||||
report_annotated_check
|
||||
|
|
|
|||
|
|
@ -44,16 +44,12 @@ set model_file3 [make_result_file "search_test1_model3.lib"]
|
|||
write_timing_model -library_name my_custom_lib -cell_name my_custom_cell2 $model_file3
|
||||
|
||||
puts "--- Network edit: make_instance ---"
|
||||
catch {
|
||||
make_instance new_buf1 [get_lib_cells NangateOpenCellLibrary/BUF_X1]
|
||||
puts "make_instance new_buf1 done"
|
||||
}
|
||||
make_instance new_buf1 [get_lib_cells NangateOpenCellLibrary/BUF_X1]
|
||||
puts "make_instance new_buf1 done"
|
||||
|
||||
puts "--- Network edit: make_net ---"
|
||||
catch {
|
||||
make_net new_net1
|
||||
puts "make_net new_net1 done"
|
||||
}
|
||||
make_net new_net1
|
||||
puts "make_net new_net1 done"
|
||||
|
||||
puts "--- Network edit: connect_pin ---"
|
||||
catch {
|
||||
|
|
@ -68,23 +64,17 @@ catch {
|
|||
}
|
||||
|
||||
puts "--- Network edit: delete_net ---"
|
||||
catch {
|
||||
delete_net [get_nets new_net1]
|
||||
puts "delete_net done"
|
||||
}
|
||||
delete_net [get_nets new_net1]
|
||||
puts "delete_net done"
|
||||
|
||||
puts "--- Network edit: delete_instance ---"
|
||||
catch {
|
||||
delete_instance [get_cells new_buf1]
|
||||
puts "delete_instance done"
|
||||
}
|
||||
delete_instance [get_cells new_buf1]
|
||||
puts "delete_instance done"
|
||||
|
||||
puts "--- Network edit: replace_cell ---"
|
||||
catch {
|
||||
replace_cell [get_cells buf1] [get_lib_cells NangateOpenCellLibrary/BUF_X2]
|
||||
report_checks -path_delay max
|
||||
puts "replace_cell done"
|
||||
}
|
||||
replace_cell [get_cells buf1] [get_lib_cells NangateOpenCellLibrary/BUF_X2]
|
||||
report_checks -path_delay max
|
||||
puts "replace_cell done"
|
||||
|
||||
puts "--- report_checks after edits ---"
|
||||
report_checks -path_delay max
|
||||
|
|
|
|||
|
|
@ -3,8 +3,22 @@
|
|||
#include <cstdio>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <tcl.h>
|
||||
#include "MinMax.hh"
|
||||
#include "Transition.hh"
|
||||
#include "Sta.hh"
|
||||
#include "Network.hh"
|
||||
#include "ReportTcl.hh"
|
||||
#include "Corner.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "Graph.hh"
|
||||
#include "PathEnd.hh"
|
||||
#include "PathExpanded.hh"
|
||||
#include "PathAnalysisPt.hh"
|
||||
#include "DcalcAnalysisPt.hh"
|
||||
#include "Search.hh"
|
||||
#include "CircuitSim.hh"
|
||||
#include "spice/Xyce.hh"
|
||||
#include "spice/WriteSpice.hh"
|
||||
|
||||
|
|
@ -1367,4 +1381,477 @@ TEST_F(XyceCsvTest, ReadCsv50Signals) {
|
|||
EXPECT_EQ(waveforms.size(), 50u);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// SpiceDesignTest: tests that load a design and exercise
|
||||
// higher-level SPICE writing functionality
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
class SpiceDesignTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
interp_ = Tcl_CreateInterp();
|
||||
initSta();
|
||||
sta_ = new Sta;
|
||||
Sta::setSta(sta_);
|
||||
sta_->makeComponents();
|
||||
ReportTcl *report = dynamic_cast<ReportTcl*>(sta_->report());
|
||||
if (report)
|
||||
report->setTclInterp(interp_);
|
||||
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
const MinMaxAll *min_max = MinMaxAll::all();
|
||||
LibertyLibrary *lib = sta_->readLiberty(
|
||||
"test/nangate45/Nangate45_typ.lib", corner, min_max, false);
|
||||
ASSERT_NE(lib, nullptr);
|
||||
lib_ = lib;
|
||||
|
||||
bool ok = sta_->readVerilog("search/test/search_test1.v");
|
||||
ASSERT_TRUE(ok);
|
||||
ok = sta_->linkDesign("search_test1", true);
|
||||
ASSERT_TRUE(ok);
|
||||
|
||||
// Create clock and constraints
|
||||
Network *network = sta_->cmdNetwork();
|
||||
Instance *top = network->topInstance();
|
||||
Pin *clk_pin = network->findPin(top, "clk");
|
||||
ASSERT_NE(clk_pin, nullptr);
|
||||
PinSet *clk_pins = new PinSet(network);
|
||||
clk_pins->insert(clk_pin);
|
||||
FloatSeq *waveform = new FloatSeq;
|
||||
waveform->push_back(0.0f);
|
||||
waveform->push_back(5.0f);
|
||||
sta_->makeClock("clk", clk_pins, false, 10.0f, waveform, nullptr);
|
||||
|
||||
Pin *in1 = network->findPin(top, "in1");
|
||||
Pin *in2 = network->findPin(top, "in2");
|
||||
Pin *out1 = network->findPin(top, "out1");
|
||||
Clock *clk = sta_->sdc()->findClock("clk");
|
||||
sta_->setInputDelay(in1, RiseFallBoth::riseFall(), clk, RiseFall::rise(),
|
||||
nullptr, false, false, MinMaxAll::all(), false, 0.5f);
|
||||
sta_->setInputDelay(in2, RiseFallBoth::riseFall(), clk, RiseFall::rise(),
|
||||
nullptr, false, false, MinMaxAll::all(), false, 0.5f);
|
||||
sta_->setOutputDelay(out1, RiseFallBoth::riseFall(), clk, RiseFall::rise(),
|
||||
nullptr, false, false, MinMaxAll::all(), false, 0.5f);
|
||||
sta_->updateTiming(true);
|
||||
design_loaded_ = true;
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
deleteAllMemory();
|
||||
sta_ = nullptr;
|
||||
if (interp_)
|
||||
Tcl_DeleteInterp(interp_);
|
||||
interp_ = nullptr;
|
||||
}
|
||||
|
||||
// Helper: find a vertex for a pin by hierarchical path name
|
||||
Vertex *findVertex(const char *path_name) {
|
||||
Network *network = sta_->cmdNetwork();
|
||||
Pin *pin = network->findPin(path_name);
|
||||
if (pin == nullptr)
|
||||
return nullptr;
|
||||
Graph *graph = sta_->graph();
|
||||
if (graph == nullptr)
|
||||
return nullptr;
|
||||
return graph->pinDrvrVertex(pin);
|
||||
}
|
||||
|
||||
Pin *findPin(const char *path_name) {
|
||||
Network *network = sta_->cmdNetwork();
|
||||
return network->findPin(path_name);
|
||||
}
|
||||
|
||||
Sta *sta_;
|
||||
Tcl_Interp *interp_;
|
||||
LibertyLibrary *lib_;
|
||||
bool design_loaded_ = false;
|
||||
};
|
||||
|
||||
// Verify that the design loaded and basic network is accessible
|
||||
TEST_F(SpiceDesignTest, DesignLoaded) {
|
||||
ASSERT_TRUE(design_loaded_);
|
||||
Network *network = sta_->cmdNetwork();
|
||||
Instance *top = network->topInstance();
|
||||
ASSERT_NE(top, nullptr);
|
||||
}
|
||||
|
||||
// Verify all leaf instances are accessible for SPICE netlisting
|
||||
TEST_F(SpiceDesignTest, NetworkLeafInstances) {
|
||||
Network *network = sta_->cmdNetwork();
|
||||
InstanceSeq leaves = network->leafInstances();
|
||||
// search_test1.v has: and1 (AND2_X1), buf1 (BUF_X1), reg1 (DFF_X1),
|
||||
// buf2 (BUF_X1)
|
||||
EXPECT_EQ(leaves.size(), 4u);
|
||||
}
|
||||
|
||||
// Verify each instance can be found by name for SPICE subcircuit generation
|
||||
TEST_F(SpiceDesignTest, NetworkInstancesByName) {
|
||||
Network *network = sta_->cmdNetwork();
|
||||
Instance *and1 = network->findInstance("and1");
|
||||
Instance *buf1 = network->findInstance("buf1");
|
||||
Instance *reg1 = network->findInstance("reg1");
|
||||
Instance *buf2 = network->findInstance("buf2");
|
||||
EXPECT_NE(and1, nullptr);
|
||||
EXPECT_NE(buf1, nullptr);
|
||||
EXPECT_NE(reg1, nullptr);
|
||||
EXPECT_NE(buf2, nullptr);
|
||||
}
|
||||
|
||||
// Verify liberty cell information is accessible for SPICE model generation
|
||||
TEST_F(SpiceDesignTest, LibertyCellAccess) {
|
||||
Network *network = sta_->cmdNetwork();
|
||||
Instance *and1 = network->findInstance("and1");
|
||||
ASSERT_NE(and1, nullptr);
|
||||
LibertyCell *cell = network->libertyCell(and1);
|
||||
ASSERT_NE(cell, nullptr);
|
||||
EXPECT_STREQ(cell->name(), "AND2_X1");
|
||||
}
|
||||
|
||||
// Verify liberty cell ports (needed for SPICE subcircuit port mapping)
|
||||
TEST_F(SpiceDesignTest, LibertyCellPortInfo) {
|
||||
LibertyCell *and2_cell = lib_->findLibertyCell("AND2_X1");
|
||||
ASSERT_NE(and2_cell, nullptr);
|
||||
|
||||
LibertyPort *a1 = and2_cell->findLibertyPort("A1");
|
||||
LibertyPort *a2 = and2_cell->findLibertyPort("A2");
|
||||
LibertyPort *zn = and2_cell->findLibertyPort("ZN");
|
||||
EXPECT_NE(a1, nullptr);
|
||||
EXPECT_NE(a2, nullptr);
|
||||
EXPECT_NE(zn, nullptr);
|
||||
}
|
||||
|
||||
// Verify buffer cell identification (used in SPICE path analysis)
|
||||
TEST_F(SpiceDesignTest, LibertyCellIsBuffer) {
|
||||
LibertyCell *buf_cell = lib_->findLibertyCell("BUF_X1");
|
||||
ASSERT_NE(buf_cell, nullptr);
|
||||
EXPECT_TRUE(buf_cell->isBuffer());
|
||||
|
||||
LibertyCell *and2_cell = lib_->findLibertyCell("AND2_X1");
|
||||
ASSERT_NE(and2_cell, nullptr);
|
||||
EXPECT_FALSE(and2_cell->isBuffer());
|
||||
}
|
||||
|
||||
// Verify inverter cell identification (used in SPICE logic value computation)
|
||||
TEST_F(SpiceDesignTest, LibertyCellIsInverter) {
|
||||
LibertyCell *inv_cell = lib_->findLibertyCell("INV_X1");
|
||||
ASSERT_NE(inv_cell, nullptr);
|
||||
EXPECT_TRUE(inv_cell->isInverter());
|
||||
|
||||
LibertyCell *buf_cell = lib_->findLibertyCell("BUF_X1");
|
||||
ASSERT_NE(buf_cell, nullptr);
|
||||
EXPECT_FALSE(buf_cell->isInverter());
|
||||
}
|
||||
|
||||
// Verify timing arcs exist for cells (needed for SPICE delay checking)
|
||||
TEST_F(SpiceDesignTest, LibertyCellTimingArcs) {
|
||||
LibertyCell *and2_cell = lib_->findLibertyCell("AND2_X1");
|
||||
ASSERT_NE(and2_cell, nullptr);
|
||||
EXPECT_GT(and2_cell->timingArcSets().size(), 0u);
|
||||
}
|
||||
|
||||
// Verify pin connectivity for SPICE net writing
|
||||
TEST_F(SpiceDesignTest, PinConnectivity) {
|
||||
Network *network = sta_->cmdNetwork();
|
||||
Instance *top = network->topInstance();
|
||||
|
||||
// The internal net n1 connects and1:ZN to buf1:A
|
||||
Pin *and1_zn = network->findPin("and1/ZN");
|
||||
Pin *buf1_a = network->findPin("buf1/A");
|
||||
ASSERT_NE(and1_zn, nullptr);
|
||||
ASSERT_NE(buf1_a, nullptr);
|
||||
|
||||
// Both pins should be on the same net
|
||||
Net *net_and1_zn = network->net(and1_zn);
|
||||
Net *net_buf1_a = network->net(buf1_a);
|
||||
ASSERT_NE(net_and1_zn, nullptr);
|
||||
ASSERT_NE(net_buf1_a, nullptr);
|
||||
EXPECT_EQ(net_and1_zn, net_buf1_a);
|
||||
}
|
||||
|
||||
// Verify driver/load pin classification (used in SPICE netlisting)
|
||||
TEST_F(SpiceDesignTest, PinDriverLoad) {
|
||||
Network *network = sta_->cmdNetwork();
|
||||
|
||||
Pin *and1_zn = network->findPin("and1/ZN");
|
||||
Pin *buf1_a = network->findPin("buf1/A");
|
||||
ASSERT_NE(and1_zn, nullptr);
|
||||
ASSERT_NE(buf1_a, nullptr);
|
||||
|
||||
// ZN is an output (driver), A is an input (load)
|
||||
EXPECT_TRUE(network->isDriver(and1_zn));
|
||||
EXPECT_TRUE(network->isLoad(buf1_a));
|
||||
}
|
||||
|
||||
// Verify graph vertex access (needed for SPICE path traversal)
|
||||
TEST_F(SpiceDesignTest, GraphVertexAccess) {
|
||||
Graph *graph = sta_->graph();
|
||||
ASSERT_NE(graph, nullptr);
|
||||
|
||||
Vertex *v = findVertex("buf1/Z");
|
||||
EXPECT_NE(v, nullptr);
|
||||
|
||||
Vertex *v2 = findVertex("and1/ZN");
|
||||
EXPECT_NE(v2, nullptr);
|
||||
}
|
||||
|
||||
// Verify timing paths exist after analysis (prerequisite for writePathSpice)
|
||||
TEST_F(SpiceDesignTest, TimingPathExists) {
|
||||
PathEndSeq path_ends = sta_->findPathEnds(
|
||||
nullptr, // from
|
||||
nullptr, // thrus
|
||||
nullptr, // to
|
||||
false, // unconstrained
|
||||
sta_->cmdCorner(),
|
||||
MinMaxAll::max(),
|
||||
10, // group_path_count
|
||||
1, // endpoint_path_count
|
||||
false, // unique_pins
|
||||
false, // unique_edges
|
||||
-INF, // slack_min
|
||||
INF, // slack_max
|
||||
false, // sort_by_slack
|
||||
nullptr, // group_names
|
||||
true, // setup
|
||||
false, // hold
|
||||
false, // recovery
|
||||
false, // removal
|
||||
false, // clk_gating_setup
|
||||
false // clk_gating_hold
|
||||
);
|
||||
// The design has constrained paths (in1/in2 -> reg1 -> out1)
|
||||
EXPECT_GT(path_ends.size(), 0u);
|
||||
}
|
||||
|
||||
// Verify path end has a valid path object for SPICE writing
|
||||
TEST_F(SpiceDesignTest, PathEndHasPath) {
|
||||
PathEndSeq path_ends = sta_->findPathEnds(
|
||||
nullptr, nullptr, nullptr, false,
|
||||
sta_->cmdCorner(), MinMaxAll::max(),
|
||||
10, 1, false, false, -INF, INF, false, nullptr,
|
||||
true, false, false, false, false, false
|
||||
);
|
||||
ASSERT_GT(path_ends.size(), 0u);
|
||||
PathEnd *path_end = path_ends[0];
|
||||
ASSERT_NE(path_end, nullptr);
|
||||
Path *path = path_end->path();
|
||||
ASSERT_NE(path, nullptr);
|
||||
}
|
||||
|
||||
// Verify worst slack computation (used to select paths for SPICE simulation)
|
||||
TEST_F(SpiceDesignTest, WorstSlackComputation) {
|
||||
Slack worst_slack;
|
||||
Vertex *worst_vertex;
|
||||
sta_->worstSlack(MinMax::max(), worst_slack, worst_vertex);
|
||||
// The design should have a finite slack (not INF/-INF)
|
||||
EXPECT_NE(worst_vertex, nullptr);
|
||||
}
|
||||
|
||||
// Verify DcalcAnalysisPt access (needed for WriteSpice constructor)
|
||||
TEST_F(SpiceDesignTest, DcalcAnalysisPtAccess) {
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
ASSERT_NE(corner, nullptr);
|
||||
const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(MinMax::max());
|
||||
ASSERT_NE(dcalc_ap, nullptr);
|
||||
}
|
||||
|
||||
// Verify SPICE file can be written for a timing path
|
||||
TEST_F(SpiceDesignTest, WriteSpicePathFile) {
|
||||
PathEndSeq path_ends = sta_->findPathEnds(
|
||||
nullptr, nullptr, nullptr, false,
|
||||
sta_->cmdCorner(), MinMaxAll::max(),
|
||||
10, 1, false, false, -INF, INF, false, nullptr,
|
||||
true, false, false, false, false, false
|
||||
);
|
||||
ASSERT_GT(path_ends.size(), 0u);
|
||||
Path *path = path_ends[0]->path();
|
||||
ASSERT_NE(path, nullptr);
|
||||
|
||||
// Create temp files for SPICE output
|
||||
char spice_tmpl[] = "/tmp/sta_spice_path_XXXXXX";
|
||||
int fd = mkstemp(spice_tmpl);
|
||||
ASSERT_NE(fd, -1);
|
||||
close(fd);
|
||||
|
||||
// writePathSpice requires subckt/model files to exist, but we can test
|
||||
// that the function does not crash with empty stubs
|
||||
char subckt_tmpl[] = "/tmp/sta_spice_subckt_XXXXXX";
|
||||
fd = mkstemp(subckt_tmpl);
|
||||
ASSERT_NE(fd, -1);
|
||||
close(fd);
|
||||
|
||||
// We cannot provide real model/subckt files for this unit test, so we
|
||||
// verify the path is valid and the API is callable. The actual file write
|
||||
// would fail without proper SPICE models, so we just verify the path
|
||||
// and analysis point are properly formed.
|
||||
Corner *corner = sta_->cmdCorner();
|
||||
const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(MinMax::max());
|
||||
EXPECT_NE(dcalc_ap, nullptr);
|
||||
|
||||
// Clean up temp files
|
||||
std::remove(spice_tmpl);
|
||||
std::remove(subckt_tmpl);
|
||||
}
|
||||
|
||||
// Verify multiple timing paths are found (SPICE multi-path analysis)
|
||||
TEST_F(SpiceDesignTest, MultipleTimingPaths) {
|
||||
PathEndSeq path_ends = sta_->findPathEnds(
|
||||
nullptr, nullptr, nullptr, false,
|
||||
sta_->cmdCorner(), MinMaxAll::max(),
|
||||
10, 10, false, false, -INF, INF, false, nullptr,
|
||||
true, false, false, false, false, false
|
||||
);
|
||||
// The design has multiple paths through and1/buf1/reg1/buf2
|
||||
EXPECT_GE(path_ends.size(), 1u);
|
||||
}
|
||||
|
||||
// Verify liberty library cell lookup (used in writeSubckts)
|
||||
TEST_F(SpiceDesignTest, LibraryLookupForSpice) {
|
||||
// The library should contain the cells used in our design
|
||||
EXPECT_NE(lib_->findLibertyCell("AND2_X1"), nullptr);
|
||||
EXPECT_NE(lib_->findLibertyCell("BUF_X1"), nullptr);
|
||||
EXPECT_NE(lib_->findLibertyCell("DFF_X1"), nullptr);
|
||||
}
|
||||
|
||||
// Verify cell name is accessible from instance (for SPICE subcircuit naming)
|
||||
TEST_F(SpiceDesignTest, InstanceCellName) {
|
||||
Network *network = sta_->cmdNetwork();
|
||||
Instance *and1 = network->findInstance("and1");
|
||||
ASSERT_NE(and1, nullptr);
|
||||
const char *cell_name = network->cellName(and1);
|
||||
ASSERT_NE(cell_name, nullptr);
|
||||
EXPECT_STREQ(cell_name, "AND2_X1");
|
||||
|
||||
Instance *reg1 = network->findInstance("reg1");
|
||||
ASSERT_NE(reg1, nullptr);
|
||||
cell_name = network->cellName(reg1);
|
||||
ASSERT_NE(cell_name, nullptr);
|
||||
EXPECT_STREQ(cell_name, "DFF_X1");
|
||||
}
|
||||
|
||||
// Verify streamPrint with SPICE subcircuit instance format for design cells
|
||||
TEST_F(SpiceDesignTest, StreamPrintSubcktInst) {
|
||||
char tmpl[] = "/tmp/sta_spice_subckt_inst_XXXXXX";
|
||||
int fd = mkstemp(tmpl);
|
||||
ASSERT_NE(fd, -1);
|
||||
close(fd);
|
||||
|
||||
Network *network = sta_->cmdNetwork();
|
||||
Instance *and1 = network->findInstance("and1");
|
||||
ASSERT_NE(and1, nullptr);
|
||||
const char *inst_name = network->name(and1);
|
||||
const char *cell_name = network->cellName(and1);
|
||||
|
||||
std::ofstream out(tmpl);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "x%s VDD VSS %s\n", inst_name, cell_name);
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpl);
|
||||
std::string line;
|
||||
std::getline(in, line);
|
||||
EXPECT_NE(line.find("xand1"), std::string::npos);
|
||||
EXPECT_NE(line.find("AND2_X1"), std::string::npos);
|
||||
std::remove(tmpl);
|
||||
}
|
||||
|
||||
// Verify net names for SPICE node naming
|
||||
TEST_F(SpiceDesignTest, NetNamesForSpice) {
|
||||
Network *network = sta_->cmdNetwork();
|
||||
Pin *and1_zn = network->findPin("and1/ZN");
|
||||
ASSERT_NE(and1_zn, nullptr);
|
||||
Net *net = network->net(and1_zn);
|
||||
ASSERT_NE(net, nullptr);
|
||||
const char *net_name = network->name(net);
|
||||
EXPECT_NE(net_name, nullptr);
|
||||
// The net name should be "n1" (from the Verilog: wire n1)
|
||||
EXPECT_STREQ(net_name, "n1");
|
||||
}
|
||||
|
||||
// Verify hold timing paths (for SPICE min-delay analysis)
|
||||
TEST_F(SpiceDesignTest, HoldTimingPaths) {
|
||||
PathEndSeq path_ends = sta_->findPathEnds(
|
||||
nullptr, nullptr, nullptr, false,
|
||||
sta_->cmdCorner(), MinMaxAll::min(),
|
||||
10, 1, false, false, -INF, INF, false, nullptr,
|
||||
false, true, false, false, false, false
|
||||
);
|
||||
// Hold paths should exist for the constrained design
|
||||
EXPECT_GE(path_ends.size(), 0u);
|
||||
}
|
||||
|
||||
// Verify clock can be found for SPICE waveform generation
|
||||
TEST_F(SpiceDesignTest, ClockAccessForSpice) {
|
||||
Clock *clk = sta_->sdc()->findClock("clk");
|
||||
ASSERT_NE(clk, nullptr);
|
||||
EXPECT_FLOAT_EQ(clk->period(), 10.0f);
|
||||
}
|
||||
|
||||
// Verify vertex arrival times are computed (used in SPICE timing correlation)
|
||||
TEST_F(SpiceDesignTest, VertexArrivalForSpice) {
|
||||
Vertex *v = findVertex("buf1/Z");
|
||||
ASSERT_NE(v, nullptr);
|
||||
Arrival arr = sta_->vertexArrival(v, MinMax::max());
|
||||
// Arrival should be finite (not INF)
|
||||
(void)arr;
|
||||
}
|
||||
|
||||
// Verify PathExpanded works on timing paths (used in SPICE path writing)
|
||||
TEST_F(SpiceDesignTest, PathExpandedAccess) {
|
||||
PathEndSeq path_ends = sta_->findPathEnds(
|
||||
nullptr, nullptr, nullptr, false,
|
||||
sta_->cmdCorner(), MinMaxAll::max(),
|
||||
10, 1, false, false, -INF, INF, false, nullptr,
|
||||
true, false, false, false, false, false
|
||||
);
|
||||
ASSERT_GT(path_ends.size(), 0u);
|
||||
Path *path = path_ends[0]->path();
|
||||
ASSERT_NE(path, nullptr);
|
||||
|
||||
PathExpanded expanded(path, sta_);
|
||||
// The expanded path should have multiple elements
|
||||
EXPECT_GT(expanded.size(), 0u);
|
||||
}
|
||||
|
||||
// Verify all top-level ports are accessible (for SPICE port mapping)
|
||||
TEST_F(SpiceDesignTest, TopLevelPorts) {
|
||||
Network *network = sta_->cmdNetwork();
|
||||
Instance *top = network->topInstance();
|
||||
ASSERT_NE(top, nullptr);
|
||||
|
||||
// search_test1.v: input clk, in1, in2; output out1
|
||||
Pin *clk = network->findPin(top, "clk");
|
||||
Pin *in1 = network->findPin(top, "in1");
|
||||
Pin *in2 = network->findPin(top, "in2");
|
||||
Pin *out1 = network->findPin(top, "out1");
|
||||
EXPECT_NE(clk, nullptr);
|
||||
EXPECT_NE(in1, nullptr);
|
||||
EXPECT_NE(in2, nullptr);
|
||||
EXPECT_NE(out1, nullptr);
|
||||
}
|
||||
|
||||
// Verify register cell identification (used in SPICE sequential port values)
|
||||
TEST_F(SpiceDesignTest, RegisterCellForSpice) {
|
||||
LibertyCell *dff_cell = lib_->findLibertyCell("DFF_X1");
|
||||
ASSERT_NE(dff_cell, nullptr);
|
||||
|
||||
// DFF should have timing arcs for setup/hold checks
|
||||
EXPECT_GT(dff_cell->timingArcSets().size(), 0u);
|
||||
|
||||
// Verify DFF ports needed for SPICE
|
||||
EXPECT_NE(dff_cell->findLibertyPort("D"), nullptr);
|
||||
EXPECT_NE(dff_cell->findLibertyPort("CK"), nullptr);
|
||||
EXPECT_NE(dff_cell->findLibertyPort("Q"), nullptr);
|
||||
}
|
||||
|
||||
// Verify CircuitSim enum values used in WriteSpice
|
||||
TEST_F(SpiceDesignTest, CircuitSimEnum) {
|
||||
// These enum values are used by writePathSpice
|
||||
CircuitSim hspice = CircuitSim::hspice;
|
||||
CircuitSim ngspice = CircuitSim::ngspice;
|
||||
CircuitSim xyce = CircuitSim::xyce;
|
||||
EXPECT_NE(static_cast<int>(hspice), static_cast<int>(ngspice));
|
||||
EXPECT_NE(static_cast<int>(ngspice), static_cast<int>(xyce));
|
||||
EXPECT_NE(static_cast<int>(hspice), static_cast<int>(xyce));
|
||||
}
|
||||
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ if { $sz7 >= $sz6 } {
|
|||
#---------------------------------------------------------------
|
||||
puts "--- Test 5: -sort option ---"
|
||||
set out8 [make_result_file verilog_gcd_sort.v]
|
||||
catch {write_verilog -sort $out8} msg_sort
|
||||
set msg_sort [write_verilog -sort $out8]
|
||||
puts "write_verilog -sort: $msg_sort"
|
||||
if { [file exists $out8] } {
|
||||
set sz8 [file size $out8]
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ puts "basic size: $sz1, remove_cells size: $sz3"
|
|||
|
||||
puts "--- write_verilog -sort (deprecated, should warn) ---"
|
||||
set out4 [make_result_file verilog_write_options_out4.v]
|
||||
catch {write_verilog -sort $out4} msg_sort
|
||||
set msg_sort [write_verilog -sort $out4]
|
||||
puts "write_verilog -sort: $msg_sort"
|
||||
puts "--- read_verilog / write_verilog roundtrip ---"
|
||||
# Read back the written verilog to exercise reader code paths
|
||||
|
|
|
|||
Loading…
Reference in New Issue