Hi guys,
I am very new to tcl here. would like to request some help please
let say i have a design .it's a IC design .
I would like to know each usage of metal layer of that design and also measure its length and width?
how to code in such way?
essentially , what i want to do is find out total metal tracks being used in the design and measure length and width of each metal tracks . metal layer could be from Metal 1 to Metal 8 or 9 for example.
i have a script here below like a sample. i have looked at it , it should be more or less revolve around there , i think. would i get some help please to modify it to suit my main needs?
(btw, it is not coded by me , took it from some links on coding)
#Proc to calculate the route utilization of a vertical track
proc util_cal_v { llx lly urx ury metal_name } {
set nt_sp_len 0
set box1 [split [get_attribute [ get_die_area ] bbox] "{ }" ]
#set h_trk_len [lindex $box1 5]
set v_trk_len [lindex $box1 6]
set ab [sizeof_collection [get_net_shapes -quiet -intersect "$llx $lly $urx $ury" -filter "layer_name==$metal_name"]]
if { $ab != 0 } {
set nt_sp [get_net_shapes -quiet -intersect "$llx $lly $urx $ury" -filter "layer_name==$metal_name"]
set nt_sp_lst [collection_to_list -name_only -no_braces $nt_sp]
foreach nt $nt_sp_lst {
set h_v [string index $nt 0]
if {$h_v == "V"} {
set nt_sp_len [expr $nt_sp_len + [get_attribute [get_net_shapes $nt] length]]
} else {
set nt_sp_len [expr $nt_sp_len + [get_attribute [get_net_shapes $nt] width]]
}
}
set ut_v [expr $nt_sp_len / $v_trk_len]
} else {
set ut_v 0.00
}
return $ut_v
}
###############################################################3
#Proc to calculate the route utilization of a horizontal track
proc util_cal_h { llx lly urx ury metal_name } {
set nt_sp_len 0
set box1 [split [get_attribute [ get_die_area ] bbox] "{ }" ]
set h_trk_len [lindex $box1 5]
#set v_trk_len [lindex $box1 6]
set ab [sizeof_collection [get_net_shapes -quiet -intersect "$llx $lly $urx $ury" -filter "layer_name==$metal_name"]]
if { $ab != 0 } {
set nt_sp [get_net_shapes -quiet -intersect "$llx $lly $urx $ury" -filter "layer_name==$metal_name"]
set nt_sp_lst [collection_to_list -name_only -no_braces $nt_sp]
foreach nt $nt_sp_lst {
set h_v [string index $nt 0]
if {$h_v == "H"} {
set nt_sp_len [expr $nt_sp_len + [get_attribute [get_net_shapes $nt] length]]
} else {
set nt_sp_len [expr $nt_sp_len + [get_attribute [get_net_shapes $nt] width]]
}
}
set ut_h [expr $nt_sp_len / $h_trk_len]
} else {
set ut_h 0.00
}
return $ut_h
}
######################################################################################
#Proc to calculate the start location of each track
proc track_route_utilization_in_design { metal_name } {
echo "START TIME [date]"
set fp [ open "track_route_util.rpt" "w" ]
set pitch [get_attribute [get_layers $metal_name] pitch]
set box [split [get_attribute [ get_die_area ] bbox] "{ }" ]
set wdth [lindex $box 5]
set ht [lindex $box 6]
if {[get_attribute [get_layers $metal_name] preferred_direction] == "vertical"} {
set trk_v_off 0.0
set tck [get_tracks -filter "layer==$metal_name && direction==vertical"]
set trk_v_off1 [lindex [get_attribute -class track $tck start] 0]
foreach p $trk_v_off1 {
if {$p != 0} {
set trk_v_off $p
}
}
set ver_trk_ref 0
set cnt_v 0
set design_util_v 0
while { $ver_trk_ref < $wdth } {
if { $cnt_v == 0 } {
set ver_trk_ref [expr $ver_trk_ref + $trk_v_off]
incr cnt_v
#set ab [sizeof_collection [get_net_shapes -quiet -intersect "$ver_trk_ref 0 $ver_trk_ref $ht" -filter "layer_name==$metal_name"]]
set v_trk_util [ util_cal_v $ver_trk_ref 0 $ver_trk_ref $ht $metal_name ]
set design_util_v [ expr $design_util_v + $v_trk_util ]
puts $fp "The route utilization of the vertical track $cnt_v starting at ($ver_trk_ref , 0) is [ expr $v_trk_util * 100 ] percent."
} else {
set ver_trk_ref [expr $ver_trk_ref + $pitch]
incr cnt_v
set v_trk_util [ util_cal_v $ver_trk_ref 0 $ver_trk_ref $ht $metal_name ]
set design_util_v [ expr $design_util_v + $v_trk_util ]
puts $fp "The route utilization of vertical track $cnt_v starting at ($ver_trk_ref , 0) is [ expr $v_trk_util * 100 ] percent."
}
}
puts "Total number of vertical tracks is $cnt_v"
puts "Total route utilization of all vertical metal $metal_name tracks in the design is [ expr [ expr $design_util_v / $cnt_v ] * 100 ] percent"
puts "To see the route utilization of each vertical track of metal $metal_name in the design, open the file track_route_util.rpt "
} else {
set tck [get_tracks -filter "layer==$metal_name && direction==horizontal"]
set trk_h_off 0.0
set trk_h_off1 [lindex [get_attribute -class track $tck start] 1]
foreach p $trk_h_off1 {
if {$p != 0} {
set trk_h_off $p
}
}
set hor_trk_ref 0
set cnt_h 0
set design_util_h 0
while {$hor_trk_ref < $ht} {
if {$cnt_h == 0} {
set hor_trk_ref [expr $hor_trk_ref + $trk_h_off]
incr cnt_h
#set ab [sizeof_collection [get_net_shapes -quiet -intersect "$ver_trk_ref 0 $ver_trk_ref $ht" -filter "layer_name==$metal_name"]]
set h_trk_util [ util_cal_h 0 $hor_trk_ref $wdth $hor_trk_ref $metal_name ]
set design_util_h [ expr $design_util_h + $h_trk_util ]
puts $fp "The route utilization of horizontal track $cnt_h starting at (0 ,$hor_trk_ref) is [ expr $h_trk_util * 100 ] percent."
} else {
set hor_trk_ref [expr $hor_trk_ref + $pitch]
incr cnt_h
set h_trk_util [ util_cal_h 0 $hor_trk_ref $wdth $hor_trk_ref $metal_name ]
set design_util_h [ expr $design_util_h + $h_trk_util ]
puts $fp "The route utilization of horizontal track $cnt_h starting at (0 ,$hor_trk_ref) is [ expr $h_trk_util * 100 ] percent."
}
}
puts "Total number of horizontal tracks is $cnt_h"
puts "Total route utilization of all horizontal metal $metal_name tracks in the design is [ expr [ expr $design_util_h / $cnt_h ] * 100 ] percent"
puts "To see the route utilization of each horizontal track of metal $metal_name in the design, open the file track_route_util.rpt "
}
close $fp
echo "END TIME [date]"
}
define_proc_attributes track_route_utilization_in_design -info "Script to report the route utilization of each metal track."