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:


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 (''). 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.

We also can show the filtered ERC results \\[Figure 2\\] obtained by running 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.

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.

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 '', running the tcl code will give us the sub-block's placement details. For example,

calibredrv -64 |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\\}*\\]' > 
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\\].

The Algorithm

The algorithm of the Perl routine 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 ) 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. We can show in a diagram this scheme of separating the cell polygons from error polygons \\[Figure 5\\] in Tcl space inside the foreach looping. We will now discuss some details of generating the ‘Err.tcl’ file in Step 5.

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
$L1 create polygon FULLCHIP 401
$L1 create polygon FULLCHIP 401

and so on.

For edge DRC/ERC data:

$L1 create wire FULLCHIP 401 5
$L1 create wire FULLCHIP 401 5
$L1 create wire FULLCHIP 401 5

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’) \\[Figure 6\\] for an error type ‘ppvdd150.’ 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 ('') generated on the fly by the Perl routine appears in this way:

LAYOUT PATH filtered_ppvdd150.gds
DRC RESULTS DATABASE filtered.ppvdd150.db
DRC SUMMARY REPORT filtered.ppvdd150.rep
ppvdd150 \{ @ gate1 connected to POWER

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.


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.


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.