Advanced Layout Editing Using XI-scripts

To provide uniform etching of metal, dummy metal rectangles can be placed over an unused area of the chip.
The following script generates dummy layer with a full array of metal rectangles over the whole cell area. It calls DRC script <dummy.dsf> which sizes the real metal layout up by 2 µm and subtracts it from the dummy layer. Then the dummy layer sized up and down to remove any slivers left over from the subtraction phase.

Resultant dummy layer can be added to real metal in current cell or copied into a new cell.

Xs = 4.0; ! X size of dummy    metal box
   Ys = 10.0; ! Y size of dummy metal box
   dist = 10.0; ! spacing between dummy boxes
C1 = get_edited_cell_name();
   bb = get_cell_bbox(C1);
IF ((layer_exists("DummyM5"))    NEQ TRUE) 
   THEN (new layer "DummyM5");
layer DummyM5;
   SepX = Xs + dist;
   SepY = Ys + dist;
   nRow = (bb.ysize + Ys)/(SepY);
   nCol = (bb.xsize + Xs)/(SepX);
PosX = bb.xpos;
   PosY = bb.ypos;
   iBoxY = 1;
   LOOP BEGIN
   IF (iBoxY GTR nRow) THEN (LEAVE LOOP);
iBoxX = 1;
 LOOP BEGIN
IF (iBoxX GTR nCol) THEN        (LEAVE LOOP);
       box (PosX) (PosY) (Xs) (Ys);
       PosX = PosX + SepX;
       iBoxX = iBoxX + 1;
END;
PosY = PosY + SepY;
   PosX = 0;
   iBoxY = iBoxY + 1;
   END;
   drc script ("D:/DRC/dummy.dsf") /whole /flat;
   select 
   delete layer "DummyM5";
   delete layer "DMet";
 --------------- < dummy.dsf>    ---------------------
OverSize: Value=2um, Layer=Metal5,    LayerR=&ovMet(0);
   Dif: Layer1=DummyM5, Layer2=&ovMet, LayerR=&Dummy(0);
   UnderSize: Value=1um, Layer=&Dummy, LayerR=&tmp(0);
   OverSize: Value=1um, Layer=&tmp, LayerR=DMet(0);
   Or: Layer1=DMet, Layer2=Metal5, LayerR=&M5new(0);
   // Copy: Layer=&M5new, LayerR= Metal5 (0); 
   // Dummy metal boxes will be added to layer 
"Metal5" in current cell


Figure 1. Dummy metal boxes added to layer "Metal5" in current cell.

 

To increase the surface breakdown of a structure the high field emission points must be eliminated. This can be achieved by rounding the corners of any orthogonal mask shape (radius should exceed the junction depth of the diffusion to increase considerably the breakedown voltage of the shallow junction).

Rounded corner shapes can be created in Expert with "Rolled Region" tool or with XI script.

The following script rounds each corner of selected orthogonal polygons. Both inside and outside corners will receive fillets.

 

----------- <round_corner.xis>    ---------------------
   DEFINE PROCEDURE "point_distance" /REPLACE
PARAMETER pt1
     PARAMETER pt2
     DO BEGIN
s = abs(pt1.x - pt2.x);
       IF (s EQL 0.0) THEN (s = abs(pt1.y - pt2.y));
       RETURN (s);
END;
DEFINE PROCEDURE "get_next_vertex"    /REPLACE
PARAMETER vertices
     PARAMETER cur_idx
     DO BEGIN
nVertices = vertices.size;
       IF (cur_idx EQL nVertices) 
THEN (RETURN (vertices[1])) ELSE (RETURN (vertices[cur_idx + 1]));
END;
DEFINE PROCEDURE "get_prev_vertex"    /REPLACE
PARAMETER vertices
     PARAMETER cur_idx
     DO BEGIN
nVertices = vertices.size;
       IF (cur_idx EQL 1) THEN (RETURN 
(vertices[nVertices ])) ELSE (RETURN (vertices[cur_idx - 1]));
END;
DEFINE PROCEDURE "round_corner"    /REPLACE
PARAMETER pt_prev
     PARAMETER pt
     PARAMETER pt_next
     PARAMETER radius
     PARAMETER layer_name
     DO BEGIN
     x = pt.x;
     y = pt.y;
     IF (pt_prev.y GTR pt.y AND pt_next.x GTR pt.x)
THEN BEGIN
region mode /hole;
         box (x) (y) (radius) 
