|
80 | 80 | # 30 "Layer specified for std. cell rails '$layer' not in list of layers." |
81 | 81 | # 31 "No matching grid specification found for $instance" |
82 | 82 | # 33 "Unknown direction for layer $layer_name" |
| 83 | +# 41 "Need to define pwr_pads and gnd_pads in config file to use pad_offset option" |
83 | 84 | # |
84 | 85 | # 9999 - Unexpected error |
85 | 86 | # |
@@ -1841,27 +1842,27 @@ proc generate_via_stacks {l1 l2 tag constraints} { |
1841 | 1842 | if {[get_dir $layer1] == "hor"} { |
1842 | 1843 | if {$height < [get_grid_wire_width $layer1]} { |
1843 | 1844 | # If the intersection doesnt cover the whole width of the bottom level wire, then ignore |
1844 | | - warning 40 "No via added at ([expr 1.0 * $xMin / $def_units] [expr 1.0 * $yMin / $def_units] [expr 1.0 * $xMax / $def_units] [expr 1.0 * $yMax / $def_units]) because the full height of $layer1 ([expr 1.0 * [get_grid_wire_width $layer1] / $def_units]) is not covered by the overlap" |
| 1845 | + # warning 40 "No via added at ([expr 1.0 * $xMin / $def_units] [expr 1.0 * $yMin / $def_units] [expr 1.0 * $xMax / $def_units] [expr 1.0 * $yMax / $def_units]) because the full height of $layer1 ([expr 1.0 * [get_grid_wire_width $layer1] / $def_units]) is not covered by the overlap" |
1845 | 1846 | continue |
1846 | 1847 | } |
1847 | 1848 | } else { |
1848 | 1849 | if {$width < [get_grid_wire_width $layer1]} { |
1849 | 1850 | # If the intersection doesnt cover the whole width of the bottom level wire, then ignore |
1850 | | - warning 41 "No via added at ([expr 1.0 * $xMin / $def_units] [expr 1.0 * $yMin / $def_units] [expr 1.0 * $xMax / $def_units] [expr 1.0 * $yMax / $def_units]) because the full width of $layer1 ([expr 1.0 * [get_grid_wire_width $layer1] / $def_units]) is not covered by the overlap" |
| 1851 | + # warning 41 "No via added at ([expr 1.0 * $xMin / $def_units] [expr 1.0 * $yMin / $def_units] [expr 1.0 * $xMax / $def_units] [expr 1.0 * $yMax / $def_units]) because the full width of $layer1 ([expr 1.0 * [get_grid_wire_width $layer1] / $def_units]) is not covered by the overlap" |
1851 | 1852 | continue |
1852 | 1853 | } |
1853 | 1854 | } |
1854 | 1855 | } |
1855 | 1856 | if {[get_dir $layer2] == "hor"} { |
1856 | 1857 | if {$height < [get_grid_wire_width $layer2]} { |
1857 | 1858 | # If the intersection doesnt cover the whole width of the top level wire, then ignore |
1858 | | - warning 40 "No via added at ([expr 1.0 * $xMin / $def_units] [expr 1.0 * $yMin / $def_units] [expr 1.0 * $xMax / $def_units] [expr 1.0 * $yMax / $def_units]) because the full height of $layer2 ([expr 1.0 * [get_grid_wire_width $layer2] / $def_units]) is not covered by the overlap" |
| 1859 | + # warning 40 "No via added at ([expr 1.0 * $xMin / $def_units] [expr 1.0 * $yMin / $def_units] [expr 1.0 * $xMax / $def_units] [expr 1.0 * $yMax / $def_units]) because the full height of $layer2 ([expr 1.0 * [get_grid_wire_width $layer2] / $def_units]) is not covered by the overlap" |
1859 | 1860 | continue |
1860 | 1861 | } |
1861 | 1862 | } else { |
1862 | 1863 | if {$width < [get_grid_wire_width $layer2]} { |
1863 | 1864 | # If the intersection doesnt cover the whole width of the top level wire, then ignore |
1864 | | - warning 41 "No via added at ([expr 1.0 * $xMin / $def_units] [expr 1.0 * $yMin / $def_units] [expr 1.0 * $xMax / $def_units] [expr 1.0 * $yMax / $def_units]) because the full width of $layer2 ([expr 1.0 * [get_grid_wire_width $layer2] / $def_units]) is not covered by the overlap" |
| 1865 | + # warning 41 "No via added at ([expr 1.0 * $xMin / $def_units] [expr 1.0 * $yMin / $def_units] [expr 1.0 * $xMax / $def_units] [expr 1.0 * $yMax / $def_units]) because the full width of $layer2 ([expr 1.0 * [get_grid_wire_width $layer2] / $def_units]) is not covered by the overlap" |
1865 | 1866 | continue |
1866 | 1867 | } |
1867 | 1868 | } |
@@ -1983,24 +1984,29 @@ proc generate_upper_metal_mesh_stripes {tag layer layer_info area} { |
1983 | 1984 | proc adjust_area_for_core_rings {layer area} { |
1984 | 1985 | variable grid_data |
1985 | 1986 |
|
1986 | | - set core_offset [dict get $grid_data core_ring $layer core_offset] |
1987 | | - set width [dict get $grid_data core_ring $layer width] |
1988 | | - set spacing [dict get $grid_data core_ring $layer spacing] |
| 1987 | + if {[dict exists $grid_data core_ring $layer pad_offset]} { |
| 1988 | + set pad_area [find_pad_offset_area] |
| 1989 | + set width [dict get $grid_data core_ring $layer width] |
| 1990 | + set offset [expr [dict get $grid_data core_ring $layer pad_offset]] |
| 1991 | + set spacing [dict get $grid_data core_ring $layer spacing] |
| 1992 | + set xMin [expr [lindex $pad_area 0] + $offset] |
| 1993 | + set yMin [expr [lindex $pad_area 1] + $offset] |
| 1994 | + set xMax [expr [lindex $pad_area 2] - $offset] |
| 1995 | + set yMax [expr [lindex $pad_area 3] - $offset] |
| 1996 | + } elseif {[dict exists $grid_data core_ring $layer core_offset]} { |
| 1997 | + set offset [dict get $grid_data core_ring $layer core_offset] |
| 1998 | + set width [dict get $grid_data core_ring $layer width] |
| 1999 | + set spacing [dict get $grid_data core_ring $layer spacing] |
| 2000 | + set xMin [expr [lindex $area 0] - $offset - $width - $spacing - $width / 2] |
| 2001 | + set yMin [expr [lindex $area 1] - $offset - $width - $spacing - $width / 2] |
| 2002 | + set xMax [expr [lindex $area 2] + $offset + $width + $spacing + $width / 2] |
| 2003 | + set yMax [expr [lindex $area 3] + $offset + $width + $spacing + $width / 2] |
| 2004 | + } |
1989 | 2005 |
|
1990 | 2006 | if {[get_dir $layer] == "hor"} { |
1991 | | - set extended_area [list \ |
1992 | | - [expr [lindex $area 0] - $core_offset - $width - $spacing - $width / 2] \ |
1993 | | - [lindex $area 1] \ |
1994 | | - [expr [lindex $area 2] + $core_offset + $width + $spacing + $width / 2] \ |
1995 | | - [lindex $area 3] \ |
1996 | | - ] |
| 2007 | + set extended_area [list $xMin [lindex $area 1] $xMax [lindex $area 3]] |
1997 | 2008 | } else { |
1998 | | - set extended_area [list \ |
1999 | | - [lindex $area 0] \ |
2000 | | - [expr [lindex $area 1] - $core_offset - $width - $spacing - $width / 2] \ |
2001 | | - [lindex $area 2] \ |
2002 | | - [expr [lindex $area 3] + $core_offset + $width + $spacing + $width / 2] \ |
2003 | | - ] |
| 2009 | + set extended_area [list [lindex $area 0] $yMin [lindex $area 2] $yMax] |
2004 | 2010 | } |
2005 | 2011 | return $extended_area |
2006 | 2012 | } |
@@ -2084,61 +2090,172 @@ proc generate_grid_vias {tag net_name} { |
2084 | 2090 | proc get_core_ring_centre {type side layer_info} { |
2085 | 2091 | variable grid_data |
2086 | 2092 |
|
2087 | | - set area [find_core_area] |
2088 | | - set xMin [lindex $area 0] |
2089 | | - set yMin [lindex $area 1] |
2090 | | - set xMax [lindex $area 2] |
2091 | | - set yMax [lindex $area 3] |
2092 | | - set core_offset [dict get $layer_info core_offset] |
2093 | 2093 | set spacing [dict get $layer_info spacing] |
2094 | 2094 | set width [dict get $layer_info width] |
2095 | 2095 |
|
2096 | | - # debug "area $area" |
2097 | | - # debug "core_offset $core_offset" |
2098 | | - # debug "spacing $spacing" |
2099 | | - # debug "width $width" |
2100 | | - switch $type { |
2101 | | - "POWER" { |
2102 | | - switch $side { |
2103 | | - "t" {return [expr $yMax + $core_offset]} |
2104 | | - "b" {return [expr $yMin - $core_offset]} |
2105 | | - "l" {return [expr $xMin - $core_offset]} |
2106 | | - "r" {return [expr $xMax + $core_offset]} |
| 2096 | + if {[dict exists $layer_info pad_offset]} { |
| 2097 | + set area [find_pad_offset_area] |
| 2098 | + set xMin [lindex $area 0] |
| 2099 | + set yMin [lindex $area 1] |
| 2100 | + set xMax [lindex $area 2] |
| 2101 | + set yMax [lindex $area 3] |
| 2102 | + set offset [expr [dict get $layer_info pad_offset] + $width / 2] |
| 2103 | + # debug "area $area" |
| 2104 | + # debug "pad_offset $offset" |
| 2105 | + # debug "spacing $spacing" |
| 2106 | + # debug "width $width" |
| 2107 | + switch $type { |
| 2108 | + "GROUND" { |
| 2109 | + switch $side { |
| 2110 | + "t" {return [expr $yMax - $offset]} |
| 2111 | + "b" {return [expr $yMin + $offset]} |
| 2112 | + "l" {return [expr $xMin + $offset]} |
| 2113 | + "r" {return [expr $xMax - $offset]} |
| 2114 | + } |
| 2115 | + } |
| 2116 | + "POWER" { |
| 2117 | + switch $side { |
| 2118 | + "t" {return [expr $yMax - $offset - $spacing - $width]} |
| 2119 | + "b" {return [expr $yMin + $offset + $spacing + $width]} |
| 2120 | + "l" {return [expr $xMin + $offset + $spacing + $width]} |
| 2121 | + "r" {return [expr $xMax - $offset - $spacing - $width]} |
| 2122 | + } |
2107 | 2123 | } |
2108 | 2124 | } |
2109 | | - "GROUND" { |
2110 | | - switch $side { |
2111 | | - "t" {return [expr $yMax + $core_offset + $spacing + $width]} |
2112 | | - "b" {return [expr $yMin - $core_offset - $spacing - $width]} |
2113 | | - "l" {return [expr $xMin - $core_offset - $spacing - $width]} |
2114 | | - "r" {return [expr $xMax + $core_offset + $spacing + $width]} |
| 2125 | + } elseif {[dict exists $layer_info core_offset]} { |
| 2126 | + set area [find_core_area] |
| 2127 | + set xMin [lindex $area 0] |
| 2128 | + set yMin [lindex $area 1] |
| 2129 | + set xMax [lindex $area 2] |
| 2130 | + set yMax [lindex $area 3] |
| 2131 | + |
| 2132 | + set offset [dict get $layer_info core_offset] |
| 2133 | + # debug "area $area" |
| 2134 | + # debug "core_offset $offset" |
| 2135 | + # debug "spacing $spacing" |
| 2136 | + # debug "width $width" |
| 2137 | + switch $type { |
| 2138 | + "POWER" { |
| 2139 | + switch $side { |
| 2140 | + "t" {return [expr $yMax + $offset]} |
| 2141 | + "b" {return [expr $yMin - $offset]} |
| 2142 | + "l" {return [expr $xMin - $offset]} |
| 2143 | + "r" {return [expr $xMax + $offset]} |
| 2144 | + } |
| 2145 | + } |
| 2146 | + "GROUND" { |
| 2147 | + switch $side { |
| 2148 | + "t" {return [expr $yMax + $offset + $spacing + $width]} |
| 2149 | + "b" {return [expr $yMin - $offset - $spacing - $width]} |
| 2150 | + "l" {return [expr $xMin - $offset - $spacing - $width]} |
| 2151 | + "r" {return [expr $xMax + $offset + $spacing + $width]} |
| 2152 | + } |
2115 | 2153 | } |
2116 | 2154 | } |
2117 | 2155 | } |
2118 | 2156 | } |
2119 | 2157 |
|
2120 | | -proc generate_core_rings {} { |
| 2158 | +proc find_pad_offset_area {} { |
| 2159 | + variable block |
| 2160 | + variable grid_data |
| 2161 | + variable design_data |
| 2162 | + |
| 2163 | + if {!([dict exists $grid_data pwr_pads] && [dict exists $grid_data gnd_pads])} { |
| 2164 | + critical 41 "Need to define pwr_pads and gnd_pads in config file to use pad_offset option" |
| 2165 | + } |
| 2166 | + |
| 2167 | + set pad_names {} |
| 2168 | + dict for {pin_name pads} [dict get $grid_data pwr_pads] { |
| 2169 | + set pad_names [concat $pad_names $pads] |
| 2170 | + } |
| 2171 | + dict for {pin_name pads} [dict get $grid_data gnd_pads] { |
| 2172 | + set pad_names [concat $pad_names $pads] |
| 2173 | + } |
| 2174 | + set pad_names [lsort -unique $pad_names] |
| 2175 | + set die_area [dict get $design_data config die_area] |
| 2176 | + set xMin [lindex $die_area 0] |
| 2177 | + set yMin [lindex $die_area 1] |
| 2178 | + set xMax [lindex $die_area 2] |
| 2179 | + set yMax [lindex $die_area 3] |
| 2180 | + |
| 2181 | + foreach inst [$block getInsts] { |
| 2182 | + if {[lsearch $pad_names [[$inst getMaster] getName]] > -1} { |
| 2183 | + set quadrant [get_quadrant {*}[$inst getOrigin]] |
| 2184 | + switch $quadrant { |
| 2185 | + "b" { |
| 2186 | + if {$yMin < [set y [[$inst getBBox] yMax]]} { |
| 2187 | + set yMin $y |
| 2188 | + } |
| 2189 | + } |
| 2190 | + "r" { |
| 2191 | + if {$xMax > [set x [[$inst getBBox] xMin]]} { |
| 2192 | + set xMax $x |
| 2193 | + } |
| 2194 | + } |
| 2195 | + "t" { |
| 2196 | + if {$yMax > [set y [[$inst getBBox] yMin]]} { |
| 2197 | + set yMax $y |
| 2198 | + } |
| 2199 | + } |
| 2200 | + "l" { |
| 2201 | + if {$xMin < [set x [[$inst getBBox] xMax]]} { |
| 2202 | + set xMin $x |
| 2203 | + } |
| 2204 | + } |
| 2205 | + } |
| 2206 | + } |
| 2207 | + } |
| 2208 | + return [list $xMin $yMin $xMax $yMax] |
| 2209 | +} |
| 2210 | + |
| 2211 | +proc generate_core_rings {core_ring_data} { |
2121 | 2212 | variable grid_data |
2122 | 2213 |
|
2123 | | - dict for {layer layer_info} [dict get $grid_data core_ring] { |
2124 | | - set area [find_core_area] |
2125 | | - set xMin [lindex $area 0] |
2126 | | - set yMin [lindex $area 1] |
2127 | | - set xMax [lindex $area 2] |
2128 | | - set yMax [lindex $area 3] |
2129 | | - set core_offset [dict get $layer_info core_offset] |
2130 | | - set spacing [dict get $layer_info spacing] |
2131 | | - set width [dict get $layer_info width] |
| 2214 | + dict for {layer layer_info} $core_ring_data { |
| 2215 | + if {[dict exists $layer_info pad_offset]} { |
| 2216 | + set area [find_pad_offset_area] |
| 2217 | + set offset [expr [dict get $layer_info pad_offset] + [dict get $layer_info width] / 2] |
| 2218 | + |
| 2219 | + set xMin [lindex $area 0] |
| 2220 | + set yMin [lindex $area 1] |
| 2221 | + set xMax [lindex $area 2] |
| 2222 | + set yMax [lindex $area 3] |
| 2223 | + |
| 2224 | + set spacing [dict get $layer_info spacing] |
| 2225 | + set width [dict get $layer_info width] |
2132 | 2226 |
|
2133 | | - set inner_lx [expr $xMin - $core_offset] |
2134 | | - set inner_ly [expr $yMin - $core_offset] |
2135 | | - set inner_ux [expr $xMax + $core_offset] |
2136 | | - set inner_uy [expr $yMax + $core_offset] |
| 2227 | + set outer_lx [expr $xMin + $offset] |
| 2228 | + set outer_ly [expr $yMin + $offset] |
| 2229 | + set outer_ux [expr $xMax - $offset] |
| 2230 | + set outer_uy [expr $yMax - $offset] |
| 2231 | + |
| 2232 | + set inner_lx [expr $xMin + $offset + $spacing + $width] |
| 2233 | + set inner_ly [expr $yMin + $offset + $spacing + $width] |
| 2234 | + set inner_ux [expr $xMax - $offset - $spacing - $width] |
| 2235 | + set inner_uy [expr $yMax - $offset - $spacing - $width] |
| 2236 | + } elseif {[dict exists $layer_info core_offset]} { |
| 2237 | + set area [find_core_area] |
| 2238 | + set offset [dict get $layer_info core_offset] |
| 2239 | + |
| 2240 | + set xMin [lindex $area 0] |
| 2241 | + set yMin [lindex $area 1] |
| 2242 | + set xMax [lindex $area 2] |
| 2243 | + set yMax [lindex $area 3] |
| 2244 | + |
| 2245 | + set spacing [dict get $layer_info spacing] |
| 2246 | + set width [dict get $layer_info width] |
| 2247 | + |
| 2248 | + set inner_lx [expr $xMin - $offset] |
| 2249 | + set inner_ly [expr $yMin - $offset] |
| 2250 | + set inner_ux [expr $xMax + $offset] |
| 2251 | + set inner_uy [expr $yMax + $offset] |
| 2252 | + |
| 2253 | + set outer_lx [expr $xMin - $offset - $spacing - $width] |
| 2254 | + set outer_ly [expr $yMin - $offset - $spacing - $width] |
| 2255 | + set outer_ux [expr $xMax + $offset + $spacing + $width] |
| 2256 | + set outer_uy [expr $yMax + $offset + $spacing + $width] |
| 2257 | + } |
2137 | 2258 |
|
2138 | | - set outer_lx [expr $xMin - $core_offset - $spacing - $width] |
2139 | | - set outer_ly [expr $yMin - $core_offset - $spacing - $width] |
2140 | | - set outer_ux [expr $xMax + $core_offset + $spacing + $width] |
2141 | | - set outer_uy [expr $yMax + $core_offset + $spacing + $width] |
2142 | 2259 |
|
2143 | 2260 | if {[get_dir $layer] == "hor"} { |
2144 | 2261 | add_stripe $layer POWER \ |
@@ -2862,7 +2979,7 @@ proc init {{PDN_cfg "PDN.cfg"}} { |
2862 | 2979 | proc convert_layer_spec_to_def_units {data} { |
2863 | 2980 | variable def_units |
2864 | 2981 |
|
2865 | | - foreach key {width pitch spacing offset core_offset} { |
| 2982 | + foreach key {width pitch spacing offset pad_offset core_offset} { |
2866 | 2983 | if {[dict exists $data $key]} { |
2867 | 2984 | dict set data $key [expr round([dict get $data $key] * $def_units)] |
2868 | 2985 | } |
@@ -3455,7 +3572,7 @@ proc add_grid {} { |
3455 | 3572 | variable grid_data |
3456 | 3573 |
|
3457 | 3574 | if {[dict exists $grid_data core_ring]} { |
3458 | | - generate_core_rings |
| 3575 | + generate_core_rings [dict get $grid_data core_ring] |
3459 | 3576 | if {[dict exists $grid_data gnd_pads]} { |
3460 | 3577 | dict for {pin_name cells} [dict get $grid_data gnd_pads] { |
3461 | 3578 | connect_pads_to_core_ring "GROUND" $pin_name $cells |
@@ -3677,7 +3794,7 @@ proc report_layer_details {layer} { |
3677 | 3794 | variable def_units |
3678 | 3795 |
|
3679 | 3796 | set str " - " |
3680 | | - foreach element {width pitch spacing offset core_offset} { |
| 3797 | + foreach element {width pitch spacing offset pad_offset core_offset} { |
3681 | 3798 | if {[dict exists $layer $element]} { |
3682 | 3799 | set str [format "$str $element: %.3f " [expr 1.0 * [dict get $layer $element] / $def_units]] |
3683 | 3800 | } |
|
0 commit comments