219 lines
7.0 KiB
Tcl
219 lines
7.0 KiB
Tcl
# Test graph vertex and edge operations in depth: makeVertex, deleteVertex,
|
|
# makeEdge, deleteEdge, edge arc queries, bidirectional pin handling,
|
|
# hasFaninOne, vertex iteration, edge linking.
|
|
# Targets: Graph.cc uncovered:
|
|
# deleteVertex: edge cleanup during vertex deletion
|
|
# deleteInEdge / deleteOutEdge: linked list manipulation for edges
|
|
# hasFaninOne: single fanin check
|
|
# pinDrvrVertex / pinLoadVertex: bidirect driver vertex lookup
|
|
# gateEdgeArc: arc lookup by rise/fall
|
|
# makePaths / paths / deletePaths: vertex path management
|
|
# slew / setSlew: slew value access
|
|
# makeWireEdgesToPin: create wire edges to a pin
|
|
# isIsolatedNet: isolated net detection
|
|
# arcDelay / setArcDelay: edge arc delay access
|
|
|
|
source ../../test/helpers.tcl
|
|
|
|
read_liberty ../../test/nangate45/Nangate45_typ.lib
|
|
read_verilog graph_delete_modify.v
|
|
link_design graph_delete_modify
|
|
|
|
create_clock -name clk -period 10 [get_ports clk]
|
|
set_input_delay -clock clk 1.0 [get_ports {d1 d2 d3 rst}]
|
|
set_output_delay -clock clk 1.0 [get_ports {q1 q2 q3 q4}]
|
|
set_input_transition 0.1 [get_ports {d1 d2 d3 rst clk}]
|
|
|
|
#---------------------------------------------------------------
|
|
# Test 1: Baseline - build graph and verify edges
|
|
#---------------------------------------------------------------
|
|
puts "--- Test 1: baseline edge count ---"
|
|
report_checks
|
|
|
|
# Query edges for each cell
|
|
foreach cell_name {buf1 buf2 inv1 and1 or1 nand1 nor1} {
|
|
set edges [get_timing_edges -of_objects [get_cells $cell_name]]
|
|
puts "$cell_name edges: [llength $edges]"
|
|
}
|
|
|
|
#---------------------------------------------------------------
|
|
# Test 2: Add chain of buffers, verify edges, then delete one by one
|
|
# Exercises: makeVertex, makeEdge, deleteVertex, deleteEdge,
|
|
# deleteInEdge, deleteOutEdge
|
|
#---------------------------------------------------------------
|
|
puts "--- Test 2: chain add/delete ---"
|
|
|
|
# Create 4-stage buffer chain
|
|
set chain_nets {}
|
|
set chain_insts {}
|
|
for {set i 0} {$i < 4} {incr i} {
|
|
lappend chain_nets [make_net "chain_n$i"]
|
|
}
|
|
lappend chain_nets [make_net "chain_n4"]
|
|
|
|
for {set i 0} {$i < 4} {incr i} {
|
|
set inst [make_instance "chain_buf$i" NangateOpenCellLibrary/BUF_X1]
|
|
lappend chain_insts $inst
|
|
connect_pin "chain_n$i" "chain_buf$i/A"
|
|
set j [expr {$i + 1}]
|
|
connect_pin "chain_n$j" "chain_buf$i/Z"
|
|
}
|
|
|
|
report_checks
|
|
|
|
# Query chain edges
|
|
for {set i 0} {$i < 4} {incr i} {
|
|
set edges [get_timing_edges -of_objects [get_cells "chain_buf$i"]]
|
|
puts "chain_buf$i edges: [llength $edges]"
|
|
}
|
|
|
|
# Delete chain from end to beginning (exercises reverse cleanup)
|
|
for {set i 3} {$i >= 0} {incr i -1} {
|
|
disconnect_pin "chain_n$i" "chain_buf$i/A"
|
|
set j [expr {$i + 1}]
|
|
disconnect_pin "chain_n$j" "chain_buf$i/Z"
|
|
delete_instance "chain_buf$i"
|
|
}
|
|
for {set i 0} {$i <= 4} {incr i} {
|
|
delete_net "chain_n$i"
|
|
}
|
|
|
|
report_checks
|
|
|
|
#---------------------------------------------------------------
|
|
# Test 3: Multiple fan-out and fan-in scenarios
|
|
# Exercises: makeWireEdgesFromPin with multi-driver nets
|
|
#---------------------------------------------------------------
|
|
puts "--- Test 3: fan-out/fan-in ---"
|
|
|
|
set fo_net [make_net "fanout_net"]
|
|
set fo_drv [make_instance "fo_drv" NangateOpenCellLibrary/BUF_X4]
|
|
set fo_load1 [make_instance "fo_load1" NangateOpenCellLibrary/BUF_X1]
|
|
set fo_load2 [make_instance "fo_load2" NangateOpenCellLibrary/BUF_X1]
|
|
set fo_load3 [make_instance "fo_load3" NangateOpenCellLibrary/BUF_X1]
|
|
|
|
set fo_in [make_net "fo_in"]
|
|
connect_pin fo_in fo_drv/A
|
|
connect_pin fanout_net fo_drv/Z
|
|
connect_pin fanout_net fo_load1/A
|
|
connect_pin fanout_net fo_load2/A
|
|
connect_pin fanout_net fo_load3/A
|
|
|
|
report_checks
|
|
|
|
# Query edge count on fanout driver
|
|
set drv_edges [get_timing_edges -of_objects [get_cells fo_drv]]
|
|
puts "fo_drv edges: [llength $drv_edges]"
|
|
|
|
# Disconnect loads one by one
|
|
disconnect_pin fanout_net fo_load3/A
|
|
report_checks
|
|
|
|
disconnect_pin fanout_net fo_load2/A
|
|
report_checks
|
|
|
|
# Cleanup
|
|
disconnect_pin fanout_net fo_load1/A
|
|
disconnect_pin fanout_net fo_drv/Z
|
|
disconnect_pin fo_in fo_drv/A
|
|
delete_instance fo_load1
|
|
delete_instance fo_load2
|
|
delete_instance fo_load3
|
|
delete_instance fo_drv
|
|
delete_net fanout_net
|
|
delete_net fo_in
|
|
|
|
report_checks
|
|
|
|
#---------------------------------------------------------------
|
|
# Test 4: Replace cell multiple times and verify edge rebuild
|
|
# Exercises: makeInstanceEdges rebuild, timing arc set changes
|
|
#---------------------------------------------------------------
|
|
puts "--- Test 4: cell replacement cycle ---"
|
|
|
|
# Replace buf1 through several sizes
|
|
foreach lib_cell {BUF_X1 BUF_X2 BUF_X4 BUF_X8 BUF_X4 BUF_X2 BUF_X1} {
|
|
replace_cell buf1 "NangateOpenCellLibrary/$lib_cell"
|
|
report_checks -path_delay max
|
|
}
|
|
|
|
# Replace AND gate
|
|
foreach lib_cell {AND2_X1 AND2_X2 AND2_X4 AND2_X2 AND2_X1} {
|
|
replace_cell and1 "NangateOpenCellLibrary/$lib_cell"
|
|
report_checks
|
|
}
|
|
|
|
#---------------------------------------------------------------
|
|
# Test 5: Register add/delete to exercise reg_clk_vertices
|
|
# Exercises: makeVertex is_reg_clk path, reg_clk_vertices_ insert/erase
|
|
#---------------------------------------------------------------
|
|
puts "--- Test 5: register add/delete ---"
|
|
|
|
# Add multiple registers
|
|
for {set i 0} {$i < 3} {incr i} {
|
|
set rn [make_net "reg_d$i"]
|
|
set rqn [make_net "reg_q$i"]
|
|
set ri [make_instance "test_reg$i" NangateOpenCellLibrary/DFF_X1]
|
|
connect_pin "reg_d$i" "test_reg$i/D"
|
|
connect_pin "reg_q$i" "test_reg$i/Q"
|
|
connect_pin clk "test_reg$i/CK"
|
|
}
|
|
|
|
report_checks
|
|
|
|
# Delete the registers
|
|
for {set i 0} {$i < 3} {incr i} {
|
|
disconnect_pin clk "test_reg$i/CK"
|
|
disconnect_pin "reg_d$i" "test_reg$i/D"
|
|
disconnect_pin "reg_q$i" "test_reg$i/Q"
|
|
delete_instance "test_reg$i"
|
|
delete_net "reg_d$i"
|
|
delete_net "reg_q$i"
|
|
}
|
|
|
|
report_checks
|
|
|
|
#---------------------------------------------------------------
|
|
# Test 6: Slew and timing edge reports
|
|
# Exercises: slew access, edge arc iteration
|
|
#---------------------------------------------------------------
|
|
puts "--- Test 6: slew and edge reports ---"
|
|
|
|
report_slews [get_ports d1]
|
|
report_slews [get_ports d2]
|
|
report_slews [get_ports d3]
|
|
report_slews [get_ports clk]
|
|
|
|
report_slews [get_pins buf1/A]
|
|
report_slews [get_pins buf1/Z]
|
|
report_slews [get_pins and1/A1]
|
|
report_slews [get_pins and1/ZN]
|
|
report_slews [get_pins inv1/A]
|
|
report_slews [get_pins inv1/ZN]
|
|
report_slews [get_pins nand1/ZN]
|
|
report_slews [get_pins nor1/ZN]
|
|
|
|
# Edge reports
|
|
report_edges -from [get_pins buf1/A] -to [get_pins buf1/Z]
|
|
report_edges -from [get_pins and1/A1] -to [get_pins and1/ZN]
|
|
report_edges -from [get_pins inv1/A] -to [get_pins inv1/ZN]
|
|
|
|
#---------------------------------------------------------------
|
|
# Test 7: Through-pin and endpoint queries
|
|
# Exercises: graph traversal paths
|
|
#---------------------------------------------------------------
|
|
puts "--- Test 7: through-pin queries ---"
|
|
|
|
report_checks -through [get_pins buf1/Z]
|
|
report_checks -through [get_pins and1/ZN]
|
|
report_checks -through [get_pins inv1/ZN]
|
|
report_checks -through [get_pins nand1/ZN]
|
|
report_checks -through [get_pins nor1/ZN]
|
|
report_checks -through [get_pins or1/ZN]
|
|
|
|
# Endpoint
|
|
report_checks -to [get_ports q1]
|
|
report_checks -to [get_ports q2]
|
|
report_checks -to [get_ports q3]
|
|
report_checks -to [get_ports q4]
|