############################################################################# # This script was written and developed by ABKGroup students at UCSD. # However, the underlying commands and reports are copyrighted by Cadence. # We thank Cadence for granting permission to share our research to help # promote and foster the next generation of innovators. # Author: Sayak Kundu (sakundu@ucsd.edu), ABKGroup, UCSD. # Thanks to Matheus Cavalcante, ETH Zürich and Jiantao Liu (jil313@ucsd.edu) # for providing the pin configuration. # # Usage: First source the script in Innovus shell. then use gen_pb_netlist # command to write out the netlist. The protobuf netlist will be available # as <design name>.pb.txt. ############################################################################# setPinAssignMode -pinEditInBatch true set group_width [dbget top.fplan.box_sizex] set group_height [dbget top.fplan.box_sizey] set NUM_GROUPS 4 set NUM_TILES 16 proc place_tcdm_top_bus {bus direction index width start end layers} { global NUM_TILES global group_height # Number of ports per tile set ports_per_tile [expr $width / $NUM_TILES] # Which ports are we placing? set ports [] # Shuffle the tiles to have the ports organized from left to right set tile_shuffle [list 0 1 8 9 2 3 10 11 4 5 12 13 6 7 14 15] if {$direction == "in"} { for {set tile 0} {$tile < $NUM_TILES} {incr tile} { set tile_sh [lindex $tile_shuffle $tile] for {set idx 0} {$idx < $ports_per_tile} {incr idx} { set act_idx [expr $index*$width + $ports_per_tile*$tile_sh + $ports_per_tile - 1 - $idx] set port_name [lindex [dbget top.terms.name ${bus}_i[$act_idx] -e] 0] if { $port_name != "" } { lappend ports $port_name } } foreach_in_collection port [get_ports ${bus}_valid_i[[expr $tile_sh + $index*$NUM_TILES]]] { lappend ports [get_object_name $port] } foreach_in_collection port [get_ports ${bus}_ready_o[[expr $tile_sh + $index*$NUM_TILES]]] { lappend ports [get_object_name $port] } } } else { for {set tile 0} {$tile < $NUM_TILES} {incr tile} { set tile_sh [lindex $tile_shuffle $tile] for {set idx 0} {$idx < $ports_per_tile} {incr idx} { set act_idx [expr $index*$width + $ports_per_tile*$tile_sh + $ports_per_tile - 1 - $idx] set port_name [lindex [dbget top.terms.name ${bus}_o[$act_idx] -e] 0] if { $port_name != "" } { lappend ports $port_name } } foreach_in_collection port [get_ports ${bus}_valid_o[[expr $tile_sh + $index*$NUM_TILES]]] { lappend ports [get_object_name $port] } foreach_in_collection port [get_ports ${bus}_ready_i[[expr $tile_sh + $index*$NUM_TILES]]] { lappend ports [get_object_name $port] } } } set num_ports [llength $ports] set offset [expr ($end - $start)/$num_ports] set y [dbget top.fplan.box_ury] set pt1 [list $start $y] set pt2 [list $end $y] editPin -pin $ports -edge 1 -start $pt1 -end $pt2 -fixedPin -layer $layers -spreadDirection clockwise -pattern fill_optimised } proc place_tcdm_left_bus {bus direction index width start end layers} { global NUM_TILES global group_height # Number of ports per tile set ports_per_tile [expr $width / $NUM_TILES] # Shuffle the tiles to have the ports organized from top to bottom set tile_shuffle [list 8 9 12 13 10 11 14 15 2 3 6 7 0 1 4 5] # Which ports are we placing? set ports [] if {$direction == "in"} { for {set tile 0} {$tile < $NUM_TILES} {incr tile} { set tile_sh [lindex $tile_shuffle $tile] for {set idx 0} {$idx < $ports_per_tile} {incr idx} { set act_idx [expr $index*$width + $ports_per_tile*$tile_sh + $ports_per_tile - 1 - $idx] set port_name [lindex [dbget top.terms.name ${bus}_i[$act_idx] -e] 0] if { $port_name != "" } { lappend ports $port_name } } foreach_in_collection port [get_ports ${bus}_valid_i[[expr $tile_sh + $index*$NUM_TILES]]] { lappend ports [get_object_name $port] } foreach_in_collection port [get_ports ${bus}_ready_o[[expr $tile_sh + $index*$NUM_TILES]]] { lappend ports [get_object_name $port] } } } else { for {set tile 0} {$tile < $NUM_TILES} {incr tile} { set tile_sh [lindex $tile_shuffle $tile] for {set idx 0} {$idx < $ports_per_tile} {incr idx} { set act_idx [expr $index*$width + $ports_per_tile*$tile_sh + $ports_per_tile - 1 - $idx] set port_name [lindex [dbget top.terms.name ${bus}_o[$act_idx] -e] 0] if { $port_name != "" } { lappend ports $port_name } } foreach_in_collection port [get_ports ${bus}_valid_o[[expr $tile_sh + $index*$NUM_TILES]]] { lappend ports [get_object_name $port] } foreach_in_collection port [get_ports ${bus}_ready_i[[expr $tile_sh + $index*$NUM_TILES]]] { lappend ports [get_object_name $port] } } } set num_ports [llength $ports] set offset [expr ($end - $start)/$num_ports] set x [dbget top.fplan.box_urx] set pt1 [list $x $start] set pt2 [list $x $end] editPin -pin $ports -edge 2 -start $pt1 -end $pt2 -fixedPin -layer $layers -spreadDirection counterclockwise -pattern fill_optimised } set master_req_bus_length [expr [llength [get_object_name [get_ports tcdm_master_req_o*]]] / ($NUM_GROUPS - 1)] set master_resp_bus_length [expr [llength [get_object_name [get_ports tcdm_master_resp_i*]]] / ($NUM_GROUPS - 1)] set slave_req_bus_length [expr [llength [get_object_name [get_ports tcdm_slave_req_i*]]] / ($NUM_GROUPS - 1)] set slave_resp_bus_length [expr [llength [get_object_name [get_ports tcdm_slave_resp_o*]]] / ($NUM_GROUPS - 1)] # North place_tcdm_top_bus tcdm_master_req out 1 $master_req_bus_length [expr 0.35*$group_width] [expr 0.51*$group_width] [list metal4 metal6] place_tcdm_top_bus tcdm_slave_req in 1 $slave_req_bus_length [expr 0.35*$group_width] [expr 0.51*$group_width] [list metal6 metal8] place_tcdm_top_bus tcdm_slave_resp out 1 $slave_resp_bus_length [expr 0.51*$group_width] [expr 0.67*$group_width] [list metal6 metal8] place_tcdm_top_bus tcdm_master_resp in 1 $master_resp_bus_length [expr 0.51*$group_width] [expr 0.67*$group_width] [list metal4 metal6] # Northeast place_tcdm_top_bus tcdm_slave_req in 2 $slave_req_bus_length [expr 0.67*$group_width] [expr 0.83*$group_width] [list metal4 metal6] place_tcdm_top_bus tcdm_master_resp in 2 $master_resp_bus_length [expr 0.67*$group_width] [expr 0.83*$group_width] [list metal6 metal8] # set ports [] # lappend ports [get_object_name [get_ports clk_i* ]] # lappend ports [get_object_name [get_ports rst_ni*]] # set ports [list $ports [get_object_name [get_ports scan*]]] # lappend ports [get_object_name [get_ports testmode*]] # puts "Ports are $ports" set ports {clk_i rst_ni scan_enable_i scan_data_i scan_data_o testmode_i dma_meta_o[0] dma_meta_o[1] group_id_i[0] group_id_i[1]} set y [dbget top.fplan.box_ury] set x1 [expr 0.45*$group_width] set x2 [expr 0.55*$group_width] set pt1 [list $x1 $y] set pt2 [list $x2 $y] editPin -pin $ports -edge 1 -start $pt1 -end $pt2 -fixedPin -layer [list metal4 metal6] -spreadDirection clockwise -pattern fill_optimised # Northeast place_tcdm_left_bus tcdm_master_req out 2 $master_req_bus_length [expr 0.17*$group_height] [expr 0.33*$group_height] [list metal3 metal5] place_tcdm_left_bus tcdm_slave_resp out 2 $slave_resp_bus_length [expr 0.17*$group_height] [expr 0.33*$group_height] [list metal5 metal7] # East place_tcdm_left_bus tcdm_master_req out 0 $master_req_bus_length [expr 0.33*$group_height] [expr 0.49*$group_height] [list metal3 metal5] place_tcdm_left_bus tcdm_slave_req in 0 $slave_req_bus_length [expr 0.33*$group_height] [expr 0.49*$group_height] [list metal5 metal7] place_tcdm_left_bus tcdm_master_resp in 0 $master_resp_bus_length [expr 0.49*$group_height] [expr 0.65*$group_height] [list metal3 metal5] place_tcdm_left_bus tcdm_slave_resp out 0 $slave_resp_bus_length [expr 0.49*$group_height] [expr 0.65*$group_height] [list metal5 metal7] set ports [dbget top.terms.name *dma_req*] set x [dbget top.fplan.box_urx] set y1 [expr 0.66*$group_height] set y2 [expr 0.80*$group_height] set pt1 [list $x $y1] set pt2 [list $x $y2] editPin -pin $ports -edge 2 -start $pt1 -end $pt2 -fixedPin -layer [list metal3 metal5] -spreadDirection counterclockwise -pattern fill_optimised set ports [dbget top.terms.name *wake_up*] set x [dbget top.fplan.box_llx] set y1 [expr 0.17*$group_height] set y2 [expr 0.32*$group_height] set pt1 [list $x $y1] set pt2 [list $x $y2] editPin -pin $ports -edge 0 -start $pt1 -end $pt2 -fixedPin -layer [list metal3 metal5] -spreadDirection clockwise -pattern fill_optimised set ports [dbget top.terms.name -regexp ".*axi.*|.*ro_cache.*"] set x [dbget top.fplan.box_llx] set y1 [expr 0.33*$group_height] set y2 [expr 0.67*$group_height] set pt1 [list $x $y1] set pt2 [list $x $y2] editPin -pin $ports -edge 0 -start $pt1 -end $pt2 -fixedPin -layer [list metal3 metal5] -spreadDirection clockwise -pattern fill_optimised setPinAssignMode -pinEditInBatch false