You are on page 1of 4

Chip IR Drop Reduction through Automated Via Checking and Addition

Arya Raychaudhuri Fastrack Design San Jose, CA


Figure 1: Calibre SVRF Include File Generating Perl Complex physical designs (layouts) in 65 nm and below process nodes often use ten (10) or more layers of metallization. So, the length of supply (power/ground) nets as well as that of clock and signal nets is typically long, and the nets involve multiple layers of Vias. These Vias tend to dominate the impedance due to these nets. It is, therefore, often the case that insufficient Via placements on the junctions between Metal(N) and Metal(N+1) turns out to be the root cause of the IR drop failures, and net delays giving rise to setup and hold time violations. The other detrimental effect of Via-deficient junctions is increased heat dissipation and current crowding leading to electro-migration. Wide metals warping resulting in unreliable Via connections require redundant Via placements. Some Via-deficient junctions may barely meet redundant Via requirements, but additional Vias often make the junctions more robust. This paper discusses a simple Perl-Calibre approach to check for and add Vias to M(N)-M(N+1) junctions that have insufficient Vias or no Vias, but could hold more Vias without violating the topological design rules checks (DRCs). The Vias are checked for and added to junctions on user-specified nets. Although, typically supply nets (VDD,VSS) are handled by the code, there are actually no restrictions on the net names as long as they are top-level net names that can be traced downwards along metal and via lines, or even other connectivity layers.
#! /usr/bin/perl -w $infile = "via_check_add_net_names"; open(F, $infile); $i = 0; while(<F>) { $pg_name = $_; chomp $pg_name; $i = $i + 1; $m8_pg_name ="M8_".$pg_name." = "."metal8 NET ". $pg_name; $m7_pg_name ="M7_".$pg_name." = "."metal7 NET ". $pg_name; :::::::::Similar Lines of Code deleted::::::::::::::::::::::::::::::::::::::::::::: $m1_pg_name ="M1_".$pg_name." = "."metal1 NET ". $pg_name; $m8_m7_pg_name_int = "M8_M7_".$pg_name."_INT = "."M8_".$pg_name. " AND ". "M7_".$pg_name; $m7_m6_pg_name_int = "M7_M6_".$pg_name."_INT = "."M7_".$pg_name. " AND ". "M6_".$pg_name; :::::::::Similar Lines of Code deleted::::::::::::::::::::::::::::::::::::::::::::: $m2_m1_pg_name_int = "M2_M1_".$pg_name."_INT = "."M2_".$pg_name. " AND ". "M1_".$pg_name; if ($i == 1) { $m8_m7_all_int = "M8_M7_".$pg_name."_INT"; $m7_m6_all_int = "M7_M6_".$pg_name."_INT"; :::::::::Similar Lines of Code deleted::::::::::::::::::::::::::::::::::::::::::::: $m2_m1_all_int = "M2_M1_".$pg_name."_INT"; } if ($i == 2) { $m8_m7_all_int = $m8_m7_all_int. " OR "."M8_M7_".$pg_name."_INT)"; $m7_m6_all_int = $m7_m6_all_int. " OR "."M7_M6_".$pg_name."_INT)"; :::::::::Similar Lines of Code deleted::::::::::::::::::::::::::::::::::::::::::::: $m2_m1_all_int = $m2_m1_all_int. " OR "."M2_M1_".$pg_name."_INT)"; } if ($i > 2) { $m8_m7_all_int = "(".$m8_m7_all_int. " OR "."M8_M7_".$pg_name."_INT)"; $m7_m6_all_int = "(".$m7_m6_all_int. " OR "."M7_M6_".$pg_name."_INT)"; :::::::::Similar Lines of Code deleted::::::::::::::::::::::::::::::::::::::::::::: $m2_m1_all_int = "(".$m2_m1_all_int. " OR "."M2_M1_".$pg_name."_INT)"; } print "$m8_pg_name\n"; print "$m7_pg_name\n"; :::::::::Similar Lines of Code deleted:::::::::::::::::::::::::::::::::::::::::::::

