Hi,
I am trying to create a circle in my layout with smallest possible resolution (PDK suggests 5 nm). For this, I used the SKILL code posted before on this forum. The code works for the radius 1 um and grid size 5 nm and the shape passes the DRC. But I need the circle to be designed for atleast a 20 um radius(circle shown in circle 1um.png). When I try to do this for the 20 um radius (circle 20 um.png), I get a circle chopped off into sectors and the DRC fails. I am new to SKILL and I do not undertsand the reason behind this. Can someone please help me understand this issue and provide a solution that works for 20 um radius without theDRC errors.
The skill code for generating the circle is...
Direction
5 6 7
\ | /
4 - O - 0
/ | \
3 2 1
--- Using it ---
You'll need to modify the call to pcDefinePCell() below to specify your
preferred library/cell names and possibly the default radius, grid and layer.
Once you've done that just use 'load("/path/to/circlePcell.il")' in the CIW or
the libInit.il file for your library.
*/
(defun RALgetNextPoint (direction X Y grid radius)
(let (X0 Y0 R0 D0 X1 Y1 R1 D1 X2 Y2 R2 D2 X3 Y3 R3 D3 X4 Y4 R4 D4
X5 Y5 R5 D5 X6 Y6 R6 D6 X7 Y7 R7 D7 ret)
(if direction == 0 || direction == 1 || direction == 7 then
(X0 = X + grid)
(Y0 = Y)
(R0 = (X0**2 + Y0**2)**0.5)
(D0 = (abs R0 - radius)))
(if direction == 1 || direction == 2 || direction == 0 then
(X1 = X + grid)
(Y1 = Y - grid)
(R1 = (X1**2 + Y1**2)**0.5)
(D1 = (abs R1 - radius)))
(if direction == 2 || direction == 3 || direction == 1 then
(X2 = X)
(Y2 = Y - grid)
(R2 = (X2**2 + Y2**2)**0.5)
(D2 = (abs R2 - radius)))
(if direction == 3 || direction == 4 || direction == 2 then
(X3 = X - grid)
(Y3 = Y - grid)
(R3 = (X3**2 + Y3**2)**0.5)
(D3 = (abs R3 - radius)))
(if direction == 4 || direction == 5 || direction == 3 then
(X4 = X - grid)
(Y4 = Y)
(R4 = (X4**2 + Y4**2)**0.5)
(D4 = (abs R4 - radius)))
(if direction == 5 || direction == 6 || direction == 4 then
(X5 = X - grid)
(Y5 = Y + grid)
(R5 = (X5**2 + Y5**2)**0.5)
(D5 = (abs R5 - radius)))
(if direction == 6 || direction == 7 || direction == 5 then
(X6 = X)
(Y6 = Y + grid)
(R6 = (X6**2 + Y6**2)**0.5)
(D6 = (abs R6 - radius)))
(if direction == 7 || direction == 0 || direction == 6 then
(X7 = X + grid)
(Y7 = Y + grid)
(R7 = (X7**2 + Y7**2)**0.5)
(D7 = (abs R7 - radius)))
(caseq direction
(0
/* Possible 7 0 1 */
(if D0 < D1 && D0 < D7 then
/* Go D0 */
(ret = (list X0 Y0 0))
else
(if D1 < D0 && D1 < D7 then
/* Go D1 */
(ret = (list X1 Y1 1))
else
/* Go D7 */
(ret = (list X7 Y7 7))
)
)
)
(1
/* Possible 0 1 2 */
(if D1 < D2 && D1 < D0 then
/* Go D1 */
(ret = (list X1 Y1 1))
else
(if D2 < D1 && D2 < D0 then
/* Go D2 */
(ret = (list X2 Y2 2))
else
/* Go D0 */
(ret = (list X0 Y0 0))
)
)
)
(2
/* Possible 1 2 3 */
(if D2 < D3 && D2 < D1 then
/* Go D2 */
(ret = (list X2 Y2 2))
else
(if D3 < D2 && D3 < D1 then
/* Go D3 */
(ret = (list X3 Y3 3))
else
/* Go D1 */
(ret = (list X1 Y1 1))
)
)
)
(3
/* Possible 2 3 4 */
(if D3 < D4 && D3 < D2 then
/* Go D3 */
(ret = (list X3 Y3 3))
else
(if D4 < D3 && D4 < D2 then
/* Go D4 */
(ret = (list X4 Y4 4))
else
/* Go D2 */
(ret = (list X2 Y2 2))
)
)
)
(4
/* Possible 3 4 5 */
(if D4 < D5 && D4 < D3 then
/* Go D4 */
(ret = (list X4 Y4 4))
else
(if D5 < D4 && D5 < D3 then
/* Go D5 */
(ret = (list X5 Y5 5))
else
/* Go D3 */
(ret = (list X3 Y3 3))
)
)
)
(5
/* Possible 4 5 6 */
(if D5 < D6 && D5 < D4 then
/* Go D5 */
(ret = (list X5 Y5 5))
else
(if D6 < D5 && D6 < D4 then
/* Go D6 */
(ret = (list X6 Y6 6))
else
/* Go D4 */
(ret = (list X4 Y4 4))
)
)
)
(6
/* Possible 5 6 7 */
(if D6 < D7 && D6 < D5 then
/* Go D6 */
(ret = (list X6 Y6 6))
else
(if D7 < D6 && D7 < D5 then
/* Go D7 */
(ret = (list X7 Y7 7))
else
/* Go D5 */
(ret = (list X5 Y5 5))
)
)
)
(7
/* Possible 6 7 0 */
(if D7 < D0 && D7 < D6 then
/* Go D7 */
(ret = (list X7 Y7 7))
else
(if D0 < D7 && D0 < D6 then
/* Go D0 */
(ret = (list X0 Y0 0))
else
/* Go D6 */
(ret = (list X6 Y6 6))
)
)
)
)
ret
))
pcDefinePCell(list(ddGetObj("ph90wg") "disk1" "layout")
((Radius float 1.0) (Grid float 0.005) (Layer string "RX"))
let(( pcParameters pcParamProp pcLayer pcPurpose polyList
X Y direction ret cheese points)
(pcParameters = ((pcCellView~>parameters)~>value))
(pcParamProp = car(exists(prop pcParameters ((prop~>name) == "Radius"))))
(Radius = (pcParamProp~>value))
(pcParamProp = car(exists(prop pcParameters ((prop~>name) == "Grid"))))
(Grid = (pcParamProp~>value))
(pcParamProp = car(exists(prop pcParameters ((prop~>name) == "Layer"))))
(Layer = (pcParamProp~>value))
(dbReplaceProp pcCellView "viewSubType" "string" "maskLayoutParamCell")
(polyList = nil)
(X = 0.0)
(Y = Radius)
(direction = 0)
(pcLayer = Layer)
(pcPurpose = "drawing")
(polyList = (tconc polyList (list X Y)))
(ret = (RALgetNextPoint direction X Y Grid Radius))
(X = (car ret))
(Y = (cadr ret))
(direction = (caddr ret))
(polyList = (tconc polyList (list X Y)))
(points = 1)
(cheese = 0)
(while !( (abs X) < Grid && (abs Radius-Y) < Grid)
(points = points + 1)
(ret = (RALgetNextPoint direction X Y Grid Radius))
(X = (car ret))
(Y = (cadr ret))
(direction = (caddr ret))
(polyList = (tconc polyList (list X Y)))
/* Split into multiple polygons if the number of points will exceed
* the maximum. If this happens, the final polygon must contain an
* additional point at 0,0 so that it closes properly. This is
* controlled with the "cheese" variable because the output shape
* resembles a round cheese chopped into pieces. */
(if points == 2047 then
(polyList = (tconc polyList (list 0.0 0.0)))
(dbCreatePolygon pcCellView
(list pcLayer pcPurpose)
(car polyList))
(points = 0)
(cheese = 1)
(polyList = (tconc nil (list X Y)))
)
)
(if (onep cheese) then
(polyList = (tconc polyList (list 0.0 0.0)))
)
(dbCreatePolygon pcCellView
(list pcLayer pcPurpose)
(car polyList))
t
)
)