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 BEGINIF (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 BEGINs = 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 BEGINnVertices = 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 BEGINnVertices = 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 BEGINregion 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 BEGINIF (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 BEGINIF (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 BEGINi=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.