The Code
In principle, the code is organized as follows. A simple Perl routine that reads in the list of top level net names computes all the M(N)-M(N+1) junctions that the userspecified nets traverse. The Perl routine shown in Fig.1 reads in the list of net names supplied in a file called via_check_add_net_names. In our test example, we just used: VDD VSS as the net names specified in this file. But, there is no restriction on the net names, as long as the physical design (layout) is LVS correct, and the top-level texting is available for the net names.

print "$m1_pg_name\n"; print "$m8_m7_pg_name_int\n"; print "$m7_m6_pg_name_int\n"; :::::::::Similar Lines of Code deleted::::::::::::::::::::::::::::::::::::::::::::: print "$m2_m1_pg_name_int\n"; } $m8_m7_all_int = "M8_M7_ALL_INT_ = ". $m8_m7_all_int; $m7_m6_all_int = "M7_M6_ALL_INT_ = ". $m7_m6_all_int; :::::::::Similar Lines of Code deleted::::::::::::::::::::::::::::::::::::::::::::: $m2_m1_all_int = "M2_M1_ALL_INT_ = ". $m2_m1_all_int; chop $m8_m7_all_int; chop $m7_m6_all_int; :::::::::Similar Lines of Code deleted::::::::::::::::::::::::::::::::::::::::::::: chop $m2_m1_all_int; print "$m8_m7_all_int\n"; print "$m7_m6_all_int\n"; :::::::::Similar Lines of Code deleted::::::::::::::::::::::::::::::::::::::::::::: print "$m2_m1_all_int\n";

In general, Via deficiency can be of two types, Vias completely missing from a junction, or a junction having insufficient Vias. In the main Calibre deck for Vias checking and adding (via_check_add.deck), we define a Via deficiency factor called VIA_FACTOR which is set to 2 for our test case. It means that, only those Viadeficient junctions will be flagged, that could hold more than twice (2-times) the number of existing Vias. We show an excerpt from the via_check_add.deck to depict the central algorithm involved, in Fig. 3. Figure 3: Excerpt from the Via checker-adder Calibre deck showing the checking for V7-deficiency and additional V7 creation in the variable VIA7_ALL_ADD
VARIABLE VIA_FACTOR 2 INCLUDE "via_check_add_include_file" CONNECT M8_M7_ALL_INT_ VIA7_COPY = COPY VIA7 CONNECT VIA7_COPY M8_M7_ALL_CORNERS = SIZE (EXT metal8 metal7 <0.005 ABUT == 90 INTERSECTING ONLY REGION) BY 0.005 M8_M7_ALL_INT = M8_M7_ALL_INT_ INTERACT M8_M7_ALL_CORNERS == 4 M8_M7_ALL_INT_CAND = M8_M7_ALL_INT ENCLOSE VIA7 M8_M7_ALL_INT_CAND_0 = M8_M7_ALL_INT NOT ENCLOSE VIA7 M8_M7_ALL_INT_SHRUNK = SIZE M8_M7_ALL_INT BY (VIA7_EN_2) CONNECT VIA7_COPY M8_M7_ALL_INT_CAND NEW_VIA7_ALL = RECTANGLES VIA7_W_1 VIA7_W_1 VIA7_S_1 INSIDE OF LAYER M8_M7_ALL_INT_SHRUNK NEW_VIA7_ALL_3_NEIGHBORS = WITH NEIGHBOR NEW_VIA7_ALL > 2 SPACE < VIA7_S_2_S NEW_VIA7_ALL_3_NEIGHBORS_ERR = EXT NEW_VIA7_ALL_3_NEIGHBORS NEW_VIA7_ALL < VIA7_S_2 ABUT < 90 SINGULAR REGION M8_M7_ALL_INT_SHRUNK_ERR = M8_M7_ALL_INT_SHRUNK INTERACT NEW_VIA7_ALL_3_NEIGHBORS_ERR NEW_VIA7_ALL_S1 = NEW_VIA7_ALL NOT INSIDE M8_M7_ALL_INT_SHRUNK_ERR NEW_VIA7_ALL_S2 = RECTANGLES VIA7_W_1 VIA7_W_1 VIA7_S_2 INSIDE OF LAYER M8_M7_ALL_INT_SHRUNK_ERR NEW_VIA7_ALL_ALL = NEW_VIA7_ALL_S1 OR NEW_VIA7_ALL_S2 CONNECT NEW_VIA7_ALL_ALL M8_M7_ALL_INT_CAND MORE_NEW_VIA7_ALL = NET AREA RATIO NEW_VIA7_ALL_ALL VIA7_COPY > VIA_FACTOR MISSING_V7_ALL_NET {@This junction has no V7 (M8_M7_ALL_INT_CAND_0 ENCLOSE NEW_VIA7_ALL_ALL) NOT NEW_VIA7_ALL_ALL } V7_OPPORTUNITY_ON_ALL_NET {@More V7s are possible on this junction M8_M7_ALL_INT_CAND_VIA_DEF = M8_M7_ALL_INT_CAND ENCLOSE MORE_NEW_VIA7_ALL M8_M7_ALL_INT_CAND_VIA_DEF NOT MORE_NEW_VIA7_ALL } VIA7_ALL_ADD_ = (NEW_VIA7_ALL_ALL INSIDE M8_M7_ALL_INT_CAND_0) OR (MORE_NEW_VIA7_ALL NOT (SIZE VIA7_COPY BY VIA7_S_2)) VIA7_ALL_ADD_HIER = M8 AND (RECTANGLE VIA7_ALL_ADD_ ==VIA7_W_1 BY ==VIA7_W_1) VIA7_ALL_ADD = FLATTEN VIA7_ALL_ADD_HIER

