place_mempool_macros.tcl 6.09 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
#############################################################################
# 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
    }
  }
}