You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

450 lines
26KB

  1. import pya
  2. import os
  3. base_dir = os.path.dirname(os.path.abspath(__file__))
  4. # init vars
  5. pixel_size = 20
  6. shift_mult = 5
  7. image_size = 4266 * pixel_size * 100 #calculate this directly (4266 and 4242 for shift_mult 5 and 3, respectively)
  8. image_size_half = image_size / 2
  9. image_dist = (shift_mult * 3 * 2 + 2) * pixel_size * 100
  10. object_border = 0
  11. #print(image_dist)
  12. # create layout
  13. layout = pya.Layout()
  14. layout.dbu = 0.01
  15. top = layout.create_cell("Top")
  16. layer1_index = layout.insert_layer(pya.LayerInfo.new(1, 0))
  17. layer2_index = layout.insert_layer(pya.LayerInfo.new(2, 0))
  18. layer3_index = layout.insert_layer(pya.LayerInfo.new(3, 0))
  19. layer4_index = layout.insert_layer(pya.LayerInfo.new(4, 0))
  20. layer5_index = layout.insert_layer(pya.LayerInfo.new(5, 0))
  21. # wafer limits
  22. wafer = layout.create_cell("Wafer")
  23. wafer_circle_limit = layout.create_cell("CIRCLE", "Basic",
  24. { "actual_radius": 75000, "npoints": 256, "layer": pya.LayerInfo(5, 0)} )
  25. wafer1_cell_border = layout.create_cell("DONUT", "Basic",
  26. { "actual_radius1": 67500, "actual_radius2": 75000, "npoints": 256, "layer": pya.LayerInfo(1, 0)} )
  27. wafer2_cell_border = layout.create_cell("DONUT", "Basic",
  28. { "actual_radius1": 67500, "actual_radius2": 75000, "npoints": 256, "layer": pya.LayerInfo(2, 0)} )
  29. wafer.insert(pya.CellInstArray(wafer_circle_limit.cell_index(), pya.Trans(0, 0)))
  30. wafer.insert(pya.CellInstArray(wafer1_cell_border.cell_index(), pya.Trans(0, 0)))
  31. wafer.insert(pya.CellInstArray(wafer2_cell_border.cell_index(), pya.Trans(0, 0)))
  32. limit_region = pya.Region(wafer_circle_limit.begin_shapes_rec(layer5_index))
  33. wafer1_fill_region = pya.Region()
  34. wafer1_fill_region.insert(pya.Box(-7500000, -6850000 + 1750000, 7500000, -1 * (6850000 + 1850000))) #mount area fill
  35. frame_width = 300000
  36. square_width = 2000000
  37. wafer1_fill_region.insert(pya.Box(image_size_half, image_size_half, image_size_half + square_width, image_size_half + square_width)) #encoder
  38. wafer1_fill_region.insert(pya.Box(image_size_half, -1 * image_size_half, image_size_half + square_width, -1 * (image_size_half + square_width))) #encoder
  39. wafer1_fill_region.insert(pya.Box(-1 * image_size_half, image_size_half, -1 * (image_size_half + square_width), image_size_half + square_width)) #encoder
  40. wafer1_fill_region.insert(pya.Box(-1 * image_size_half, -1 * image_size_half, -1 * (image_size_half + square_width), -1 * (image_size_half + square_width))) #encoder
  41. wafer.shapes(layer1_index).insert(limit_region & wafer1_fill_region)
  42. wafer2_fill_region = pya.Region()
  43. wafer2_fill_region.insert(pya.Box(-7500000, 6850000 - 1750000, 7500000, 6850000 + 1850000)) #mount area fill
  44. wafer2_fill_region.insert(pya.Box(image_size_half, image_size_half, image_size_half + square_width, image_size_half + square_width)) #encoder
  45. wafer2_fill_region.insert(pya.Box(image_size_half, -1 * image_size_half, image_size_half + square_width, -1 * (image_size_half + square_width))) #encoder
  46. wafer2_fill_region.insert(pya.Box(-1 * image_size_half, image_size_half, -1 * (image_size_half + square_width), image_size_half + square_width)) #encoder
  47. wafer2_fill_region.insert(pya.Box(-1 * image_size_half, -1 * image_size_half, -1 * (image_size_half + square_width), -1 * (image_size_half + square_width))) #encoder
  48. wafer.shapes(layer2_index).insert(limit_region & wafer2_fill_region)
  49. wafer.shapes(layer3_index).insert(pya.Box(-7500000, -6850000, 7500000, 6850000 - 1850000)) #printable area wafer 1
  50. wafer.shapes(layer4_index).insert(pya.Box(-7500000, 6850000, 7500000, -1 * (6850000 - 1850000))) #printable area wafer 2
  51. top.insert(pya.CellInstArray(wafer.cell_index(), pya.Trans(0, 0)))
  52. layout.rename_cell(wafer.cell_index(), "Wafer_Border")
  53. # def for circ grating
  54. def gen_circ_grating(pitch, width, square_size, name):
  55. #create grating archetype for circ grating
  56. circ_grating = layout.create_cell("Circ_Grating")
  57. circ_grating_inv = layout.create_cell("Circ_Grating_Inv")
  58. i = 0
  59. while (i * pitch) < (8000):
  60. donut = layout.create_cell("DONUT", "Basic",
  61. { "actual_radius1": (i * pitch), "actual_radius2": (i * pitch + width), "npoints": 256, "layer": pya.LayerInfo(1, 0)} )
  62. circ_grating.insert(pya.CellInstArray(donut.cell_index(), pya.Trans(0, 0)))
  63. i = i + 1
  64. i = 0
  65. while (i * pitch) < (8000):
  66. donut = layout.create_cell("DONUT", "Basic",
  67. { "actual_radius1": (i * pitch) + width, "actual_radius2": (i * pitch + width) + width, "npoints": 256, "layer": pya.LayerInfo(2, 0)} )
  68. circ_grating_inv.insert(pya.CellInstArray(donut.cell_index(), pya.Trans(0, 0)))
  69. i = i + 1
  70. circ_grating_clip = layout.clip(circ_grating.cell_index(), pya.Box(-1 * square_size, -1 * square_size, square_size, square_size))
  71. circ_grating_inv_clip = layout.clip(circ_grating_inv.cell_index(), pya.Box(-1 * square_size, -1 * square_size, square_size, square_size))
  72. circ_grating.delete()
  73. circ_grating_inv.delete()
  74. layout.rename_cell(circ_grating_clip, name + "_Clip")
  75. layout.rename_cell(circ_grating_inv_clip, name + "_Inv_Clip")
  76. return [circ_grating_clip, circ_grating_inv_clip]
  77. # verniers
  78. linear_grating_vernier = layout.create_cell("Vernier")
  79. base_period = image_size_half - 500000
  80. revealing_period = image_dist
  81. velocity_ratio = 1
  82. pitch1 = (base_period * (revealing_period / velocity_ratio)) / (base_period - (revealing_period / velocity_ratio))
  83. pitch2 = revealing_period / velocity_ratio
  84. opening1 = 4000
  85. #print(pitch1)
  86. #print(pitch2)
  87. frame_width = 300000
  88. for i in range(-1 * int((image_size_half) / pitch1), int((image_size_half) / pitch1)):
  89. line = layout.create_cell("Line")
  90. line.shapes(layer2_index).insert(pya.Box(opening1 / 2, -1 * frame_width, pitch1 - opening1 / 2, 0))
  91. linear_grating_vernier.insert(pya.CellInstArray(line.cell_index(), pya.Trans(i * pitch1, 0)))
  92. for i in range(-1 * int((image_size_half - image_dist) / pitch2), int((image_size_half - image_dist) / pitch2)):
  93. line = layout.create_cell("Line")
  94. line.shapes(layer1_index).insert(pya.Box(opening1 / 2, -1 * frame_width, pitch2 - opening1 / 2, 0))
  95. linear_grating_vernier.insert(pya.CellInstArray(line.cell_index(), pya.Trans(i * pitch2, 0)))
  96. base_period = -1 * (image_size_half - 500000)
  97. revealing_period = image_dist
  98. velocity_ratio = 5
  99. pitch3 = (base_period * (revealing_period / velocity_ratio)) / (base_period - (revealing_period / velocity_ratio))
  100. pitch4 = revealing_period / velocity_ratio
  101. opening2 = 800
  102. for i in range(-1 * int(image_size_half / pitch3), int(image_size_half / pitch3)):
  103. line = layout.create_cell("Line")
  104. line.shapes(layer2_index).insert(pya.Box(opening2 / 2, 0, pitch3 - opening2 / 2, frame_width))
  105. linear_grating_vernier.insert(pya.CellInstArray(line.cell_index(), pya.Trans(i * pitch3, 0)))
  106. for i in range(-1 * int((image_size_half - image_dist) / pitch4), int((image_size_half - image_dist) / pitch4)):
  107. line = layout.create_cell("Line")
  108. line.shapes(layer1_index).insert(pya.Box(opening2 / 2, 0, pitch4 - opening2 / 2, frame_width))
  109. linear_grating_vernier.insert(pya.CellInstArray(line.cell_index(), pya.Trans(i * pitch4, 0)))
  110. line = layout.create_cell("Line")
  111. line.shapes(layer2_index).insert(pya.Box(image_size_half - (2 * image_dist), -1 * frame_width, image_size_half, 0))
  112. line.shapes(layer2_index).insert(pya.Box(-1 * (image_size_half - (2 * image_dist)), -1 * frame_width, -1 * (image_size_half), 0))
  113. line.shapes(layer2_index).insert(pya.Box(image_size_half - (2 * image_dist), image_dist, image_size_half, image_dist + frame_width))
  114. line.shapes(layer2_index).insert(pya.Box(-1 * (image_size_half - (2 * image_dist)), image_dist, -1 * (image_size_half), image_dist + frame_width))
  115. #These four lines can be taken away to get rid of the bounding black out
  116. line.shapes(layer2_index).insert(pya.Box(-1 * image_size_half, image_dist, image_size_half, 0 - image_dist))
  117. line.shapes(layer2_index).insert(pya.Box(-1 * image_size_half, -1 * (frame_width - image_dist), image_size_half, -1 * (frame_width + image_dist)))
  118. line.shapes(layer2_index).insert(pya.Box(-1 * image_size_half, 0, image_size_half, image_dist))
  119. line.shapes(layer2_index).insert(pya.Box(-1 * image_size_half, frame_width + (1 * image_dist), image_size_half, frame_width - image_dist))
  120. linear_grating_vernier.insert(pya.CellInstArray(line.cell_index(), pya.Trans(0, 0)))
  121. line = layout.create_cell("Line")
  122. line.shapes(layer1_index).insert(pya.Box(image_size_half - image_dist, -1 * frame_width, image_size_half - (2 * image_dist), 0))
  123. line.shapes(layer1_index).insert(pya.Box(-1 * (image_size_half - image_dist), -1 * frame_width, -1 * (image_size_half - (2 * image_dist)), 0))
  124. line.shapes(layer1_index).insert(pya.Box(image_size_half - image_dist, 0, image_size_half - (2 * image_dist), frame_width))
  125. line.shapes(layer1_index).insert(pya.Box(-1 * (image_size_half - image_dist), 0, -1 * (image_size_half - (2 * image_dist)), frame_width))
  126. linear_grating_vernier.insert(pya.CellInstArray(line.cell_index(), pya.Trans(0, 0)))
  127. vernier_extent = image_size_half + object_border + frame_width + image_dist
  128. top.insert(pya.CellInstArray(linear_grating_vernier.cell_index(), pya.Trans(3, False, vernier_extent, 0)))
  129. top.insert(pya.CellInstArray(linear_grating_vernier.cell_index(), pya.Trans(1, False, -1 * vernier_extent, 0)))
  130. top.insert(pya.CellInstArray(linear_grating_vernier.cell_index(), pya.Trans(0, False, 0, vernier_extent)))
  131. top.insert(pya.CellInstArray(linear_grating_vernier.cell_index(), pya.Trans(2, False, 0, -1 * vernier_extent)))
  132. vernier_extent = vernier_extent + frame_width + image_dist
  133. # linear grating unison for rotational alignment
  134. linear_grating_uni = layout.create_cell("Linear_Grating_Uni")
  135. pitch = 2000
  136. line_width = 1000
  137. frame_width = 300000 / 2
  138. line_length = image_size_half - 500000
  139. i = -1 * frame_width
  140. while (i) < (frame_width):
  141. line = layout.create_cell("Line")
  142. line.shapes(layer1_index).insert(pya.Box(0, -1 * line_length, line_width, line_length))
  143. linear_grating_uni.insert(pya.CellInstArray(line.cell_index(), pya.Trans(i, 0)))
  144. i = i + pitch
  145. i = -1 * frame_width
  146. shift = line_width
  147. while (i) < (frame_width):
  148. line = layout.create_cell("Line")
  149. line.shapes(layer2_index).insert(pya.Box(0, -1 * line_length, line_width, line_length))
  150. linear_grating_uni.insert(pya.CellInstArray(line.cell_index(), pya.Trans(i + shift, 0)))
  151. i = i + pitch
  152. unison_rot_extent = vernier_extent + object_border + frame_width + image_dist
  153. top.insert(pya.CellInstArray(linear_grating_uni.cell_index(), pya.Trans(2, False, unison_rot_extent, 0)))
  154. top.insert(pya.CellInstArray(linear_grating_uni.cell_index(), pya.Trans(0, False, -1 * unison_rot_extent, 0)))
  155. unison_rot_extent = unison_rot_extent + frame_width + image_dist
  156. # 9 * 9 grid with larger squares
  157. circ_grating_square_array_2 = layout.create_cell("Circ_Grating_Square_Array_2")
  158. square_dist = 400000
  159. pitch = 10
  160. width = 5
  161. square_size = (square_dist / 2) - 20000
  162. [circ_grating_square_array_clip, circ_grating_square_array_inv_clip] = gen_circ_grating(pitch, width, square_size, "Circ_Grating_2")
  163. for r in range(-1, 2):
  164. for c in range(-1, 2):
  165. circ_grating_square_array_2.insert(pya.CellInstArray(circ_grating_square_array_clip, pya.Trans(0, False, square_dist * r, square_dist * c)))
  166. circ_grating_square_array_2.insert(pya.CellInstArray(circ_grating_square_array_inv_clip, pya.Trans(0, False, square_dist * r + (r * image_dist), square_dist * c + (c * image_dist))))
  167. grid_extent = unison_rot_extent + square_size + square_dist + image_dist
  168. y_offset = square_dist + image_dist + (square_size)
  169. top.insert(pya.CellInstArray(circ_grating_square_array_2.cell_index(), pya.Trans(2, False, grid_extent, 0)))
  170. top.insert(pya.CellInstArray(circ_grating_square_array_2.cell_index(), pya.Trans(0, False, -1 * grid_extent, 0)))
  171. # verniers md course
  172. linear_grating_vernier_md_course = layout.create_cell("Vernier_md_course")
  173. square_size = 650000
  174. fray = 0
  175. line_length = square_size / 2 + fray
  176. velocity_ratio = 2
  177. pitch1 = ((square_size * 1) * (image_dist / velocity_ratio)) / ((square_size * 1) - (image_dist / velocity_ratio))
  178. pitch2 = image_dist / velocity_ratio
  179. opening = 8000
  180. for i in range(-1 * int(square_size / 2 / pitch1) - 0, int(square_size / 2 / pitch1) + 0):
  181. line = layout.create_cell("Line")
  182. line.shapes(layer2_index).insert(pya.Box(opening / 2, -1 * line_length, pitch1 - opening / 2, line_length))
  183. linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(i * pitch1, 0)))
  184. linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(1, False, 0, (i * pitch1))))
  185. for i in range(-1 * int(square_size / 2 / pitch2) - 0, int(square_size / 2 / pitch2) + 0):
  186. line = layout.create_cell("Line")
  187. line.shapes(layer1_index).insert(pya.Box(opening / 2, -1 * line_length, pitch2 - opening / 2, line_length))
  188. linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(i * pitch2, 0)))
  189. linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(1, False, 0, (i * pitch2))))
  190. line = layout.create_cell("Line")
  191. line.shapes(layer2_index).insert(pya.Box(-1 * (square_size / 2 + (1 * image_dist)), square_size / 2 - image_dist, square_size / 2 + (1 * image_dist), square_size / 2 + (1 * image_dist)))
  192. linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(0, 0)))
  193. line = layout.create_cell("Line")
  194. line.shapes(layer2_index).insert(pya.Box(-1 * (square_size / 2 + (1 * image_dist)), square_size / 2 - image_dist, square_size / 2 + (0 * image_dist), square_size / 2 + (1 * image_dist)))
  195. #linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(0, 0)))
  196. linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(1, False, 0, 0)))
  197. linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(2, False, 0, 0)))
  198. linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(1, True, 0, 0)))
  199. line = layout.create_cell("Line")
  200. line.shapes(layer1_index).insert(pya.Box(-1 * (square_size / 2 + (1 * image_dist)), square_size / 2, square_size / 2 + (1 * image_dist), square_size / 2 + (0 * image_dist)))
  201. linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(0, 0)))
  202. linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(1, False, 0, 0)))
  203. linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(2, False, 0, 0)))
  204. linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(3, False, 0, 0)))
  205. triangle = layout.create_cell("Triangle")
  206. triangle.shapes(layer2_index).insert(pya.Polygon([pya.Point(-45000, -1 * image_dist), pya.Point(45000, -1 * image_dist), pya.Point(0, 0)]))
  207. linear_grating_vernier_md_course.insert(pya.CellInstArray(triangle.cell_index(), pya.Trans(0, False, 0, -1 * (square_size / 2 + (image_dist * 1)))))
  208. linear_grating_vernier_md_course.insert(pya.CellInstArray(triangle.cell_index(), pya.Trans(1, False, (square_size / 2 + (image_dist * 1)), 0)))
  209. grid_extent = unison_rot_extent + (square_size / 2) + (image_dist * 1)
  210. y_offset = y_offset + (square_size / 2) + (image_dist * 3)
  211. top.insert(pya.CellInstArray(linear_grating_vernier_md_course.cell_index(), pya.Trans(0, False, (grid_extent + fray), (y_offset + fray))))
  212. top.insert(pya.CellInstArray(linear_grating_vernier_md_course.cell_index(), pya.Trans(0, True, (grid_extent + fray), -1 * (y_offset + fray))))
  213. top.insert(pya.CellInstArray(linear_grating_vernier_md_course.cell_index(), pya.Trans(2, False, -1 * (grid_extent + fray), -1 * (y_offset + fray))))
  214. top.insert(pya.CellInstArray(linear_grating_vernier_md_course.cell_index(), pya.Trans(2, True, -1 * (grid_extent + fray), (y_offset + fray))))
  215. # verniers md fine
  216. linear_grating_vernier_md_fine = layout.create_cell("Vernier_md_fine")
  217. square_size = 650000
  218. fray = 0
  219. line_length = square_size / 2 + fray
  220. velocity_ratio = 3
  221. pitch1 = ((square_size * -1) * (image_dist / velocity_ratio)) / ((square_size * -1) - (image_dist / velocity_ratio))
  222. pitch2 = image_dist / velocity_ratio
  223. opening = 8000 * 2/3
  224. for i in range(-1 * int(square_size / 2 / pitch1) - 0, int(square_size / 2 / pitch1) + 0):
  225. line = layout.create_cell("Line")
  226. line.shapes(layer2_index).insert(pya.Box(opening / 2, -1 * line_length, pitch1 - opening / 2, line_length))
  227. linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(i * pitch1, 0)))
  228. linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(1, False, 0, (i * pitch1))))
  229. for i in range(-1 * int(square_size / 2 / pitch1) - 0, int(square_size / 2 / pitch1) + 0):
  230. line = layout.create_cell("Line")
  231. line.shapes(layer1_index).insert(pya.Box(opening / 2, -1 * line_length, pitch2 - opening / 2, line_length))
  232. linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(i * pitch2, 0)))
  233. linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(1, False, 0, (i * pitch2))))
  234. line = layout.create_cell("Line")
  235. line.shapes(layer2_index).insert(pya.Box(-1 * (square_size / 2 + (1 * image_dist)), square_size / 2 - image_dist, square_size / 2 + (1 * image_dist), square_size / 2 + (1 * image_dist)))
  236. linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(0, 0)))
  237. line = layout.create_cell("Line")
  238. line.shapes(layer2_index).insert(pya.Box(-1 * (square_size / 2 + (1 * image_dist)), square_size / 2 - image_dist, square_size / 2 + (0 * image_dist), square_size / 2 + (1 * image_dist)))
  239. #linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(0, 0)))
  240. linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(1, False, 0, 0)))
  241. linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(2, False, 0, 0)))
  242. linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(1, True, 0, 0)))
  243. line = layout.create_cell("Line")
  244. line.shapes(layer1_index).insert(pya.Box(-1 * (square_size / 2 + (1 * image_dist)), square_size / 2, square_size / 2 + (1 * image_dist), square_size / 2 + (0 * image_dist)))
  245. linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(0, 0)))
  246. linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(1, False, 0, 0)))
  247. linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(2, False, 0, 0)))
  248. linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(3, False, 0, 0)))
  249. triangle = layout.create_cell("Triangle")
  250. triangle.shapes(layer2_index).insert(pya.Polygon([pya.Point(-45000, -1 * image_dist), pya.Point(45000, -1 * image_dist), pya.Point(0, 0)]))
  251. linear_grating_vernier_md_fine.insert(pya.CellInstArray(triangle.cell_index(), pya.Trans(0, False, 0, -1 * (square_size / 2 + (image_dist * 1)))))
  252. linear_grating_vernier_md_fine.insert(pya.CellInstArray(triangle.cell_index(), pya.Trans(1, False, (square_size / 2 + (image_dist * 1)), 0)))
  253. grid_extent = unison_rot_extent + (square_size / 2) + (image_dist * 1)
  254. y_offset = y_offset + square_size + (image_dist * 1)
  255. top.insert(pya.CellInstArray(linear_grating_vernier_md_course.cell_index(), pya.Trans(0, True, (grid_extent + fray), (y_offset + fray))))
  256. top.insert(pya.CellInstArray(linear_grating_vernier_md_course.cell_index(), pya.Trans(0, False, (grid_extent + fray), -1 * (y_offset + fray))))
  257. top.insert(pya.CellInstArray(linear_grating_vernier_md_course.cell_index(), pya.Trans(2, True, -1 * (grid_extent + fray), -1 * (y_offset + fray))))
  258. top.insert(pya.CellInstArray(linear_grating_vernier_md_course.cell_index(), pya.Trans(2, False, -1 * (grid_extent + fray), (y_offset + fray))))
  259. y_offset = y_offset + (square_size / 2) + (image_dist * 3)
  260. # larger squares only in the unison position
  261. circ_grating_uni = layout.create_cell("Circ_Grating_Uni")
  262. pitch = 20
  263. width = 10
  264. square_size = 530000 / 2
  265. [circ_grating_uni_clip, circ_grating_uni_inv_clip] = gen_circ_grating(pitch, width, square_size, "Circ_Grating_3")
  266. circ_grating_uni.insert(pya.CellInstArray(circ_grating_uni_clip, pya.Trans(0, False, 0, 0)))
  267. circ_grating_uni.insert(pya.CellInstArray(circ_grating_uni_inv_clip, pya.Trans(0, False, 0, 0)))
  268. grid_extent = unison_rot_extent + square_size + image_dist
  269. y_offset = y_offset + (square_size / 1)
  270. top.insert(pya.CellInstArray(circ_grating_uni.cell_index(), pya.Trans(0, False, grid_extent, -1 * y_offset)))
  271. top.insert(pya.CellInstArray(circ_grating_uni.cell_index(), pya.Trans(0, False, -1 * grid_extent, -1 * y_offset)))
  272. top.insert(pya.CellInstArray(circ_grating_uni.cell_index(), pya.Trans(0, False, grid_extent, y_offset)))
  273. top.insert(pya.CellInstArray(circ_grating_uni.cell_index(), pya.Trans(0, False, -1 * grid_extent, y_offset)))
  274. #top.insert(pya.CellInstArray(linear_grating_encoder_clip, pya.Trans(0, False, image_size_half, image_size_half)))
  275. # linear grating encoder for optional optosensor
  276. def gen_encoder_grating(alg_layout, cell):
  277. frame_width = 300000
  278. linear_grating_encoder_1 = alg_layout.create_cell("Linear_Grating_Encoder_1")
  279. linear_grating_encoder_2 = alg_layout.create_cell("Linear_Grating_Encoder_2")
  280. pitch = 1000
  281. line_width = 500
  282. square_width = (frame_width * 2) + (image_dist * 2)
  283. square_width = 2000000
  284. line_length = square_width
  285. i = -1 * square_width
  286. while (i) < (square_width):
  287. line = alg_layout.create_cell("Line")
  288. line.shapes(layer1_index).insert(pya.Box(line_width, 0, -1 * square_width, line_width))
  289. line.shapes(layer1_index).insert(pya.Box(0, 0, line_width, -1 * square_width))
  290. linear_grating_encoder_1.insert(pya.CellInstArray(line.cell_index(), pya.Trans(0, False, i, i)))
  291. line = alg_layout.create_cell("Line")
  292. line.shapes(layer2_index).insert(pya.Box(line_width, 0, -1 * square_width, line_width))
  293. line.shapes(layer2_index).insert(pya.Box(0, 0, line_width, -1 * square_width))
  294. linear_grating_encoder_2.insert(pya.CellInstArray(line.cell_index(), pya.Trans(0, False, i, i)))
  295. i = i + pitch
  296. i = -1 * square_width
  297. shift = line_width
  298. while (i) < (frame_width + image_dist):
  299. line = alg_layout.create_cell("Line")
  300. line.shapes(layer2_index).insert(pya.Box(line_width, 0, -1 * square_width, line_width))
  301. line.shapes(layer2_index).insert(pya.Box(0, 0, line_width, -1 * square_width))
  302. linear_grating_encoder_1.insert(pya.CellInstArray(line.cell_index(), pya.Trans(0, False, i + shift, i + shift)))
  303. line = alg_layout.create_cell("Line")
  304. line.shapes(layer1_index).insert(pya.Box(line_width, 0, -1 * square_width, line_width))
  305. line.shapes(layer1_index).insert(pya.Box(0, 0, line_width, -1 * square_width))
  306. linear_grating_encoder_2.insert(pya.CellInstArray(line.cell_index(), pya.Trans(0, False, i + shift, i + shift)))
  307. i = i + pitch
  308. inner_clip_2 = alg_layout.clip(linear_grating_encoder_2.cell_index(), pya.Box(0, 0, frame_width + image_dist, frame_width + image_dist))
  309. linear_grating_encoder_clip_2 = alg_layout.clip(linear_grating_encoder_2.cell_index(), pya.Box(0, 0, square_width, square_width))
  310. cell.insert(pya.CellInstArray(linear_grating_encoder_clip_2, pya.Trans(0, False, image_size_half, image_size_half)))
  311. cell.insert(pya.CellInstArray(inner_clip_2, pya.Trans(0, False, image_size_half + frame_width + image_dist, image_size_half + frame_width + image_dist)))
  312. cell.insert(pya.CellInstArray(linear_grating_encoder_clip_2, pya.Trans(1, False, -1 * image_size_half, image_size_half)))
  313. cell.insert(pya.CellInstArray(inner_clip_2, pya.Trans(1, False, -1 * (image_size_half + frame_width + image_dist), image_size_half + frame_width + image_dist)))
  314. inner_clip_1 = alg_layout.clip(linear_grating_encoder_1.cell_index(), pya.Box(0, 0, frame_width + image_dist, frame_width + image_dist))
  315. linear_grating_encoder_clip_1 = alg_layout.clip(linear_grating_encoder_1.cell_index(), pya.Box(0, 0, square_width, square_width))
  316. cell.insert(pya.CellInstArray(linear_grating_encoder_clip_1, pya.Trans(2, False, -1 * image_size_half, -1 * image_size_half)))
  317. cell.insert(pya.CellInstArray(inner_clip_1, pya.Trans(2, False, -1 * (image_size_half + frame_width + image_dist), -1 * (image_size_half + frame_width + image_dist))))
  318. cell.insert(pya.CellInstArray(linear_grating_encoder_clip_1, pya.Trans(3, False, image_size_half, -1 * image_size_half)))
  319. cell.insert(pya.CellInstArray(inner_clip_1, pya.Trans(3, False, image_size_half + frame_width + image_dist, -1 * (image_size_half + frame_width + image_dist))))
  320. cell.flatten(1)
  321. alg_layout.prune_cell(linear_grating_encoder_1.cell_index(), -1)
  322. alg_layout.prune_cell(linear_grating_encoder_2.cell_index(), -1)
  323. top.flatten(1)
  324. wafer1_region1 = pya.Region(top.begin_shapes_rec(layer1_index))
  325. wafer1_region2 = pya.Region(top.begin_shapes_rec(layer3_index))
  326. wafer2_region1 = pya.Region(top.begin_shapes_rec(layer2_index))
  327. wafer2_region2 = pya.Region(top.begin_shapes_rec(layer4_index))
  328. alignment_layout = pya.Layout()
  329. alignment = alignment_layout.create_cell("Alignment")
  330. alignment_layout.dbu = 0.01
  331. layer1_index = alignment_layout.insert_layer(pya.LayerInfo.new(1, 0))
  332. layer2_index = alignment_layout.insert_layer(pya.LayerInfo.new(2, 0))
  333. encode_region = pya.Region()
  334. square_width = 2000000
  335. encode_region.insert(pya.Box(image_size_half, image_size_half, image_size_half + square_width, image_size_half + square_width)) #encoder
  336. encode_region.insert(pya.Box(image_size_half, -1 * image_size_half, image_size_half + square_width, -1 * (image_size_half + square_width))) #encoder
  337. encode_region.insert(pya.Box(-1 * image_size_half, image_size_half, -1 * (image_size_half + square_width), image_size_half + square_width)) #encoder
  338. encode_region.insert(pya.Box(-1 * image_size_half, -1 * image_size_half, -1 * (image_size_half + square_width), -1 * (image_size_half + square_width))) #encoder
  339. alignment.shapes(layer1_index).insert((wafer1_region1 & wafer1_region2) - encode_region)
  340. alignment.shapes(layer2_index).insert((wafer2_region1 & wafer2_region2) - encode_region)
  341. gen_encoder_grating(alignment_layout, alignment)
  342. #alignment_layout.transform(pya.Trans(2, False, 0, 0))
  343. alignment_layout.write(os.path.join(base_dir, "..", "gds", "alignment_marks_overlapped.gds"))
  344. alignment_inv_layout = pya.Layout()
  345. alignment_inv = alignment_inv_layout.create_cell("Alignment_Inverse")
  346. alignment_inv_layout.dbu = 0.01
  347. layer1_index = alignment_inv_layout.insert_layer(pya.LayerInfo.new(1, 0))
  348. layer2_index = alignment_inv_layout.insert_layer(pya.LayerInfo.new(2, 0))
  349. alignment_inv.shapes(layer1_index).insert(wafer1_region2 - wafer1_region1)
  350. alignment_inv.shapes(layer2_index).insert(wafer2_region2 - wafer2_region1)
  351. gen_encoder_grating(alignment_inv_layout, alignment_inv)
  352. #alignment_inv_layout.transform(pya.Trans(2, False, 0, 0))
  353. alignment_inv_layout.write(os.path.join(base_dir, "..", "gds", "inverted_tonality", "alignment_marks_overlapped_inverse.gds"))