As shown in Fig. 1, the Perl routine computes the metal junctions from M8 through M1, and combines them into single SVRF junction variables for all user-specified nets. For our example of the two nets VDD, VSS, the SVRF include file looks like the one shown in Fig. 2. Figure 2: Calibre SVRF Include file that computes the candidate metal junctions for Via Checking and Addition
M8_VDD = metal8 NET VDD M7_VDD = metal7 NET VDD :::::::::Similar Lines of Code deleted::::::::::::::::::::::::::::::::::::::::::::: M1_VDD = metal1 NET VDD M8_M7_VDD_INT = M8_VDD AND M7_VDD M7_M6_VDD_INT = M7_VDD AND M6_VDD :::::::::Similar Lines of Code deleted::::::::::::::::::::::::::::::::::::::::::::: M2_M1_VDD_INT = M2_VDD AND M1_VDD M8_VSS = metal8 NET VSS M7_VSS = metal7 NET VSS :::::::::Similar Lines of Code deleted::::::::::::::::::::::::::::::::::::::::::::: M1_VSS = metal1 NET VSS M8_M7_VSS_INT = M8_VSS AND M7_VSS M7_M6_VSS_INT = M7_VSS AND M6_VSS :::::::::Similar Lines of Code deleted::::::::::::::::::::::::::::::::::::::::::::: M2_M1_VSS_INT = M2_VSS AND M1_VSS M8_M7_ALL_INT_ = M8_M7_VDD_INT OR M8_M7_VSS_INT M7_M6_ALL_INT_ = M7_M6_VDD_INT OR M7_M6_VSS_INT :::::::::Similar Lines of Code deleted::::::::::::::::::::::::::::::::::::::::::::: M2_M1_ALL_INT_ = M2_M1_VDD_INT OR M2_M1_VSS_INT

The SVRF include file shown in Fig. 2 clearly indicates that the net-based intersections are computed net-bynet, and M(N)-M(N+1) pair-by-pair, and then ORed together for each pair of consecutive metallization levels. This via_check_add_include_file forms a part of the main Calibre deck that checks for and adds Vias in Viadeficient junctions.

