############################################################################# # 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 tile configuration. # # Usage: This script places macros for MemPool Group NG45 design. First source # the script in the Innovus terminal and then use the following command: # mempool_group_macro_placement ############################################################################# # Y Flip # RO --> MX MY --> R180 # It do not validate if there is enough space to create the macro stack # For the boundary macros of the cluster always have pin facing towards outside # Stack size indicates the number of macros will be stacked # Also it considers all the macro size in the macro list is same proc place_macro_mem_stack {macro_list stack_size ch_space origin_x origin_y\ isFlip} { if {$isFlip == 0} { set orient [list "R0" "MY"] set stack_dir 1 } else { set orient [list "MX" "R180"] set stack_dir -1 } # Extract macro informations set macro_width [dbget [dbget top.insts.name [lindex $macro_list 0] -p ].box_sizex] set macro_height [dbget [dbget top.insts.name [lindex $macro_list 0] -p ].box_sizey] # i indicates the row number and j indicates the column number set i 0 set j 0 set llx $origin_x set lly $origin_y foreach macro $macro_list { # For each column all the macros have same orientation set orientation [lindex $orient [expr $j%2]] placeInstance $macro $llx $lly $orientation -placed incr i if { $i == $stack_size } { set i 0 incr j set lly $origin_y set llx [expr $origin_x + ($j/2)*$ch_space + $j*$macro_width] } else { set lly [expr $origin_y + ${stack_dir}*($i*$macro_height)] } } } proc place_macro_mem_stack_in {macro_list stack_size ch_space origin_x origin_y\ isFlip} { if {$isFlip == 0} { set orient [list "R0" "MY"] set stack_dir 1 } else { set orient [list "MX" "R180"] set stack_dir -1 } # Extract macro informations set macro_width [dbget [dbget top.insts.name [lindex $macro_list 0] -p ].box_sizex] set macro_height [dbget [dbget top.insts.name [lindex $macro_list 0] -p ].box_sizey] # i indicates the row number and j indicates the column number set i 0 set j 1 set llx $origin_x set lly $origin_y foreach macro $macro_list { # For each column all the macros have same orientation set orientation [lindex $orient [expr $j%2]] placeInstance $macro $llx $lly $orientation -placed incr i if { $i == $stack_size } { set i 0 incr j set lly $origin_y set llx [expr $origin_x + ($j/2)*$ch_space + ($j-1)*$macro_width] } else { set lly [expr $origin_y + ${stack_dir}*($i*$macro_height)] } } } # Tile origin is always the lower left coordinate of the tile bbox proc place_tiles {tile_id tile_origin_x tile_origin_y tile_width tile_height \ isFlip {halo_wdith 5} {stack_size 2} } { # ICACHE set icache_rams [dbget [dbget top.insts.cell.subClass block -p2\ ].name gen_tiles[${tile_id}]*i_tile*i_lookup*i_data*] set icache_width [dbget [dbget top.insts.name [lindex $icache_rams 0] -p \ ].cell.size_x] set icache_height [dbget [dbget top.insts.name [lindex $icache_rams 0] -p \ ].cell.size_y] set ch_space [expr $halo_wdith*4] ## Place the ICACHE memories on the left boundary ## Stack two memories together set icache_llx [expr $tile_origin_x + $ch_space] if { $isFlip == 0 } { set icache_lly [expr $tile_origin_y + $ch_space] } else { set icache_lly [expr $tile_origin_y + $tile_height - $icache_height - $ch_space] } place_macro_mem_stack $icache_rams 2 $ch_space $icache_llx $icache_lly $isFlip # Place the TCDM memories on the right of the boundary # Stack 4 memories together # Ensure set tcdm_rams [dbget [dbget top.insts.cell.subClass block -p2 ].name \ gen_tiles*[${tile_id}]*i_tile*mem_bank*] set tcdm_width [dbget [dbget top.insts.name [lindex $tcdm_rams 0] -p \ ].cell.size_x] set tcdm_height [dbget [dbget top.insts.name [lindex $tcdm_rams 0] -p \ ].cell.size_y] if { $stack_size == 2 } { set tcdm_llx [expr $tile_origin_x + $tile_width - 4*$ch_space - 8*$tcdm_width] } elseif { $stack_size == 4 } { set tcdm_llx [expr $tile_origin_x + $tile_width - 2*$ch_space - 4*$tcdm_width] } if { $isFlip == 0 } { set tcdm_lly [expr $tile_origin_y + $ch_space] } else { set tcdm_lly [expr $tile_origin_y + $tile_height - $ch_space - $tcdm_height] } place_macro_mem_stack $tcdm_rams $stack_size $ch_space $tcdm_llx $tcdm_lly $isFlip } proc mempool_group_macro_placement { {halo_width 10} {stack_size 2} } { set core_llx [dbget top.fplan.coreBox_llx] set core_lly [dbget top.fplan.coreBox_lly] set core_width [dbget top.fplan.coreBox_sizex] set core_height [dbget top.fplan.coreBox_sizey] set tile_height [expr $core_height/4.0] set tile_width [expr $core_width/4.0] #set halo_width 10 # Scramble tiles set toffsets [list \ [list 0 1 4 5]\ [list 2 3 6 7]\ [list 8 9 12 13]\ [list 10 11 14 15]] # i is row and j is coloum set isFlip 0 for { set i 0 } { $i < 4 } { incr i } { if { $i > 1 } { set isFlip 1 } set tile_ly [expr $core_lly + $i*$tile_height] for { set j 0 } { $j < 4 } { incr j } { set tile_lx [expr $core_llx + $j*$tile_width] set tile_id [lindex $toffsets $i $j] puts "Placing Tile:$tile_id Tile lx:$tile_lx ly:$tile_ly Height:$tile_height Width:$tile_width" place_tiles $tile_id $tile_lx $tile_ly $tile_width $tile_height $isFlip $halo_width $stack_size } } }