Ring shapes using KLayout

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.
    See the "Selection" menu.

  • 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 ]
          pts = approximate_edge_normalized(e, step)
          return pts.collect { |p| t * p }
        swap_xy = RBA::Trans::M45
        return approximate_edge(swap_xy * e, step, t * swap_xy)
    # 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
    # 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)
    # ---------------------------------------------------------------
    # usage example
    source = input(1)
    step = 10.nm
    approximate_layer(source, step).output(10, 0)


  • 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.



Sign In or Register to comment.