# Ring shapes using KLayout

Hi,
I am trying to create a ring shape in Layout. First I used the donut shape and exported it to cadence. Apparently the design gives me an error with the DRC check. The donut shape created using the Klayout does not snap/fit to the grid points. One example of a ring structure fitting the DRC regulations is attached here.

Can I create such structure using the KLayout? • You can create such structure very easily with Klayout.
Create two boxes and apply "round corners". Then subtract one box to the other.

• edited July 2019

Hi Rakesh,

I think the request is about creating the pixelized pattern.

There is no function readily available for this kind of transformation yet, but it can be coded. Here for example is a DRC script which turns a layer with all-angle polygons in to one with staircase approximation:

``````# Approximates an arbitrary edge by a staircase of points
# with step size < step (all in database units)

def approximate_edge(e, step, t = RBA::Trans::R0)
if e.dx.abs >= e.dy.abs
if e.dx < 0
mirror_x = RBA::Trans::M90
return approximate_edge(mirror_x * e, step, t * mirror_x)
elsif e.dy < 0
mirror_y = RBA::Trans::M0
return approximate_edge(mirror_y * e, step, t * mirror_y)
elsif e.dy == 0
# horizontal edge
return [ t * e.p1, t * e.p2 ]
else
pts = approximate_edge_normalized(e, step)
return pts.collect { |p| t * p }
end
else
swap_xy = RBA::Trans::M45
return approximate_edge(swap_xy * e, step, t * swap_xy)
end
end

# Approximates a special edge by a staircase of points
# The edge will have dx > 0, dy 0 and dx > dy

def approximate_edge_normalized(e, step)

pts = []
dx = e.dx
dy = e.dy
nsteps = dy / step + 1

pts << e.p1

nsteps.times do |i|
xi = ((2 * i + 1) * dx) / (2 * nsteps)
yi = ((i + 1) * dy) / nsteps
p1 = RBA::Vector::new(xi + e.p1.x, pts[-1].y)
p2 = RBA::Vector::new(p1.x, yi + e.p1.y)
pts << p1
pts << p2
end

pts

end

# Approximates a DRC layer and returns a new one with
# the approximated polygons

def approximate_layer(source, step)

step_dbu = (step / dbu + 0.5).floor.to_i

target = polygon_layer

source.data.each do |p|
pts = []
p.to_simple_polygon.each_edge do |e|
pts += approximate_edge(e, step_dbu)
end
target.data.insert(RBA::Polygon::new(pts))
end

target

end

# ---------------------------------------------------------------
# usage example

source = input(1)

step = 10.nm
approximate_layer(source, step).output(10, 0)
``````

Matthias

• Matthias, Thank you for the help. I am new to ruby and do not where to get start. All I new is to go to the macros and compile this code, but how does this effect the layout diagram is not something I can understand.
Can you please direct me towards some simple RUBY examples to begin with?

• Hi Rakesh,

this is a DRC script. Go to the Macro editor, open the DRC tab, create a new DRC script and paste the above code.

If you run it, it will take input from layer 1, datatype 0, apply the steps and write it to layer 10, datatype 0 in your original layout. See the last lines for these details.

Regards,

Matthias