The Via checker adder routine uses the VARIABLE names like VIA7_W_1, VIA7_S_1, etc. and their values from a standard TSMC 65 nm DRC deck. As is seen in Fig. 3, the SVRF include file, via_check_add_include_file is an INCLUDE file in this main routine. Although it is not always necessary in this routine, we prune the set of all intersections read in from the Include file, to treat only those junctions where metals completely cross one another and form a + sign. This is normally the situation for power/ground grids, like our test layout shown in Fig. 4. In the Via checker-adder algorithm, we capture the DRC flags for Via deficiency in the rulechecks such as MISSING_V7_ALL_NET, and V7_OPPORTUNITY_ON_ALL_NET. The first category flags the junctions that are completely lacking in Vias, and the second one the junctions that have insufficient Vias. Both flags are present in the error junctions with the Calibre computed possible Vias subtracted from them. This way, we economize on the number of flags generated, as well as present comprehensive Via deficiency pictures with the single flags. As is evident from the code, DRC correctness is maintained for the newly generated Vias. The Via deficiency is computed by taking the NET AREA RATIO between the generated Vias and the pre-existing Vias, and comparing it with the VIA_FACTOR, as mentioned earlier. The DRC flags are reported in an ASCII db file that is viewable through the RVE GUI. The VIA7_ALL_ADD variable in the code captures all the additional VIA7s that are output in a GDS file by the Calibre deck. The additional Vias from the GDS file can be added to existing layout as an overlay cell, since they maintain design rules compliant spacing to the existing Vias.

Figure 4: Test VSS/VDD grid in M4 through M8 connected by V4 through V7

Figure 5: DRC Flags showing Via-deficient junctions, as well as possible DRC-correct Via positions

The Results
For this test run, we used a Calibre-generated VDD/VSS grid consisting of M4 through M8, and connected by V4 through V7. This grid is shown in Fig.4. The vertical grids, 2 um wide and 100 um long are in M7 (purple) and M5 (golden), while the horizontal grids are in M8 (light blue), M6 (white), and M4 (pink). As is seen in Fig. 4, the grids are texted VSS, VDD at the top level with M8 texter layer. The grids are connected by DRC correct Vias (V7, V6, at 0.36 um square, and V5, V4 at 0.10 um square, as per TSMC 65 nm design rules). The grid is completely checked for connectivity issues (for example, shorting of VDD, VSS) before application of our Via checker adder script. We intentionally deleted Vias from some junctions, or under-populated them to see if the routine flags the Via deficient junctions and adds the Vias properly, see Figs. 5 & 6.

In Fig. 5, we clearly see that our routine clearly flags the junctions where the Vias are either completely missing or insufficient. On the lower left, you see a M7-M8 junction being flagged, that was completely missing the V7s. On the upper right, you see a M5-M6 junction being flagged, that had just one Via (red) near the center, clearly insufficient compared to the size of the junction. In both cases, the flags are showing how many DRC correct Vias were possible and where! This feedback is often useful for the physical layout designer, who can then go ahead and add those Vias at those locations.

Figure 6: Additional Vias added through the Via checker adder procedure

In Fig, 6, we show the Calibre generated *additional* Vias at the Via-deficient junctions. In this case, the additional V4 (pink) and V5 (golden) have been added on junctions with just one Via near the center of the intersections. So, the additional generated Vias subtract that Via and the design rules compliant spacings around it, giving rise to the hole near the center of the Via patterns. In the case of the additional V7s near the right side of the picture, there was only one Via near the left/bottom corner of the M7-M8 junction. So, only 3 V7s have been added. While in the case of the V7s added on the left side of the picture, the junction was completely lacking in V7s, so all the 4 V7s have been added. In some of the real layouts on which we tried the routine, we could add tens of thousands of Vias through this procedure; thus, significantly reducing the overall IR drops and net delays.

Conclusion
In this paper, we discuss a Perl-Calibre based Via optimization procedure that can be applied to any physical designs with multiple levels of metallizations. The procedure searches for Via deficient junctions and flags them in a simple but comprehensive DRC results database formatthat can help in manual correction of the junctions. The routine also features an automatic Via generation feature that involves outputting a GDS file containing all the additional Vias that could be added to the junctions. The user can then simply add the additional Vias from the GDS as an overlay cell to the existing physical design, which will save the time and resources needed to manually correct the junctions.

You might also like