[Arya Raychaudhuri's one-man enterprise that believes in Always Move Ahead with New Ideas]
"home" , "code snippets", "via check add paper" "backpage" buttons on the left side, to select a specific page
[Norton Security Seal is now discontinued by Yahoo for Site Solution based websites, but moved from http to https]
the pages are best viewed through internet explorer
WordPress
BLOG PAGE: http://lvs-debug-solutions.com/blog/
[kept inactive to avoid spam]
This is the age of search engines - quickly search for entities and their inter-relationships. And, LVS Debug is all about analyzing netlists and gds/oasis layout databases, and finding their correspondences/matches/mismatches in the post-PD domain. So, much of the codes presented in the 'code snippets' page focus on searching and parsing these huge netlist and layout files, to extract the relevant information and their connection. The other important thing is the focus on revenue/jobs generating creative ideas - because if you cannot come up with new product ideas every now and then, what will you sell tomorrow, in the future? I have now transformed LVS DEBUG SOLUTIONS LLC into a multi-engineering concepts platform (please review the code snippets* pages under https://www.lvs-debug-solutions.com)
google email: arya.raychaudhuri@gmail.com
Please direct all official communications to
arya@lvs-debug-solutions.com, or call 408-480-1936
I typically don't answer calls from unknown callers, to avoid spam. If you are a serious caller, please leave voice or text message, or email...For text message from international locations, please use cellphone number as 1-408-480-1936
LVS DEBUG SOLUTIONS LLC
980 Kiely Blvd, Unit 308
Santa Clara, CA 95051
United States
ph: 1-408-480-1936
arya
Arya Raychaudhuri
Fastrack Design
San Jose, CA
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.
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.
Figure 1: Calibre SVRF Include File Generating Perl
#! /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:::::::::::::::::::::::::::::::::::::::::::::
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";
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-by-net, 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 Via-deficient junctions.
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 Via-deficient 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
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.
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.
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
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 format—that 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.
***
** Due to technical issues in reading the paper on Electronic Design, the original manuscript is pasted here
Programmed Splitting Of Fullchip Calibre DRC/ERC Errors Into Sub-Block Space
Arya Raychaudhuri, Fastrack Design, and Duc Vu, PLX Technology, January 19, 2011
INTRODUCTION
In many ways, the presentation of design-rule and electrical-rule checking (DRC/ERC) results to sub-block developers and IP vendors remains a vital component of physical verification work performed with Mentor Graphics’ Calibre physical verification suite. Not only is it important to see the DRC errors in the window defined by the individual sub-block instances, but also in a collection of sub-block windows, as desired by the developers, physical designers, or place-and-route engineers, to view correlations and dependencies of the errors.
The concept of analyzing the DRC/ERC errors in the context of the full chip first, and then pushing those errors that lie inside the sub-blocks or the IP boundaries to later analyze those errors again in the context of the sub-blocks or the IPs makes a lot of sense. There also are situations arising out of adjacent placement of hierarchical sub-blocks when those sub-blocks were not designed with arbitrary juxtapositions in mind. In such situations, it is relevant to view the interface errors in a window defined by the adjacent instances. Thus, productivity in physical design is enhanced by pushing the full-chip DRC/ERC errors to the specifiable sub-block windows without multiple time-consuming DRC/ERC runs.
While data filtering to the windows in the full-chip context is the crucial first step towards improved DRC error viewing and correction, it is often useful to distribute the data to the individual sub-block cells in the coordinate space of the sub-block, and pass it on to the sub-block owner for analysis and correction. Of course, Calibre's generic “DRC CELL NAME YES CELL SPACE XFORM” construct within the SVRF polygon processing language performs cell-space distributions, but it often tends to over-distribute into deeper sub-cells of a sub-block. Further, it does not handle window-based filtered data as discussed earlier. Filtered data should also contain errors that actually occur in the top level of the hierarchy, but physically sitting on top of a sub-block instance.
The same is true for GDS-formatted DRC results database outputs from a hierarchical DRC run that distributes errors data into sub-cells. Considering the limitations of some of the existing methods, we have come up with a new algorithm, based on CalibreDRV tcl, Calibre SVRF, and Perl/shell constructs, to implement DRC/ERC data filtering to cell windows in full-chip context, and subsequently translate individual cell window data to the cell's coordinate space. The methodology works well in a number of full-chip DRC/ERC scenarios.
THE METHODOLOGY
The first step in this methodology is to decide which sub-blocks of the full chip you want the DRC/ERC error to be filtered to. Say, for example, you want to filter it to the windows defined by two sub_blocks, SUB_BLOCK_X and SUB_BLOCK_Y. Make a linear list of those sub-blocks and put them in a file; call it 'subblock_list.’
The next step is to determine which error types from the DRC/ERC database you want to filter the errors for. We will give an example from the ERC results from standard TSMC layout-vs.-schematic (LVS) runs:
mnpg
floating.nxwell
npvss49
npvss150
ppvdd150
Again, you want to put these error types into an ASCII file that we will name 'ERR_list.’ Obviously, these two files are the primary inputs to the Perl routine ('drc_splitter.pl'). The other two inputs to the routine are: The full-chip ERC results database file and the full-chip GDS file. Let us call them ERC.db and FULLCHIP.gds, respectively.
As for outputs, we get a filtered ERC results database file ('filtered_erc.db') and a corresponding summary file, 'filtered_erc.rep,' that represent the ERC errors in ERC.db as filtered on the windows defined by the sub-blocks SUB_BLOCK_X and SUB_BLOCK_Y. We can show all the ERC errors reported in ERC.db [Figure 1] as super-imposed on the full-chip GDS file as viewed through Calibre RVE.
Fig. 1: Shown are all ERC results on the full chip as reported in the ERC.db ASCII ERC database.
We also can show the filtered ERC results [Figure 2] obtained by running drc_splitter.pl on the windows defined by the cell names in ‘subblock_list.’ The two sub-blocks are marked for clarity. Only errors residing inside the cell boundary of the two selected blocks are being considered.
Fig. 2: Here we see the filtered ERC results as obtained by running the drc_splitter.pl on the windows defined by the cell names in ‘subblock_list.’
The corresponding summary file ('filtered_erc.rep') reports:
RULECHECK floating.nxwell ... TOTAL Result Count = 1
RULECHECK mnpg ... TOTAL Result Count = 0
RULECHECK npvss150 ... TOTAL Result Count = 3362
RULECHECK npvss49 ... TOTAL Result Count = 5
RULECHECK ppvdd150 ... TOTAL Result Count = 304
In this fashion, one may filter the ERC results for various combinations of sub-blocks and distribute the filtered results to the corresponding sub-block owners to focus on the correlations of ERC issues, issues arising out of adjacent placements, or even issues in an individual sub-block due to its placement in the full-chip context. One may run the splitter for any combination of DRC or ERC error types by selecting them by name in the 'ERR_list' file, and even for a single error type if desired. It is also possible to run the splitter for any combination of sub-blocks by selecting them by name in the 'subblock_list' file, and even for a single sub-block for a single or multiple error types.
If we re-run the splitter for a single cell 'SUB_BLOCK_X' and all the error types listed in 'ERR_list', we may show how those results would appear [Figure 3]. In both Figure 2 and Figure 3, we showed how the data is represented in the coordinate system of the full chip. However, the ability to represent the ‘filtered’ data in the coordinate system of the individual sub-blocks or the IPs is extremely useful.
Fig. 3: This figure shows the ERC results filtered to a single sub-block.
In this case, you must first determine the cell's instance origin, placement mirroring, and orientation. Do this using simple .tcl (CalibreDRV) code such as:
set L1 [layout create FULLCHIP.gds -dt_expand -preserveProperties -preserveTextAttributes]
foreach ii [$L1 iterator ref FULLCHIP range 0 end] {
puts $ii
}
If we call this 'iterator.tc', running the tcl code will give us the sub-block's placement details. For example,
calibredrv -64 iterator.tc |grep SUB_BLOCK_X
==>
SUB_BLOCK_X 133000 3066000 0 0 1 {}
Where the x0, y0 of the instance origin follow the cell's name, the cell has no mirroring (0) and no rotation (0), and unity (1) magnification factor. Depending on these instance details, we present a simple shell script to accomplish coordinate transformation:
grep -n '[A-Za-z0-9\}*]' filtered_erc.db | sed -e 's/:/ /' | grep -v '[A-Za-z\}*]' > num_num
grep -n '[A-Za-z0-9\}*]' filtered_erc.db | sed -e 's/:/ /' | grep '[A-Za-z\}*]' > jnk_jnk
cat num_num | awk '{print $1 " " $2-x0 " " $3-y0}' > num_num_xform
cat jnk_jnk >> num_num_xform
sort -n -k1 num_num_xform | awk '{print $2 " " $3 " " $4 " " $5 " " $6 " " $7 " " $8 " " $9 " " $10}' | sed -e 's/[ ]*$//' | sed -e 's/FULLCHIP/SUB_BLOCK_X/' > filtered_erc_xform.db
This takes the 'filtered_erc.db' for the single cell with 0,0 orientation to 'filtered_erc_xform.db' in the coordinate space of the 'SUB_BLOCK_X' block. In the above shell code, note that the terms $2-x0 and $3-y0 and their order determines the transformed x,y coordinates in the cell's coordinate space. For example, for a sub-block with instance orientation of 1,270, those terms should occur as y0-$3 and x0-$2, and in that order. We can show how the transformed data looks [Figure 4].
Fig. 4: Here we see the ERC data transformed to the coordinate space of the sub-block.
THE ALGORITHM
The algorithm of the Perl routine drc_splitter.pl consists of the following steps:
Step 1. Find the instance boxes for the members of the 'subblock_list' file using calibreDRV's '$L instancedbout' command syntax. This produces the instance boxes as DRC errors into an 'instance_file.'
Step 2. Concatenate the 'instance_file' to the 'ERC.db' file to produce a combined database file that contains both errors and the sub-block's corners as error types that are named after the sub-block's name from 'subblock_list'. Let us call this combined database ERC_COMB.db. The Perl routine essentially parses this combined database to separate error polygons from instance boxes and actual ERC errors, and ANDs the two entities to create the “filtered” data.
Step 3. To match the 'ERC_COMB.db' for parsing through sub-block names and error types, create another ASCII file, concatenating the 'ERR_list' file to the 'subblock_list', and call the resulting file 'subcell_list'. Notice that in the 'subcell_list', the names of the sub-blocks come first, followed by the error types.
Step 4. Create an outer loop with the 'subcell_list' so that the sub-blocks in the ERC_COMB.db, parsed in an inner loop, are handled first. This creates calibreDRV polygons ($L create polygon FULLCHIP 400 <polygons coordinates>) for the instance boxes in an outer loop .tcl file (‘Cells.tcl’), containing the instance boxes. For example,
set L1 [layout create]
$L1 create cell FULLCHIP
$L1 create layer 400
$L1 create layer 401
$L1 create layer 402
$L1 create polygon FULLCHIP 400 133000 2510000 133000 3066001 958000 3066001 958000 2510000
There could be more polygons for more sub-blocks. Here, we are using layer 400 for the instance boxes. We will put the ERC error markers in another .tcl file (‘Err.tcl’) with layer 401. As a result, we separate the two entities in .tcl space. This scheme of separating the cell polygons from error polygons in .tcl space inside the foreach looping is represented in Figure 5. We will now discuss some details of generating the ‘Err.tcl’ file in Step 5.
Fig. 5:The algorithm separates the cell polygons from error polygons in .tcl space
Step 5. Once the sub-blocks are exhausted, we do the error types (from ERR_list) in the 'subcell_list'. For each error type, we parse the ERC_COMB.db to sense the check name, followed by the error markers until it hits the next check in the database. In this phase, we create the second .tcl file (‘Err.tcl’) mentioned in Step 4 that contains the error polygons/wires, depending on polygon/edge results in ERC_COMB.db.
for polygon DRC/ERC data:
$L1 create polygon FULLCHIP 401 <error polygons coords>
$L1 create polygon FULLCHIP 401 <next error polygons coords>
$L1 create polygon FULLCHIP 401 <next error polygons coords>
and so on.
or edge DRC/ERC data:
$L1 create edge FULLCHIP 401 <error edge coords>
$L1 create edge FULLCHIP 401 <next error edge coords>
$L1 create edge FULLCHIP 401 <next error edge coords>
and so on. Note that we give a 5-nm width to the edges for later ANDing.
Once all the polygons/edges are exhausted for the particular error type (loop variable), we combine the two .tcl files of Step 4 (‘Cells.tcl’) and Step 5 (‘Err.tcl’) to produce a single .tcl file (‘run_splitter.tcl’) , as shown in Figure 6, for an error type ‘ppvdd150’.
Fig. 6: For each error type, we generate a combined .tcl file such as this
When the resulting file (‘run_splitter.tcl’) is run in calibreDRV, it produces a GDS output called the 'filtered_error_type.gds' that contains the “filtered” errors in GDS format; for example, 'filtered_ppvdd150.gds' for the error type 'ppvdd150' in ERC.db. The combined .tcl code puts out the ANDed (“filtered”) polygons in layer 402 ($L1 AND 400 401 402).
During this phase (loop variable being an error type), we also create a Calibre SVRF code that would read in the 'filtered_error_type.gds' and translate it into ASCII database format. The SVRF code ('run_splitter.cal') generated on the fly by the Perl routine appears in this way:
LAYOUT PATH filtered_ppvdd150.gds
LAYOUT PRIMARY FULLCHIP
LAYOUT SYSTEM GDSII
DRC RESULTS DATABASE filtered.ppvdd150.db
DRC SUMMARY REPORT filtered.ppvdd150.rep
DRC MAXIMUM RESULTS ALL
DRC CHECK TEXT ALL
DRC KEEP EMPTY NO
LAYER CHK_LAYER 402
PRECISION 1000
RESOLUTION 5
ppvdd150 { @ gate1 connected to POWER
COPY CHK_LAYER }
So for each check name (error_type) selected in 'ERR_list', we get a “filtered” ASCII database and summary file: filtered.error_type.db, filtered.error_type.rep. Notice that we are picking up the layer 402 from the .tcl output GDS.
Step 6. Once the outer loop of the 'subcell_list' (subblock_list + ERR_list) is exhausted, we simply combine the several 'filtered.error_type.db', 'filtered.error_type.rep' files generated in Step 5 to produce the combined 'filtered_erc.db' and 'filtered_erc.rep.' This reflects the “filtered” results for all selected subblocks and checks.
CONCLUSION
In this article we have discussed a Perl, CalibreDRV .tcl, and Calibre SVRF-based scheme for filtering DRC/ERC results from a full-chip Calibre result down to the sub-blocks space in the full-chip context, and even to the coordinate system of individual cells or IPs. The methodology is simple to use and all the components can be integrated into a single script.
The special feature of this algorithm is that full-chip DRC/ERC is run only once, saving long runtimes associated with running window-based runs several times for different combination of window selections, and then split the results with a Perl script (driver) into user-specifiable sub-block spaces for user-specifiable checks. We have also shown a simple shell script for translating the single sub-block results in the full-chip context to the coordinate system of the sub-cell. Thus, you can then transfer the results to a sub-cell developer or a IP vendor for analysis.
ACKNOWLEDGEMENT
The authors would like to acknowledge the helpful support for this work provided by Moazzem Hossain of Fastrack Design and Syed Ahmed of PLX Technology.
***
** Due to technical issues in reading the paper on Electronic Design, the original manuscript (slightly older than the one published on Electronic Design) routed through Mentor Graphics is pasted here. The paper was based on my earlier work at AMD
Correct-by-Construct Layout Generation and Modification
By Arya Raychaudhuri, Ikanos
INTRODUCTION
Physical design verification software typically identifies faults in physical layouts by finding design rule check (DRC) violations and layout-versus-schematic (LVS) mismatches after layout is complete. Correct-by-Construct is a method for generating and modifying polygonal features during the layout construction process so that the layout satisfies both design rule constraints and connectivity requirements. Whether the design is flat or hierarchical, Correct-by-Construct polygon processing techniques can be used to check and verify that construction is proceeding correctly.
Developing formal approaches to ensure Correct-by-Construct allows physical verification software to move from merely fault-finding into physical design generation and modification, expanding the capabilities and usefulness of existing software. Beyond layout accuracy, however, Correct-by-Construct can be used in conjunction with polygon processing techniques to provide very strong solutions for automated layout construction and improvement.
This article describes the use of Correct-by-Construct in the construction of a ground plane and its associated power/ground grids. The power features are added onto an existing layout using a TCL scripting language, and the generation and mounting tasks are managed with a Perl driver. For this project, we employed a combination of Mentor Graphics Calibre nmDRC™ (to provide the polygon management) and the TCL and advanced merge features of Mentor Graphics Calibre DESIGNrev™ (to provide the database handling), supplemented with Perl (for general-purpose data and string processing). Calibre nmDRC and Calibre DESIGNrev together provide the complementary polygon processing capabilities required by Correct-by-Construct.
CORRECT-BY-CONSTRUCT TECHNIQUES
Broadly, there are two types of layout generation or modification: Flat and Hierarchical. In flat layouts, database manipulation is not needed. However, polygon processing features are exercised to deliver Correct-by-Construct flat layout cells. Whether the layout is a very complicated ground/power plane, or something as simple as a p-cell, the goal is always to ensure the layout is constructed correctly, yet can be easily reconfigured with a different set of starting parameters.
In the case of hierarchical construction, intricate database manipulation often takes center stage, because not only must the generated or modified layout be DRC/LVS correct, but its addition to the existing layout should not break the structural configurations of the leaf cells or the existing hierarchies. Polygon management alone cannot manage all of these stringent requirements, which is why we use a TCL with advanced geometry-sensitive layout database manipulation features, such as cell selective reference expansion, iterative cell reference deletion, etc. For example, a selective reference expansion scheme avoids breaking leaf cell structures during a metal subtypes change procedure.
FLAT LAYOUT CONSTRUCTION: THE GROUND PLANE PROJECT
The ground plane facilitates the supply of low IR drop electrical ground to the active devices (transistors) from a perforated metallic plane. This plane is normally built with a metal layer located above the routing metal layers for the subcells, typically, Metal5 or Metal6. An IR analysis verifies IR drop compliance.
The ground plane also serves as a capacitive shield for the signal lines and is perforated with staggered arrays of cheesing holes to comply with metal density requirements. Staggering the perforations helps prevent current channeling and formation of inductive loops, and the holes break up the wide metal regions requiring wider design rule spacings. In addition to the cheesing perforations, other holes must be created by the program to let VDD, clock, and signal nets pass through. Figure1 shows the different types of holes and islands programmed into the ground plane.
Fig. 1: Ground plane with staggered cheesing holes, and holes to accommodate VDD and Signal connection islands.
Signal routing (using ground plane metal) that eventually passes through the ground plane's signal connection islands is normally restricted to available channels that are design-rule-safe with respect to the periodic VDD, VSS, and Clock lines. In Correct-by-Construct, the ground plane with the holes and islands is connected to VSS lines below and above the ground plane, using the maximum number of vias that can be placed without breaking the design rules. Even the VDD and Clock lines below and above the plane are connected through the connection islands. The periodic placement of the VDD, VSS, and clock lines or straps, and all via placements, are also controlled by the ground plane generating program.
For some special electrical requirements, if the pre-existing routing connections are placed outside the restricted channels, or there are pre-existing VDD, VSS, and clock lines in non-periodic locations, the Correct-by-Construct program should bypass those features on the layout, and place the new straps in a DRC-correct way.
Figure 2 illustrate how the generated ground plane handles some of these complexities. Connection holes are created for the signals and VDD lines. Via islands are also created for the VDD connections. The maximal via filling for VSS straps is put into effect. Figure 2 also demonstrates the automated interruption of program-generated vertical VDD/VSS straps from above to accommodate off-channel routings and straps below.
Fig. 2: Ground plane accommodating complex routings and straps placements. Some of the bigger holes are created by the Correct-by-Construct program to reduce wide metal regions and to avoid wide metal errors.
A typical ground plane generation techfile is built up in a number of Correct-by-Construct development steps. These are the Correct-by-Construct steps for development of a plane (Metal5) and straps (Metal6 – Metal9):
1. Create the staggered perforations
2. Create Metal6 VSS and VDD straps
3. Subtract existing Metal6 materials in a DRC-correct way
4. Create DRC correct exclusions for existing Via4 – Via8
5. Create DRC correct exclusions for existing Metal5 materials
6. Create the Metal6 – Metal4 VDD connects
7. Create exclusions for existing and new Signal/Clock/VDD connects
8. Adjust the set of staggered perforations with the exclusions
9. Create DRC-correct ground plane and reduce wide metal regions
10. Create DRC-correct vias to the Metal4 VSS straps
11. Create DRC-correct vias to the Metal6 VSS straps
12. Create Metal7 VSS and VDD straps
13. Subtract existing Metal7 materials in a DRC-correct way
14. Create Metal8 VSS and VDD straps
15. Subtract existing Metal8 materials in a DRC-correct way
16. Create Metal9 VSS and VDD straps
17. Subtract existing Metal9 materials in a DRC-correct way
18. Create DRC correct maximal Via6-Via8, obeying existing exclusions
19. Check all vias (existing and created) for stress vias
20. Delete any stress vias from the set of generated vias
21. Output all generated metals and vias into a flat GDS database
If this GDS database is named cell_name_ground_plane.gds (derived from the original cell database cell_name.gds), the ground plane can be mounted on the cell using TCL code such as:
#!/usr/bin/tclsh
set L1 [layout create "cell_name.gds"]
set L2 [layout create "cell_name_gnd_plane_only.gds"]
$L2 cellname cell_name cell_name_gnd
$L1 import layout $L2 FALSE append
$L1 create ref cell_name cell_name_gnd 0 -0.215 0 0 1
$L1 gdsout "cell_name_with_gnd_plane.gds"
Once done with generation and mounting, the final database (cell_name_with_gnd_plane.gds) is tested for DRC, ERC, and LVS correctness of construction.
A Correct-by-Construct generation must also meet IR drop requirements and mask printability requirements to be viable. To ensure compliance with these requirements, the generation should be modular and driven by a simple set of perforations and straps periodicity (pitch/width/spacing) parameters. Normally, this is accomplished by driving the generation from a file of variables, where you simply change the variables to generate a slightly different plane for better compliance. This ground plane parameters file makes the generation programmable.
CORRECT-BY-CONSTRUCT CONSIDERATIONS
The important emphasis on Correct-by-Construct in the generation process is to ensure that each of the 21 steps in the generation techfile is DRC and LVS correct. In addition, the proper sequencing of the steps is important for a clean design. Continuously check and correct for slivers, narrow necks, wide metal regions, improper via enclosures, unwanted intersections, or proximity with existing materials, etc. At the end of the generation process, only the more complicated metal stress via errors remain. Devote a section of the generation techfile to finding those errors, and then removing all generated vias that have stress via errors. Since via generation is maximized, even for wrong-way metals (for example, a horizontal metal strap in Metal6 where the routing direction is vertical), appropriate application of the rectangles construct ensures that not too many vias are lost in stress vias correction.
The parameters-driven staggered perforations scheme should first be tested for maximum metal density violations. If the DRC-correct perforations are too small or too far apart, they can lead to maximum metal density violations or too many wide metal regions. Apply proactive OPC checking to avoid mask printability issues later on. These considerations drive the selection of the size, spacing, and offset of the ground plane perforations defined in the ground plane parameters file. Figure 1 shows that the stagger is not applied to the peripheral columns and rows of the plane. This is intentional to ensure smooth transitions from the plane of one layout sub-block to that of another, even when some blocks may be rotated before placement. Sub-block sizes are restricted to integral multiples of standard cells sizes. This restriction ensures continuity of straps and ground plane from one block to another.
The power/ground metal strap widths and pitches are pre-defined in the ground plane parameters file. Select these widths and pitches based on standard cell VDD/VSS pitches, as well as IR drop considerations. Once the straps pitch grid is selected, compute the allowable DRC-correct routing channels for any block, and use that information proactively in sub-blocks routing and implementation to ensure the ground plane generation does not conflict too much with existing routing.
HIERARCHICAL LAYOUT CORRECTION: SELECTIVE REFERENCE EXPANSION
The ground plane project is an example of intricate flat construction, where the correctness of construction applies only in the flat sense. However, designers often have to deal with hierarchical layout, such as changing some features of metallization based on net identities of metals in a hierarchical layout.
One good example is metals subtypes correction. In complex custom designs, designers often deal with multiple power supply voltages, clock nets, ground supply, and signal nets, all on any particular metal layer. In such situations, it is often advantageous to use different layout layers for nets used for different purposes. For example, VDD, VDDX, VDDY, VSS, CLK, and Signal metals could use different metal subtypes in layout. In this scheme, for any particular metal layer (e.g., Metal4), we have subtypes such as VDD04, VDDX04, VDDY04, VSS04, CLK04, and Sig04 represented by different data layers in the layout. This scheme not only helps visualize the different nets of a complex layout, it also helps in developing layout debug software, such as a shorts isolator program. All the different subtypes with an 04 suffix are processed as a single metal layer (Metal4 in this case) at the mask-making stage and for physical design verification purposes.
However, layout designs originating in different design groups of an organization often do not strictly adhere to the metal subtyping mentioned above. Sometimes layout blocks are designed with the wrong metal subtypes, for example, VSS04 used in parts of VDD net in Metal4, or Sig04 used for VSS net, etc. A Correct-by-Construct solution can be used to automatically detect wrong subtypes and replace them with proper subtypes. This solution requires that the layout block to be corrected is properly texted and LVS-correct to start. In principle, this is a straightforward process to identify the wrong metal subtypes with the NET construct. For example,
BAD_Sig04_VDD = Sig04 NET “VDD”
identifies the Sig04 metal subtype used wrongly on “VDD” net. Similarly, we can get wrong Sig04 on nets other than signal nets, and finally,
GOOD_Sig04 = ((((Sig04 NOT BAD_Sig04_VDD)
NOT BAD_Sig04_VSS)
NOT BAD_Sig04_VDDX) NOT BAD_Sig04_VDDY)
NOT BAD_Sig04_CLK
This way, BAD_ and GOOD_ of all metal subtypes are computed for all metal layers. They are output into a GDS database, with BAD_s assigned a layer number that maps to the layer number of the net where the error was detected. For example, if the layer number of VDD04 in the original layout was 64, BAD_Sig04_VDD is output into layer number 5064 from the techfile. Bumping up the value of the layer number by 5000 provides a convenient value well above the maximum layer number used in the original database. In addition, the GOOD_s are output to a layer number that maps to the layer number of the proper subtype. For example, if Sig04 in the original database had a layer number of 100, the GOOD_Sig04 is output to 5100 from the techfile. For example,
BAD_Sig04_VDD {COPY BAD_Sig04_VDD}
GOOD_Sig04 {COPY GOOD_Sig04}
DRC CHECK MAP BAD_Sig04_VDD 5064 //If VDD04 is 64 in input
DRC CHECK MAP GOOD_Sig04 5100 //If Sig04 is 100 in input
and so on for other subtypes and metal layers.
If HCELL cell_1 cell_1 through HCELL cell_n cell_n is used for all cells in the database in this DRC techfile, the data should be output in a proper hierarchical distribution of the cells and subcells. Simple TCL code can then incorporate the data from the run into the original database. If the original database is testcase.gds, the output of the metal subtypes identifying techfile can be testcase_metal_diag.gds. The TCL code that handles layers 5064 and 5100 looks like this:
#!/usr/bin/tclsh
set L1 [layout create "testcase.gds"]
set L2 [ layout create "testcase_metal_diag.gds”]
$L1 import layout $L2 FALSE append
if [$L1 exists layer 5100] {
$L1 delete layer 100
$L1 COPY 5100 100
$L1 delete layer 5100
}
if [$L1 exists layer 5064] {
$L1 COPY 5064 64
$L1 delete layer 5064
}
$L1 gdsout "testcase_with_new_metal.gds"
This code simply maps the bumped-up layers back to the original layer. This way, the entire database is corrected with the results of the diagnostic techfile, for all subtypes in all metal layers.
SELECTIVE REFERENCE EXPANSION
There are still some issues to be resolved with the above procedure. For cells with multiple instances, where a particular metal subtype occurs on different nets in different instances, the above procedure corrects that metal differently in each instance and moves the corrected metal subtype one level up, leaving the cell saved without the metal. This means the leaf cell or subcell structure is broken in the corrected database with respect to the original database. This issue of “conflictingly connected” instances can be addressed in two ways:
1. Do not correct those cells in the database.
2. Selectively expand only those instances where the metal subtype is on a wrong net.
The second method is more interesting because it involves a more intricate application of TCL.
In our case, we have numerous instances of via cells used in the layout. All these via cells are in the shape of a cross between signal metals and a via sandwiched at the center. As shown in Figure 3, a Via01 cell is made of a crossing between Sig01 and Sig02 with a V01 at the center
Fig. 3: The layout of a standard Via01 cell with Sig01 on the bottom, Sig02 on top, and V01 in the middle.
The Via01 cell shown above is used freely for signal nets, as well as VDD, VSS, or any other special nets, so it is an example of a conflictingly connected cell. If we follow the procedure discussed earlier, the cell will be broken up and saved in the final corrected database with just the V01 in it. That is, the leaf cell structure would be broken. A procedure is needed to identify those via cells that are connected to special (non-signal) nets and to expand (flatten) their contents to add to the cell where they have been instantiated. If the metal subtypes correction procedure discussed above is applied on the database with selectively expanded via cells, the correction no longer breaks the via leaf cells.
The selective expansion procedure needs to be perfect, because if even a single via cell on a special net (non-signal net) remains unexpanded, the subsequent metal subtypes correction will break the leaf cell. To accomplish this, a two-step procedure involving a techfile identifies the BAD_Via0x (where “x” stands for Via level) cell extents that interact with the various “special” nets (VDD, VSS, CLK, VDDX, VDDY). However, this is not enough because the software works on polygons and will report only one BAD_Via0x cell for multiple coincident (in space) placements in the hierarchical direction. If it reports a BAD_Via0x in such situations, the BAD_Via0x will be associated with only one of the parent cells where the Via cell is instantiated. If that BAD_Via0x polygon is used in subsequent TCL as the sole basis for selection of the Via0x instances for expansion, the other Via0x cell that was sitting on top of it and instantiated from another parent cell would remain unexpanded.
To circumvent this situation, we need not only the BAD_Via0x as the basis of selective expansion (because it takes care of most selections in a correct way), but also the special net metals surrounding an expansion candidate. Accomplish this in TCL by reading in the original layout database, and calculating the OR (Boolean function) of the special subtypes read in for each layer. Call it “spnets_or_0x,” where “x” stands for the metal level. In contrast to the BAD_Via0x entities obtained with the run, spnets_or_0x is not collapsed to one of the multiple cells when coincident placements occur.
However, because a Via0x cell can interact with either a “spnets_or_0x” entity or a “spnets_or_0x+1” entity, a Boolean OR of “spnets_or_0x” and “spnets_or_0x+1” forms the geometric basis of expansion. Combine the “net” basis of expansion, namely, BAD_Via0x, and the geometric basis of expansion into a single basis of expansion, ALL_ BAD_Via0x, where:
ALL_ BAD_Via0x = BAD_Via0x OR (spnets_or_0x OR spnets_or_0x+1)
In the TCL code, first form this basis of selective expansion for all metal and via layers after reading in the original database, and the results of the run. Then, for each cell, look for references that match in name with Via0x cells. If the match is found, create a small polygon at the centre of the matched reference. Then Boolean AND this polygon with the ALL_ BAD_Via0x entity. If the intersection is positive, the Via0x cell is expanded, and its contents added to the parent cell.
Did we miss anything? What if the geometric basis of expansion obtained from spnets_or_0x OR spnets_or_0x+1 failed to pick up an expandable reference because Sig0x metal was wrongly used on a special net near a Via cell? This situation can be avoided by also obtaining the entities such as BAD_Sig0x_<special_net> from the pre-run, along with the BAD_Via0x extents. The BAD_Sig0x_<special_net> entities can be recognized from the wrong metals diagnostic in the techfile, so simply add that feature to this selective expansion pre-run techfile to put out those entities as well as BAD_Via0x. Then, in the TCL code, add these new entities to the selection basis:
ALL_ BAD_Via0x_new
= ALL_BAD_Via0x OR (BAD_Sig0x OR BAD_Sig0x+1)
where the BAD_Sig0x is the Boolean OR of all the separate BAD_Sig0x_<special_net> entities (BAD_Sig0x_VDD, BAD_Sig0x_VSS, and so on).
Once done with the selective expansion, create an intermediate database (GDS) with selectively expanded via cells. This intermediate database becomes the input to the metal subtypes correction procedure. Ensure the hierarchical correctness of the process by a cell-by-cell XOR of the corrected database with respect to the original database. The XOR should be null for all layers, as well as for the Boolean OR of the metal subtypes.
An example of the correction of a leaf cell is shown in Figure 4. On the left is the metallization of the cell before the subtypes correction was applied, and on the right is the same cell after correction. Along with the subtypes correction, there is an effect of metals merging that cleans up the layout to some extent. For example, the Sig01 (green) metal on the left has pieces put together to form clean single polygons on the right. This is an added benefit of the correction process.
Fig. 4: The metallization of a small leaf cell before and after metal subtypes correction.
CONCLUSION
This project explored some of the intricacies involved in flat and hierarchical construction. For the tasks involved in flat construction, geometric design rule issues are of primary concern. For hierarchical construction, layout database issues are of greater importance. Exploiting the programmability of existing EDA software can create a generalized Correct-by-Construct tool for all types of automated layout generation and correction.
ACKNOWLEDGEMENTS
I would like to sincerely acknowledge the contributions of James Paris of Mentor Graphics in helping develop TCL code for instance-specific layout editing using Calibre DesignREV generic commands. I would also like to acknowledge Lata Valluri, Gene Forte, and very specially Shelly Stalnaker of Mentor Graphics for taking interest in this work.
***
Arya Raychaudhuri
The papers on this page are not proprietary to LVS DEBUG SOLUTIONS LLC. I had earlier published them elsewhere. I have reproduced the original manuscripts here so that readers can read them more easily and in one place.
Copyright 2011 LVS DEBUG SOLUTIONS & 2012 LVS DEBUG SOLUTIONS LLC All rights reserved.
LVS DEBUG SOLUTIONS LLC
980 Kiely Blvd, Unit 308
Santa Clara, CA 95051
United States
ph: 1-408-480-1936
arya