(radius) /layer=(layer_name); region mode /merge; ellipse (x+radius) (y+radius)
(radius) (radius) /layer=(layer_name); region mode /normal;
END
   ELSEIF (pt.x GTR pt_prev.x AND pt_next.y GTR pt.y)
THEN BEGIN
region mode /hole;
       box (x-radius) (y) (radius) 
(radius) /layer=(layer_name); region mode /merge; ellipse (x-radius) (y+radius)
(radius) (radius) /layer=(layer_name); region mode /normal;
END
   ELSEIF (pt.y GTR pt_prev.y AND pt.x GTR pt_next.x)
THEN BEGIN
region mode /hole;
       box (x - radius) (y-radius) 
(radius) (radius) /layer=(layer_name); region mode /merge; ellipse (x - radius) (y-radius)
(radius) (radius)/layer=(layer_name); region mode /normal;
END
   ELSEIF (pt.y GTR pt_next.y AND pt_prev.x GTR pt.x)
THEN BEGIN
region mode /hole;
       box (x) (y-radius) (radius) 
(radius) /layer=(layer_name); region mode /merge; ellipse (x+radius) (y-radius)
(radius) (radius) /layer=(layer_name); region mode /normal;
END
   ELSEIF (pt.x GTR pt_prev.x AND pt.y GTR pt_next.y)
THEN BEGIN
region mode /merge;
       box (x-radius) (y-radius) 
(radius) (radius) /layer=(layer_name); region mode /hole; ellipse (x-radius) (y-radius)
(radius) (radius) /layer=(layer_name); region mode /normal;
END
   ELSEIF (pt.y GTR pt_prev.y AND pt_next.x GTR pt.x)
THEN BEGIN
 region mode /merge;
       box (x) (y-radius) (radius) 
(radius) /layer=(layer_name); region mode /hole; ellipse (x+radius) (y-radius)
(radius) (radius) /layer=(layer_name); region mode /normal;
END
   ELSEIF (pt_prev.x GTR pt.x AND pt_next.y GTR pt.y)
THEN BEGIN
region mode /merge;
       box (x) (y) (radius) 
(radius) /layer=(layer_name); region mode /hole; ellipse (x+radius) (y+radius)
(radius) (radius) /layer=(layer_name); region mode /normal;
END
   ELSEIF (pt_prev.y GTR pt.y AND pt.x GTR pt_next.x)
THEN BEGIN
region mode /merge;
       box (x-radius) (y) (radius) 
(radius) /layer=(layer_name); region mode /hole; ellipse (x-radius) (y+radius)
(radius) (radius) /layer=(layer_name); region mode /normal;
END
END;
DEFINE procedure/replace "round_pol_corner"
   parameter obj
   parameter radius
   DO BEGIN
IF( obj.shape NEQ "Polygon")        
THEN (RETURN("This object is not Polygon!")); vertices = obj.coords; nVert = vertices.size;
i =1;
LOOP BEGIN
IF (i GTR nVert) THEN (LEAVE LOOP);
       pt = vertices[i];
       pt_next = get_next_vertex(vertices, i);
       IF (pt.x NEQ pt_next.x AND
       pt.y NEQ pt_next.y) 
       THEN (RETURN("Nonortogonal polygon encontered"));
       IF (point_distance(pt, pt_next) / 2 LSS radius)
       THEN (RETURN("Too big radius value"));
       i = i + 1;
END;
i = 1;
layer_name = obj.layer;
     LOOP BEGIN
IF (i GTR nVert) THEN (LEAVE LOOP);
       pt = vertices[i];
       pt_next = get_next_vertex(vertices, i);
       pt_prev = get_prev_vertex(vertices, i);
       round_corner(pt_prev, pt, pt_next, 
radius, layer_name); i = i + 1;
END;
     RETURN NIL;
END;
DEFINE command/replace "round_object_corner";
   DEFINE action
   parameter radius
   DO BEGIN
objseq = search(SEARCH_REGION, {},      
WHOLE_CELL,
CROSS_RECT, SEARCH_SELECTED, SEARCH_VISIBLE); display ("Selected " &objseq.size &" objects" ); i=0; LOOP BEGIN
i=i+1;
    if (i GTR objseq.size) then (leave LOOP);
    ret = round_pol_corner(objseq[i], radius);
    IF (ret NEQ NIL) THEN (display(ret));
END;
END;
   DEFINE argument radius/COERCE=
(DOUBLE)/positional/is_default/
value_required;complete command;

 

Figure 2. Boxes on the right were selected, then command
round_object_corner 0.5 was executed.