├── LICENSE
├── README.md
├── asap7.lyp
├── asap7.lyt
└── drc
└── drc_ASAP7.lydrc
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 2-Clause License
2 |
3 | Copyright (c) 2021, laurentc2
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ASAP7_for_KLayout
2 |
3 | ## KLayout (version 0.27.1 or higher) technology files for ASAP7 FinFET educational process
4 |
5 | * ASAP7.lyt : technology and connections description
6 | * ASAP7.lyp : layers color and shape description
7 | * drc/drc_ASAP7.lydrc : DRC script
8 |
9 | Within KLayout, create the technolgy ASAP7 by the menu : **[Tools]-[Manage Technologies]**
10 | Then press + at the bottom left, you will add a new technology that you can call : _ASAP7_
11 |
12 | Then, you can copy the file **ASAP7.lyp**, **ASAP7.lyt** and the 2 directories **drc** and **lvs** of that repository in your directory :
13 | `$HOME/.klayout/tech/ASAP7 (under Linux)`
14 | `#HOMEDATA#/klayout/tech/ASAP7 (under Windows)`
15 |
--------------------------------------------------------------------------------
/asap7.lyp:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | #c0c0c0
6 | #c0c0c0
7 | 0
8 | 0
9 | C7
10 |
11 | true
12 | true
13 | false
14 | 2
15 | false
16 | false
17 | 0
18 | NWELL - 1/0
19 | 1/0@1
20 |
21 |
22 | #c0c0c0
23 | #c0c0c0
24 | 0
25 | 0
26 | C1
27 |
28 | true
29 | true
30 | false
31 | 1
32 | false
33 | false
34 | 0
35 | NWELL.txt - 1/251
36 | 1/251@1
37 |
38 |
39 | #00ccff
40 | #00ccff
41 | 0
42 | 0
43 | C6
44 |
45 | true
46 | true
47 | false
48 | 2
49 | false
50 | false
51 | 0
52 | PSUB - 3/0
53 | 3/0@1
54 |
55 |
56 | #00ccff
57 | #00ccff
58 | 0
59 | 0
60 | C1
61 |
62 | true
63 | true
64 | false
65 | 2
66 | false
67 | false
68 | 0
69 | PSUB.txt - 3/251
70 | 3/251@1
71 |
72 |
73 | #00ff00
74 | #00ff00
75 | 0
76 | 0
77 | C13
78 |
79 | true
80 | true
81 | false
82 | 1
83 | false
84 | false
85 | 0
86 | FIN - 2/0
87 | 2/0@1
88 |
89 |
90 | #ff0000
91 | #ff0000
92 | 0
93 | 0
94 | C11
95 |
96 | true
97 | true
98 | false
99 | 1
100 | false
101 | false
102 | 0
103 | GATE - 7/0
104 | 7/0@1
105 |
106 |
107 | #ff8000
108 | #ff8000
109 | 0
110 | 0
111 | C11
112 |
113 | true
114 | true
115 | false
116 | 1
117 | false
118 | false
119 | 0
120 | GATE.Dummy - 8/0
121 | 8/0@1
122 |
123 |
124 | #ff00ff
125 | #ff00ff
126 | 0
127 | 0
128 | C1
129 |
130 | true
131 | true
132 | false
133 | 2
134 | false
135 | false
136 | 0
137 | GATE_CUT - 10/0
138 | 10/0@1
139 |
140 |
141 | #92d050
142 | #92d050
143 | 0
144 | 0
145 | C17
146 |
147 | true
148 | true
149 | false
150 | 1
151 | false
152 | false
153 | 0
154 | ACTIVE - 11/0
155 | 11/0@1
156 |
157 |
158 | #808080
159 | #808080
160 | 0
161 | 0
162 | C1
163 |
164 | true
165 | true
166 | false
167 | 2
168 | false
169 | false
170 | 0
171 | THICKOX - 4/0
172 | 4/0@1
173 |
174 |
175 | #ffbbff
176 | #ffbbff
177 | 0
178 | 0
179 | C10
180 |
181 | true
182 | true
183 | false
184 | 1
185 | false
186 | false
187 | 0
188 | SDT - 88/0
189 | 88/0@1
190 |
191 |
192 | #00b0ff
193 | #00b0ff
194 | 0
195 | 0
196 | C5
197 |
198 | true
199 | true
200 | false
201 | 1
202 | false
203 | false
204 | 0
205 | NSELECT - 12/0
206 | 12/0@1
207 |
208 |
209 | #c00000
210 | #c00000
211 | 0
212 | 0
213 | C4
214 |
215 | true
216 | true
217 | false
218 | 1
219 | false
220 | false
221 | 0
222 | PSELECT - 13/0
223 | 13/0@1
224 |
225 |
226 | #cc6600
227 | #cc6600
228 | 0
229 | 0
230 | C1
231 |
232 | true
233 | true
234 | false
235 | 1
236 | false
237 | false
238 | 0
239 | SLVT - 97/0
240 | 97/0@1
241 |
242 |
243 | #6699ff
244 | #6699ff
245 | 0
246 | 0
247 | C1
248 |
249 | true
250 | true
251 | false
252 | 1
253 | false
254 | false
255 | 0
256 | LVT - 98/0
257 | 98/0@1
258 |
259 |
260 | #ffff00
261 | #ffff00
262 | 0
263 | 0
264 | C2
265 |
266 | true
267 | true
268 | false
269 | 3
270 | false
271 | false
272 | 0
273 | LISD - 17/0
274 | 17/0@1
275 |
276 |
277 | #ff8000
278 | #ff8000
279 | 0
280 | 0
281 | C3
282 |
283 | true
284 | true
285 | false
286 | 3
287 | false
288 | false
289 | 0
290 | LIG - 16/0
291 | 16/0@1
292 |
293 |
294 | #ff0088
295 | #ff0088
296 | 0
297 | 0
298 | C1
299 |
300 | true
301 | true
302 | false
303 | 2
304 | false
305 | true
306 | 0
307 | V0 - 18/0
308 | 18/0@1
309 |
310 |
311 | #0000ff
312 | #0000ff
313 | 0
314 | 0
315 | C15
316 |
317 | true
318 | true
319 | false
320 | 1
321 | false
322 | false
323 | 0
324 | M1 - 19/0
325 | 19/0@1
326 |
327 |
328 | #0000ff
329 | #0000ff
330 | 0
331 | 0
332 | C1
333 |
334 | true
335 | true
336 | false
337 | 1
338 | false
339 | false
340 | 0
341 | M1.txt - 19/2
342 | 19/2@1
343 |
344 |
345 | #0000ff
346 | #0000ff
347 | 0
348 | 0
349 | C1
350 |
351 | true
352 | true
353 | false
354 | 1
355 | false
356 | false
357 | 0
358 | M1.pin - 19/251
359 | 19/251@1
360 |
361 |
362 | #ff7700
363 | #ff7700
364 | 0
365 | 0
366 | C1
367 |
368 | true
369 | true
370 | false
371 | 2
372 | false
373 | true
374 | 0
375 | V1 - 21/0
376 | 21/0@1
377 |
378 |
379 | #00ffff
380 | #00ffff
381 | 0
382 | 0
383 | C16
384 |
385 | true
386 | true
387 | false
388 | 1
389 | false
390 | false
391 | 0
392 | M2 - 20/0
393 | 20/0@1
394 |
395 |
396 | #00ffff
397 | #00ffff
398 | 0
399 | 0
400 | C1
401 |
402 | true
403 | true
404 | false
405 | 1
406 | false
407 | false
408 | 0
409 | M2.txt - 20/2
410 | 20/2@1
411 |
412 |
413 | #00ffff
414 | #00ffff
415 | 0
416 | 0
417 | C1
418 |
419 | true
420 | true
421 | false
422 | 2
423 | false
424 | false
425 | 0
426 | M2.pin - 20/251
427 | 20/251@1
428 |
429 |
430 | #f0f0f0
431 | #f0f0f0
432 | 0
433 | 0
434 | C1
435 |
436 | true
437 | true
438 | false
439 | 2
440 | false
441 | true
442 | 0
443 | V2 - 25/0
444 | 25/0@1
445 |
446 |
447 | #ff00ff
448 | #ff00ff
449 | 0
450 | 0
451 | C14
452 |
453 | true
454 | true
455 | false
456 | 1
457 | false
458 | false
459 | 0
460 | M3 - 30/0
461 | 30/0@1
462 |
463 |
464 | #ff00ff
465 | #ff00ff
466 | 0
467 | 0
468 | C1
469 |
470 | true
471 | true
472 | false
473 | 1
474 | false
475 | false
476 | 0
477 | M3.txt - 30/2
478 | 30/2@1
479 |
480 |
481 | #ff00ff
482 | #ff00ff
483 | 0
484 | 0
485 | C1
486 |
487 | true
488 | true
489 | false
490 | 2
491 | false
492 | false
493 | 0
494 | M3.pin - 30/251
495 | 30/251@1
496 |
497 |
498 | #ffff77
499 | #ffff77
500 | 0
501 | 0
502 | C1
503 |
504 | true
505 | true
506 | false
507 | 2
508 | false
509 | true
510 | 0
511 | V3 - 35/0
512 | 35/0@1
513 |
514 |
515 | #aa5500
516 | #aa5500
517 | 0
518 | 0
519 | C2
520 |
521 | true
522 | true
523 | false
524 | 1
525 | false
526 | false
527 | 0
528 | M4 - 40/0
529 | 40/0@1
530 |
531 |
532 | #aa5500
533 | #aa5500
534 | 0
535 | 0
536 | C1
537 |
538 | true
539 | true
540 | false
541 | 1
542 | false
543 | false
544 | 0
545 | M4.txt - 40/2
546 | 40/2@1
547 |
548 |
549 | #aa5500
550 | #aa5500
551 | 0
552 | 0
553 | C1
554 |
555 | true
556 | true
557 | false
558 | 2
559 | false
560 | false
561 | 0
562 | M4.pin - 40/251
563 | 40/251@1
564 |
565 |
566 | #aa00ff
567 | #aa00ff
568 | 0
569 | 0
570 | C1
571 |
572 | true
573 | true
574 | false
575 | 2
576 | false
577 | true
578 | 0
579 | V4 - 45/0
580 | 45/0@1
581 |
582 |
583 | #00aaff
584 | #00aaff
585 | 0
586 | 0
587 | C3
588 |
589 | true
590 | true
591 | false
592 | 1
593 | false
594 | false
595 | 0
596 | M5 - 50/0
597 | 50/0@1
598 |
599 |
600 | #00aaff
601 | #00aaff
602 | 0
603 | 0
604 | C1
605 |
606 | true
607 | true
608 | false
609 | 1
610 | false
611 | false
612 | 0
613 | M5.txt - 50/2
614 | 50/2@1
615 |
616 |
617 | #00aaff
618 | #00aaff
619 | 0
620 | 0
621 | C1
622 |
623 | true
624 | true
625 | false
626 | 2
627 | false
628 | false
629 | 0
630 | M5.pin - 50/251
631 | 50/251@1
632 |
633 |
634 | #77ff77
635 | #77ff77
636 | 0
637 | 0
638 | C1
639 |
640 | true
641 | true
642 | false
643 | 2
644 | false
645 | true
646 | 0
647 | V5 - 55/0
648 | 55/0@1
649 |
650 |
651 | #ff0000
652 | #ff0000
653 | 0
654 | 0
655 | C10
656 |
657 | true
658 | true
659 | false
660 | 1
661 | false
662 | false
663 | 0
664 | M6 - 60/0
665 | 60/0@1
666 |
667 |
668 | #ff0000
669 | #ff0000
670 | 0
671 | 0
672 | C1
673 |
674 | true
675 | true
676 | false
677 | 1
678 | false
679 | false
680 | 0
681 | M6.txt - 60/2
682 | 60/2@1
683 |
684 |
685 | #ff0000
686 | #ff0000
687 | 0
688 | 0
689 | C1
690 |
691 | true
692 | true
693 | false
694 | 2
695 | false
696 | false
697 | 0
698 | M6.pin - 60/251
699 | 60/251@1
700 |
701 |
702 | #00ffff
703 | #00ffff
704 | 0
705 | 0
706 | C1
707 |
708 | true
709 | true
710 | false
711 | 2
712 | false
713 | true
714 | 0
715 | V6 - 65/0
716 | 65/0@1
717 |
718 |
719 | #ffaaff
720 | #ffaaff
721 | 0
722 | 0
723 | C20
724 |
725 | true
726 | true
727 | false
728 | 1
729 | false
730 | false
731 | 0
732 | M7 - 70/0
733 | 70/0@1
734 |
735 |
736 | #ffaaff
737 | #ffaaff
738 | 0
739 | 0
740 | C1
741 |
742 | true
743 | true
744 | false
745 | 1
746 | false
747 | false
748 | 0
749 | M7.txt - 70/2
750 | 70/2@1
751 |
752 |
753 | #ffaaff
754 | #ffaaff
755 | 0
756 | 0
757 | C1
758 |
759 | true
760 | true
761 | false
762 | 2
763 | false
764 | false
765 | 0
766 | M7.pin - 70/251
767 | 70/251@1
768 |
769 |
770 | #777777
771 | #777777
772 | 0
773 | 0
774 | C1
775 |
776 | true
777 | true
778 | false
779 | 2
780 | false
781 | true
782 | 0
783 | V7 - 75/0
784 | 75/0@1
785 |
786 |
787 | #00aa00
788 | #00aa00
789 | 0
790 | 0
791 | C21
792 |
793 | true
794 | true
795 | false
796 | 1
797 | false
798 | false
799 | 0
800 | M8 - 80/0
801 | 80/0@1
802 |
803 |
804 | #00aa00
805 | #00aa00
806 | 0
807 | 0
808 | C1
809 |
810 | true
811 | true
812 | false
813 | 1
814 | false
815 | false
816 | 0
817 | M8.txt - 80/2
818 | 80/2@1
819 |
820 |
821 | #00aa00
822 | #00aa00
823 | 0
824 | 0
825 | C1
826 |
827 | true
828 | true
829 | false
830 | 2
831 | false
832 | false
833 | 0
834 | M8.pin - 80/251
835 | 80/251@1
836 |
837 |
838 | #3377ff
839 | #3377ff
840 | 0
841 | 0
842 | C1
843 |
844 | true
845 | true
846 | false
847 | 2
848 | false
849 | true
850 | 0
851 | V8 - 85/0
852 | 85/0@1
853 |
854 |
855 | #aa00ff
856 | #aa00ff
857 | 0
858 | 0
859 | C22
860 |
861 | true
862 | true
863 | false
864 | 1
865 | false
866 | false
867 | 0
868 | M9 - 90/0
869 | 90/0@1
870 |
871 |
872 | #aa00ff
873 | #aa00ff
874 | 0
875 | 0
876 | C1
877 |
878 | true
879 | true
880 | false
881 | 1
882 | false
883 | false
884 | 0
885 | M9.tx - 90/2
886 | 90/2@1
887 |
888 |
889 | #aa00ff
890 | #aa00ff
891 | 0
892 | 0
893 | C1
894 |
895 | true
896 | true
897 | false
898 | 2
899 | false
900 | false
901 | 0
902 | M9.pin - 90/251
903 | 90/251@1
904 |
905 |
906 | #eeeeee
907 | #eeeeee
908 | 0
909 | 0
910 | C19
911 |
912 | true
913 | true
914 | false
915 | 3
916 | false
917 | false
918 | 0
919 | PAD - 96/0
920 | 96/0@1
921 |
922 |
923 | #aaffff
924 | #aaffff
925 | 0
926 | 0
927 | C18
928 | I0
929 | true
930 | true
931 | false
932 | 2
933 | false
934 | false
935 | 0
936 | SRAMDRC - 99/0
937 | 99/0@1
938 |
939 |
940 | #aaffff
941 | #aaffff
942 | 0
943 | 0
944 | C1
945 |
946 | true
947 | true
948 | false
949 | 1
950 | false
951 | false
952 | 0
953 | SRAMVT - 110/0
954 | 110/0@1
955 |
956 |
957 | #ddff00
958 | #ddff00
959 | 0
960 | 0
961 | I9
962 |
963 | false
964 | false
965 | true
966 |
967 | false
968 | false
969 | 0
970 | IP - 63/63
971 | 63/63@1
972 |
973 |
974 | #ffaa00
975 |
976 | 0
977 | 0
978 | I1
979 | I2
980 | true
981 | true
982 | false
983 | 2
984 | false
985 | false
986 | 0
987 | Boundary - 100/0
988 | 100/0@1
989 |
990 |
991 | #aaff00
992 |
993 | 0
994 | 0
995 | I1
996 | I2
997 | true
998 | true
999 | false
1000 | 2
1001 | false
1002 | false
1003 | 0
1004 | prBoundary - 235/0
1005 | 235/0@1
1006 |
1007 | GDS Layers
1008 |
1009 |
1010 | *
1011 |
1012 | 1
1013 |
1014 |
1015 |
1016 |
1017 | .
1018 |
1019 | 2
1020 | blank
1021 |
1022 |
1023 |
1024 | ...*...*...*...*
1025 | ................
1026 | .*...*...*...*..
1027 | ................
1028 | ...*...*...*...*
1029 | ................
1030 | .*...*...*...*..
1031 | ................
1032 | ...*...*...*...*
1033 | ................
1034 | .*...*...*...*..
1035 | ................
1036 | ...*...*...*...*
1037 | ................
1038 | .*...*...*...*..
1039 | ................
1040 |
1041 | 3
1042 | dots
1043 |
1044 |
1045 |
1046 | .*...*...*...*..
1047 | ................
1048 | ...*...*...*...*
1049 | ................
1050 | .*...*...*...*..
1051 | ................
1052 | ...*...*...*...*
1053 | ................
1054 | .*...*...*...*..
1055 | ................
1056 | ...*...*...*...*
1057 | ................
1058 | .*...*...*...*..
1059 | ................
1060 | ...*...*...*...*
1061 | ................
1062 |
1063 | 4
1064 | ndots
1065 |
1066 |
1067 |
1068 | ................
1069 | ...*............
1070 | ...*............
1071 | ...*............
1072 | *******.........
1073 | ...*............
1074 | ...*............
1075 | ...*............
1076 | ................
1077 | ................
1078 | ................
1079 | ................
1080 | ................
1081 | ................
1082 | ................
1083 | ................
1084 |
1085 | 5
1086 | custom plus
1087 |
1088 |
1089 |
1090 | ................
1091 | ................
1092 | ................
1093 | ................
1094 | *******.........
1095 | ................
1096 | ................
1097 | ................
1098 | ................
1099 | ................
1100 | ................
1101 | ................
1102 | ................
1103 | ................
1104 | ................
1105 | ................
1106 |
1107 | 6
1108 | custom minus
1109 |
1110 |
1111 |
1112 | ................................
1113 | ................................
1114 | ................................
1115 | ................................
1116 | ................................
1117 | ................................
1118 | ................................
1119 | ................................
1120 | ................................
1121 | ................................
1122 | ................................
1123 | ..........*...........*.........
1124 | ..........*.....*.....*.........
1125 | ...........*...*.*...*..........
1126 | ...........*...*.*...*..........
1127 | ............*.*...*.*...........
1128 | ............*.*...*.*...........
1129 | .............*.....*............
1130 | ................................
1131 | ................................
1132 | ................................
1133 | ................................
1134 | ................................
1135 | ................................
1136 | ................................
1137 | ................................
1138 | ................................
1139 | ................................
1140 | ................................
1141 | ................................
1142 | ................................
1143 | ................................
1144 |
1145 | 7
1146 | wellp
1147 |
1148 |
1149 |
1150 | ................................
1151 | ................................
1152 | ................................
1153 | ................................
1154 | ................................
1155 | ................................
1156 | ................................
1157 | ................................
1158 | ................................
1159 | ................................
1160 | ........***....***...***........
1161 | .........**....***...**.........
1162 | .........**....***...**.........
1163 | .........**....*.*...**.........
1164 | .........***..**.**..**.........
1165 | ..........**..**.**.**..........
1166 | ..........**..**.**.**..........
1167 | ..........**..**.**.**..........
1168 | ..........**..*...*.**..........
1169 | ...........***....***...........
1170 | ...........***....***...........
1171 | ...........***....***...........
1172 | ................................
1173 | ................................
1174 | ................................
1175 | ................................
1176 | ................................
1177 | ................................
1178 | ................................
1179 | ................................
1180 | ................................
1181 | ................................
1182 |
1183 | 8
1184 | wellBp
1185 |
1186 |
1187 |
1188 | *...*...*...*...
1189 | .*.*.*.*.*.*.*.*
1190 | ..*...*...*...*.
1191 | .*.*.*.*.*.*.*.*
1192 | *...*...*...*...
1193 | .*.*.*.*.*.*.*.*
1194 | ..*...*...*...*.
1195 | .*.*.*.*.*.*.*.*
1196 | *...*...*...*...
1197 | .*.*.*.*.*.*.*.*
1198 | ..*...*...*...*.
1199 | .*.*.*.*.*.*.*.*
1200 | *...*...*...*...
1201 | .*.*.*.*.*.*.*.*
1202 | ..*...*...*...*.
1203 | .*.*.*.*.*.*.*.*
1204 |
1205 | 9
1206 | cross1
1207 |
1208 |
1209 |
1210 | *.....*.*.....*.
1211 | .*...*...*...*..
1212 | ..*.*.....*.*...
1213 | ...*.......*....
1214 | ..*.*.....*.*...
1215 | .*...*...*...*..
1216 | *.....*.*.....*.
1217 | .......*.......*
1218 | *.....*.*.....*.
1219 | .*...*...*...*..
1220 | ..*.*.....*.*...
1221 | ...*.......*....
1222 | ..*.*.....*.*...
1223 | .*...*...*...*..
1224 | *.....*.*.....*.
1225 | .......*.......*
1226 |
1227 | 10
1228 | cross2
1229 |
1230 |
1231 |
1232 | *.............*.
1233 | .*...........*..
1234 | ..*.........*...
1235 | ...*.......*....
1236 | ....*.....*.....
1237 | .....*...*......
1238 | ......*.*.......
1239 | .......*........
1240 | ......*.*.......
1241 | .....*...*......
1242 | ....*.....*.....
1243 | ...*.......*....
1244 | ..*.........*...
1245 | .*...........*..
1246 | *.............*.
1247 | ...............*
1248 |
1249 | 11
1250 | cross3
1251 |
1252 |
1253 |
1254 | ...*...*...*...*
1255 | ..*...*...*...*.
1256 | .*...*...*...*..
1257 | *...*...*...*...
1258 | ...*...*...*...*
1259 | ..*...*...*...*.
1260 | .*...*...*...*..
1261 | *...*...*...*...
1262 | ...*...*...*...*
1263 | ..*...*...*...*.
1264 | .*...*...*...*..
1265 | *...*...*...*...
1266 | ...*...*...*...*
1267 | ..*...*...*...*.
1268 | .*...*...*...*..
1269 | *...*...*...*...
1270 |
1271 | 12
1272 | slash
1273 |
1274 |
1275 |
1276 | ...*.......*....
1277 | ..*.......*.....
1278 | .*.......*......
1279 | *.......*.......
1280 | .......*.......*
1281 | ......*.......*.
1282 | .....*.......*..
1283 | ....*.......*...
1284 | ...*.......*....
1285 | ..*.......*.....
1286 | .*.......*......
1287 | *.......*.......
1288 | .......*.......*
1289 | ......*.......*.
1290 | .....*.......*..
1291 | ....*.......*...
1292 |
1293 | 13
1294 | halfslash
1295 |
1296 |
1297 |
1298 | *...*...*...*...
1299 | .*...*...*...*..
1300 | ..*...*...*...*.
1301 | ...*...*...*...*
1302 | *...*...*...*...
1303 | .*...*...*...*..
1304 | ..*...*...*...*.
1305 | ...*...*...*...*
1306 | *...*...*...*...
1307 | .*...*...*...*..
1308 | ..*...*...*...*.
1309 | ...*...*...*...*
1310 | *...*...*...*...
1311 | .*...*...*...*..
1312 | ..*...*...*...*.
1313 | ...*...*...*...*
1314 |
1315 | 14
1316 | backSlash
1317 |
1318 |
1319 |
1320 | **......**......
1321 | ..*.......*.....
1322 | ...**......**...
1323 | .....*.......*..
1324 | ......**......**
1325 | *.......*.......
1326 | .**......**.....
1327 | ...*.......*....
1328 | ....**......**..
1329 | ......*.......*.
1330 | *......**......*
1331 | .*.......*......
1332 | ..**......**....
1333 | ....*.......*...
1334 | .....**......**.
1335 | .......*.......*
1336 |
1337 | 15
1338 | hZigZag
1339 |
1340 |
1341 |
1342 | *....*....*.....
1343 | *.....*....*....
1344 | .*....*.....*...
1345 | ..*....*....*...
1346 | ..*.....*....*..
1347 | ...*....*.....*.
1348 | ....*....*....*.
1349 | ....*.....*....*
1350 | *....*....*.....
1351 | *.....*....*....
1352 | .*....*.....*...
1353 | ..*....*....*...
1354 | ..*.....*....*..
1355 | ...*....*.....*.
1356 | ....*....*....*.
1357 | ....*.....*....*
1358 |
1359 | 16
1360 | vZigZag
1361 |
1362 |
1363 |
1364 | .....*....*....*
1365 | ....*....*.....*
1366 | ...*.....*....*.
1367 | ...*....*....*..
1368 | ..*....*.....*..
1369 | .*.....*....*...
1370 | .*....*....*....
1371 | *....*.....*....
1372 | .....*....*....*
1373 | ....*....*.....*
1374 | ...*.....*....*.
1375 | ...*....*....*..
1376 | ..*....*.....*..
1377 | .*.....*....*...
1378 | .*....*....*....
1379 | *....*.....*....
1380 |
1381 | 17
1382 | rvZigZag
1383 |
1384 |
1385 |
1386 | ...*.......*....
1387 | ................
1388 | ................
1389 | ................
1390 | .......*.......*
1391 | ................
1392 | ................
1393 | ................
1394 | ...*.......*....
1395 | ................
1396 | ................
1397 | ................
1398 | .......*.......*
1399 | ................
1400 | ................
1401 | ................
1402 |
1403 | 18
1404 | sdots
1405 |
1406 |
1407 |
1408 | .......*.......*
1409 | ................
1410 | ................
1411 | ................
1412 | ...*.......*....
1413 | ................
1414 | ................
1415 | ................
1416 | .......*.......*
1417 | ................
1418 | ................
1419 | ................
1420 | ...*.......*....
1421 | ................
1422 | ................
1423 | ................
1424 |
1425 | 19
1426 | nsdots
1427 |
1428 |
1429 |
1430 | ****************
1431 | ..*.......*.....
1432 | ..*.......*.....
1433 | ..*.......*.....
1434 | ****************
1435 | ......*.......*.
1436 | ......*.......*.
1437 | ......*.......*.
1438 | ****************
1439 | ..*.......*.....
1440 | ..*.......*.....
1441 | ..*.......*.....
1442 | ****************
1443 | ......*.......*.
1444 | ......*.......*.
1445 | ......*.......*.
1446 |
1447 | 20
1448 | brick
1449 |
1450 |
1451 |
1452 | *......*.......*
1453 | *......*.......*
1454 | *......*.......*
1455 | *......*.......*
1456 | *......*.......*
1457 | *......*.......*
1458 | *......*.......*
1459 | *......*.......*
1460 | *......*.......*
1461 | *......*.......*
1462 | *......*.......*
1463 | *......*.......*
1464 | *......*.......*
1465 | *......*.......*
1466 | *......*.......*
1467 | *......*.......*
1468 |
1469 | 21
1470 | vLine2
1471 |
1472 |
1473 |
1474 | ................
1475 | ...*...*...*...*
1476 | ................
1477 | .*...*...*...*..
1478 | ................
1479 | ...*...*...*...*
1480 | ................
1481 | .*...*...*...*..
1482 | ................
1483 | ...*...*...*...*
1484 | ................
1485 | .*...*...*...*..
1486 | ................
1487 | ...*...*...*...*
1488 | ................
1489 | .*...*...*...*..
1490 |
1491 | 22
1492 | rdots
1493 |
1494 |
1495 |
1496 | ................
1497 | .*...*...*...*..
1498 | ................
1499 | ...*...*...*...*
1500 | ................
1501 | .*...*...*...*..
1502 | ................
1503 | ...*...*...*...*
1504 | ................
1505 | .*...*...*...*..
1506 | ................
1507 | ...*...*...*...*
1508 | ................
1509 | .*...*...*...*..
1510 | ................
1511 | ...*...*...*...*
1512 |
1513 | 23
1514 | nrdots
1515 |
1516 |
1517 |
1518 | 1
1519 |
1520 |
1521 |
1522 | ***
1523 | 2
1524 | solid
1525 |
1526 |
1527 | ****..
1528 | 3
1529 | dashed
1530 |
1531 |
1532 | *..
1533 | 4
1534 | dots
1535 |
1536 |
1537 | ***..*..
1538 | 5
1539 | dashDot
1540 |
1541 |
1542 | **..
1543 | 6
1544 | shortDash
1545 |
1546 |
1547 | ****..**..
1548 | 7
1549 | doubleDash
1550 |
1551 |
1552 | *...
1553 | 8
1554 | hidden
1555 |
1556 |
1557 |
1558 | 0
1559 |
1560 |
1561 |
1562 |
1563 |
--------------------------------------------------------------------------------
/asap7.lyt:
--------------------------------------------------------------------------------
1 |
2 |
3 | ASAP 7
4 | ASAP 7 nm Technology
5 |
6 | 0.00025
7 | $(appdata_path)/tech/ASAP7
8 | asap7.lyp
9 | true
10 |
11 |
12 | 1
13 | true
14 | true
15 |
16 |
17 | true
18 | layer_map()
19 | true
20 | true
21 |
22 |
23 | true
24 | layer_map('BOUNDARY : 100/0';'M1 : 19/0';'M1.LABEL : 19/2';'M1.PIN : 19/251';'M2 : 20/0';'M2.LABEL : 20/2';'M2.PIN : 20/251';'M3 : 30/0';'M3.LABEL : 30/2';'M3.PIN : 30/251';'M4 : 40/0';'M4.LABEL : 40/2';'M4.PIN : 40/251';'M5 : 50/0';'M5.LABEL : 50/2';'M5.PIN : 50/251';'M6 : 60/0';'M6.LABEL : 60/2';'M6.PIN : 60/251';'M7 : 70/0';'M7.LABEL : 70/2';'M7.PIN : 70/251';'M8 : 80/0';'M8.LABEL : 80/2';'M8.PIN : 80/251';'M9 : 90/0';'M9.LABEL : 90/2';'M9.PIN : 90/251';'V0 : 18/0';'V0.LABEL : 29/0';'V1 : 21/0';'V2 : 25/0';'V3 : 35/0';'V4 : 45/0';'V5 : 55/0';'V6 : 65/0';'V7 : 75/0';'V8 : 85/0';'V9 : 95/0';'GATE : 7/0')
25 | 0.00025
26 | true
27 | #1
28 | true
29 | #1
30 | false
31 | #1
32 | true
33 | OUTLINE
34 | true
35 | PLACEMENT_BLK
36 | true
37 | REGIONS
38 | true
39 |
40 | 0
41 | true
42 | .PIN
43 | 2
44 | true
45 | .PIN
46 | 2
47 | true
48 | .FILL
49 | 5
50 | false
51 | .OBS
52 | 3
53 | false
54 | .BLK
55 | 4
56 | true
57 | .LABEL
58 | 2
59 | true
60 |
61 | 0
62 | true
63 |
64 | 0
65 | VIA_
66 | ./platforms/asap7/lef/asap7_tech_1x_201209.lef
67 | true
68 | default
69 | false
70 |
71 |
72 |
73 | false
74 | true
75 | true
76 | 64
77 | 0
78 | 1
79 | 0
80 | DATA
81 | 0
82 | 0
83 | BORDER
84 | layer_map()
85 | true
86 |
87 |
88 | 0.00025
89 | 1
90 | 100
91 | 100
92 | 0
93 | 0
94 | 0
95 | false
96 | false
97 | false
98 | true
99 | layer_map()
100 |
101 |
102 | 0
103 | 0.00025
104 | layer_map()
105 | true
106 | false
107 |
108 |
109 | 1
110 | 0.00025
111 | layer_map()
112 | true
113 | false
114 | true
115 |
116 |
117 |
118 |
119 |
120 |
121 | true
122 | false
123 | false
124 | false
125 | false
126 | false
127 | 8000
128 | 32000
129 | LIB
130 |
131 |
132 | 2
133 | false
134 | false
135 | 1
136 | *
137 | false
138 |
139 |
140 | 0
141 |
142 |
143 | false
144 | false
145 |
146 |
147 | 0
148 |
149 | true
150 |
151 |
152 |
153 | # Provide z stack information here
154 | #
155 | # Each line is one layer. The specification consists of a layer specification, a colon and arguments.
156 | # The arguments are named (like "x=...") or in serial. Parameters are separated by comma or blanks.
157 | # Named arguments are:
158 | #
159 | # zstart The lower z position of the extruded layer in µm
160 | # zstop The upper z position of the extruded layer in µm
161 | # height The height of the extruded layer in µm
162 | #
163 | # 'height', 'zstart' and 'zstop' can be used in any combination. If no value is given for 'zstart',
164 | # the upper level of the previous layer will be used.
165 | #
166 | # If a single unnamed parameter is given, it corresponds to 'height'. Two parameters correspond to
167 | # 'zstart' and 'zstop'.
168 | #
169 | # Examples:
170 | # 1: 0.5 1.5 # extrude layer 1/0 from 0.5 to 1.5 vertically
171 | # 1/0: 0.5 1.5 # same with explicit datatype
172 | # 1: zstop=1.5, zstart=0.5 # same with named parameters
173 | # 1: height=1.0, zstop=1.5 # same with z stop minus height
174 | # 1: 1.0 zstop=1.5 # same with height as unnamed parameter
175 | #
176 | # VARIABLES
177 | #
178 | # You can declare variables with:
179 | # var name = value
180 | #
181 | # You can use variables inside numeric expressions.
182 | # Example:
183 | # var hmetal = 0.48
184 | # 7/0: 0.5 0.5+hmetal*2 # 2x thick metal
185 | #
186 | # You cannot use variables inside layer specifications currently.
187 | #
188 | # CONDITIONALS
189 | #
190 | # You can enable or disable branches of the table using 'if', 'else', 'elseif' and 'end':
191 | # Example:
192 | # var thick_m1 = true
193 | # if thickm1
194 | # 1: 0.5 1.5
195 | # else
196 | # 1: 0.5 1.2
197 | # end
198 | 1: zstart = -0.1 zstop = 0.0 # NWELL
199 | 2: zstart = 0.0 zstop = 0.029 # FIN
200 | 11: zstart = 0.03 zstop = 0.031 # ACTIVE
201 | #11: zstart = 0.068 zstop = 0.069 # ACTIVESD
202 | 7: zstart = 0.03 zstop = 0.086 # GATE
203 | # 7: zstart = 0.0 zstop = 0.056 # FGATE
204 | 88: zstart = 0.069 zstop = 0.109 # SDT
205 | 16: zstart = 0.087 zstop = 0.136 # LIG
206 | 17: zstart = 0.109 zstop = 0.137 # LISD
207 | 19: zstart = 0.156 zstop = 0.1956 # M1
208 | 21: zstart = 0.1956 zstop = 0.2352 # V1
209 | 20: zstart = 0.2352 zstop = 0.2748 # M2
210 | 25: zstart = 0.2748 zstop = 0.3108 # V2
211 | 30: zstart = 0.3108 zstop = 0.3504 # M3
212 | 35: zstart = 0.3504 zstop = 0.3864 # V3
213 | 40: zstart = 0.3864 zstop = 0.4392 # M4
214 | 45: zstart = 0.4392 zstop = 0.4872 # V4
215 | 50: zstart = 0.4872 zstop = 0.54 # M5
216 | 55: zstart = 0.54 zstop = 0.588 # V5
217 | 60: zstart = 0.588 zstop = 0.6584 # M6
218 | 65: zstart = 0.6584 zstop = 0.7224 # V6
219 | 70: zstart = 0.7224 zstop = 0.7928 # M7
220 | 75: zstart = 0.7928 zstop = 0.8568 # V7
221 | 80: zstart = 0.8568 zstop = 0.9448 # M8
222 | 85: zstart = 0.9448 zstop = 1.0248 # V8
223 | 90: zstart = 1.0248 zstop = 1.1128 # M9
224 |
225 |
226 |
227 |
228 | DrainSource,V0,M1
229 | poly,V0,M1
230 | M1,V1,M2
231 | M2,V2,M3
232 | M3,V3,M4
233 | M4,V4,M5
234 | M5,V5,M6
235 | M6,V6,M7
236 | M7,V7,M8
237 | M8,V8,M9
238 | M9,V9,Pad
239 | DrainSource='1/0 - 9/0'
240 | poly='9/0'
241 | contact='18/0'
242 | M1='19/0'
243 | V1='21/0'
244 | M2='20/0'
245 | V2='25/0'
246 | M3='30/0'
247 | V3='35/0'
248 | M4='40/0'
249 | V4='45/0'
250 | M5='50/0'
251 | V5='55/0'
252 | M6='60/0'
253 | V6='65/0'
254 | M7='70/0'
255 | V7='75/0'
256 | M8='80/0'
257 | V8='85/0'
258 | M9='90/0'
259 | V9='95/0'
260 |
261 |
262 |
--------------------------------------------------------------------------------
/drc/drc_ASAP7.lydrc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | drc
6 |
7 |
8 |
9 | false
10 | false
11 | 0
12 |
13 | true
14 | drc_scripts
15 | tools_menu.drc.end
16 | dsl
17 | drc-dsl-xml
18 | #
19 | # DRC for ASAP7 : according to : asap7_drm_201207a.pdf
20 | # found on : https://github.com/The-OpenROAD-Project/asap7/blob/master/asap7PDK_r1p7/docs/asap7_drm_201207a.pdf
21 | #
22 | ##########################################################################################
23 | tstart = Time.now
24 |
25 | # optionnal for a batch launch : klayout -b r drc_ASAP7.lydrc -rd input=my_layout.gds -rd topcell=your_topcell -rd output=ASAP7_DRC.lyrdb
26 | if $input
27 | if $topcell
28 | source($input,$topcell)
29 | else
30 | source($input)
31 | end
32 | end
33 |
34 | if $output
35 | report("ASAP7 DRC runset", $output)
36 | else
37 | report("ASAP7 DRC runset", "ASAP7_DRC.lyrdb")
38 | end
39 |
40 | # DRC test to run or not
41 | ###############
42 | OFFGRID = false
43 | DEBUG = true
44 |
45 | # KLAYOUT setup
46 | ########################
47 | # Use a tile size of 1mm
48 | tiles(1000.um)
49 | # Use a tile border of 10 micron:
50 | tile_borders(1.um)
51 | #no_borders
52 |
53 | # Hierachical
54 | deep
55 |
56 | # Use 4 CPU cores
57 | threads(4)
58 | verbose(true)
59 |
60 | # layers definitions
61 | ########################
62 | nwell = input(1, 0)
63 | fin = input(2, 0)
64 | gate = input(7, 0)
65 | gcut = input(10, 0)
66 | active = input(11, 0)
67 | sdt = input(88, 0)
68 | nselect = input(12, 0)
69 | pselect = input(13, 0)
70 | slvt = input(97, 0)
71 | lvt = input(98, 0)
72 | sramdrc = input(99, 0)
73 | sramvt = input(110, 0)
74 | dummy = input(8, 0)
75 | lig = input(16, 0)
76 | lisd = input(17, 0)
77 | v0 = input(18, 0)
78 | m1 = input(19, 0)
79 | v1 = input(21, 0)
80 | m2 = input(20, 0)
81 | v2 = input(25, 0)
82 | m3 = input(30, 0)
83 | v3 = input(35, 0)
84 | m4 = input(40, 0)
85 | v4 = input(45, 0)
86 | m5 = input(50, 0)
87 | v5 = input(55, 0)
88 | m6 = input(60, 0)
89 | v6 = input(65, 0)
90 | m7 = input(70, 0)
91 | v7 = input(75, 0)
92 | m8 = input(80, 0)
93 | v8 = input(85, 0)
94 | m9 = input(90, 0)
95 | v9 = input(95, 0)
96 | pad = input(96, 0)
97 |
98 | # DRC section
99 | ########################
100 | info("DRC section")
101 |
102 | # splits a layer classes with increasing min dimensions
103 | def classify_by_width(layer, *dimensions)
104 | dimensions.collect { |d| layer = layer.sized(-0.5 * (d - 1.dbu)).sized(0.5 * (d - 1.dbu)) }
105 | end
106 | # Define a new custom function that selects polygons by their number of holes:
107 | # It will return a new layer containing those polygons with min to max holes.
108 | # max can be nil to omit the upper limit.
109 | class DRC::DRCLayer
110 | def with_holes(min, max)
111 | new_data = RBA::Region::new
112 | self.data.each do |p|
113 | if p.holes >= (min || 0) && (!max || p.holes <= max)
114 | new_data.insert(p)
115 | end
116 | end
117 | DRC::DRCLayer::new(@engine, new_data)
118 | end
119 | end
120 |
121 | # construction layers :
122 | gatenogcut = gate - gcut
123 | (activesram , activenosram) = active.andnot(sramdrc)
124 | (ligsram , lignosram) = lig.andnot(sramdrc)
125 |
126 | ### WELL
127 | nwell.width(108.nm, projection).with_angle(90).output("WELL.W.1", "WELL.W.1 : Min. horizontal width of WELL : 108nm")
128 | nwell.width(54.nm, projection).with_angle(0).output("WELL.W.2", "WELL.W.2 : Min. vertical width of WELL : 54nm")
129 | nwell.space(108.nm, projection).with_angle(0).output("WELL.S.1", "WELL.S.1 : Min. vertical spacing between WELL : 108nm")
130 | nwell.space(54.nm, projection).with_angle(90).output("WELL.S.2", "WELL.S.2 : Min. horizontal spacing between WELL : 54nm")
131 | nwell.with_area(0 .. 0.005832).output("WELL.A.1A", "WELL.A.1A : Min. area of WELL : 5832nm2")
132 | nwell.holes.with_area(0 .. 0.005832).output("WELL.A.1B", "WELL.A.1B : Min. enclosed area of WELL : 5832nm2")
133 | nwell.enclosing(gatenogcut, 7.nm, projection).with_angle(90).output("WELL.GATE.EX.1", "WELL.GATE.EX.1 : Min. horizontal extension of WELL past GATE (not cut by GCUT layer): 7nm")
134 | nwell.not(sramdrc).enclosing(gatenogcut, 7.nm, projection).with_angle(0).output("WELL.GATE.EX.2", "WELL.GATE.EX.2 : Min. vertical extension of WELL past GATE (not cut by GCUT layer): 7nm")
135 |
136 | ### FIN
137 | fin.edges.with_angle(90).without_length(7.nm).output("FIN.W.1a", "FIN.W.1 : Exact vertical width of FIN : 7nm")
138 | fin.without_bbox_height(7.nm).output("FIN.W.1", "FIN.W.1 : Exact vertical width of FIN : 7nm")
139 | #fin.drc(if_all(angle == 90, length != 7.nm)).output("FIN.W.1c", "FIN.W.1 : Exact vertical width of FIN : 7nm")
140 | fin.drc(width(projection) < 108.nm).with_angle(90).output("FIN.W.2", "FIN.W.2 : Min. horizontal width of WELL : 108nm")
141 | fin.space(35.nm, projection).polygons.not(fin).without_bbox_height(20.nm).sized(0,3.5.nm).output("FIN.S.1", "FIN.S.1 : Exact vertical FIN pitch : 27nm")
142 | fin.corners(0..90).sized(1.nm).output("FIN.AUX.1", "FIN.AUX.1 : FIN may not bend")
143 |
144 | ### GATE
145 | gate.drc(width(projection) != 20.nm).with_angle(90).output("GATE.W.1", "GATE.W.1 : Exact horizontal width of GATE : 20nm")
146 | gate.width(40.nm, projection).with_angle(0).output("GATE.W.2", "GATE.W.2 : Min. vertical width of GATE : 40nm")
147 | gate.space(100.nm, projection).polygons.not(fin).without_bbox_width(34.nm).sized(0,10.nm).output("GATE.S.1", "GATE.S.1 : Exact horizontal GATE pitch : 54nm")
148 | gate.space(34.nm, projection).with_angle(90).output("GATE.S.3", "GATE.S.3 : Min. horizontal spacing between GATE : 34nm")
149 | gatenogcut.not(sramdrc).sized(55.nm,0).not_interacting(gate).output("GATE.S.2", "GATE.S.2 : Every GATE (not cut by GCUT and not interacting with the layer SRAMDRC) must have at least one other GATE within 54 nm of its surrounding along the horizontal axis : 54nm")
150 | gate.corners(0..90).sized(1.nm).output("GATE.AUX.1", "GATE.AUX.1 : GATE may not bend")
151 | gate.sized(1.dbu,1.mm).and(gate).with_holes(2,nil).output("GATE.AUX.2", "GATE.AUX.2 : GATE may not be discontinuous along the vertical axis")
152 | active.edges.with_angle(90).and(gate).output("GATE.AUX.3", "GATE.AUX.3 : ACTIVE layer vertical edge may not lie inside, or coincide with, the GATE layer")
153 | gate.enclosing(gate.and(active), 4.nm, projection).polygons.without_area(0).output("GATE.ACTIVE.EX.1", "GATE.ACTIVE.EX.1 : Min. vertical extension of GATE (not cut by GCUT) past ACTIVE : 4nm")
154 | active.interacting(gate).enclosing(gate.and(active), 25.nm, projection).polygons.without_area(0).output("GATE.ACTIVE.EX.2", "GATE.ACTIVE.EX.2 : Min. horizontal extension of ACTIVE interacting with GATE (not cut by GCUT layer) past GATE (not cut by GCUT layer) : 20nm")
155 | gatenogcut.separation(active, 9.nm, projection).polygons.without_area(0).not_interacting(gate & active).output("GATE.ACTIVE.S.4", "GATE.ACTIVE.S.4 : Min. horizontal spacing between ACTIVE and GATE (not cut by GCUT and not interacting with ACTIVE) : 9nm")
156 |
157 | ### ACTIVE
158 | active.enclosing(fin,10.nm, projection).polygons.without_area(0).output("ACTIVE.FIN.EX.1", "ACTIVE.FIN.EX.1 : Min. vertical extension of ACTIVE past FIN : 10nm")
159 | active.width(27.nm, projection).with_angle(0).output("ACTIVE.W.1", "ACTIVE.W.1 : Min. vertical width of ACTIVE : 27nm")
160 | active.without_bbox_height(27.nm).and(active.without_bbox_height(2*27.nm)).and(active.without_bbox_height(3*27.nm)).and(active.without_bbox_height(4*27.nm)).and(active.without_bbox_height(5*27.nm)).and(active.without_bbox_height(6*27.nm)).and(active.without_bbox_height(7*27.nm)).and(active.without_bbox_height(8*27.nm)).and(active.without_bbox_height(9*27.nm)).and(active.without_bbox_height(10*27.nm)).and(active.without_bbox_height(11*27.nm)).and(active.without_bbox_height(12*27.nm)).output("ACTIVE.W.2" , "ACTIVE.W.2 : ACTIVE layer vertical width increment is an integer multiple of : 27nm")
161 | active.width(16.nm, projection).with_angle(90).output("ACTIVE.W.3", "ACTIVE.W.3 : Min. horizontal width of ACTIVE : 16nm")
162 | active.space(27.nm, projection).with_angle(0).output("ACTIVE.S.1", "ACTIVE.S.1 : Min. vertical spacing between ACTIVE : 27nm")
163 | active.interacting(gate).space(92.nm, projection).edges.with_angle(90).extended_out(30.nm).not(lisd).output("ACTIVE.S.2A", "ACTIVE.S.2A : Min. horizontal spacing between ACTIVE layers forming source/drain regions (of different transistors) : 92nm")
164 | active.space(38.nm, projection).with_angle(90).output("ACTIVE.S.2B", "ACTIVE.S.2B : Min. horizontal spacing between ACTIVE : 38nm")
165 | activenosram.separation(nwell, 27.nm, projection).output("ACTIVE.WELL.S.4", "ACTIVE.WELL.S.4 : Min. spacing of ACTIVE to WELL : 27nm")
166 | activesram.separation(nwell, 13.5.nm, projection).output("SRAM.ACTIVE.WELL.S.5", "SRAM.ACTIVE.WELL.S.5 : Min. spacing of ACTIVE in SRAM to WELL : 13.5nm")
167 | nwell.enclosing(activenosram, 27.nm, projection).polygons.without_area(0).output("ACTIVE.WELL.EN.1", "ACTIVE.WELL.EN.1 : Min. enclosure of ACTIVE by WELL : 27nm")
168 | nwell.enclosing(activesram, 13.5.nm, projection).polygons.without_area(0).output("SRAM.ACTIVE.WELL.EN.2", "SRAM.ACTIVE.WELL.EN.2 : Min. enclosure of ACTIVE in SRAM by WELL : 13.5nm")
169 | activenosram.with_area(0 .. 0.000864).output("ACTIVE.A.1A", "ACTIVE.A.1A : Min. area of ACTIVE : 864nm2")
170 | activenosram.holes.with_area(0 .. 0.000864).output("ACTIVE.A.1B", "ACTIVE.A.1B : Min. enclosed area of ACTIVE : 864nm2")
171 | activesram.with_area(0 .. 0.000432).output("SRAM.ACTIVE.A.1A", "SRAM.ACTIVE.A.1A : Min. area of ACTIVE in SRAM : 432nm2")
172 | activesram.holes.with_area(0 .. 0.000432).output("SRAM.ACTIVE.A.1B", "SRAM.ACTIVE.A.1B : Min. enclosed area of ACTIVE in SRAM : 432nm2")
173 | active.not(nselect + pselect).output("ACTIVE.AUX.1", "ACTIVE.AUX.1 : ACTIVE must always be enclosed by NSELECT or PSELECT")
174 | active.edges.and((nselect + pselect).edges).output("ACTIVE.AUX.1_edges", "ACTIVE.AUX.1 : ACTIVE must always be enclosed by NSELECT or PSELECT, such that no ACTIVE layer edge(s) coincide with NSELECT or PSELECT layer edge(s)")
175 | sramdrc.edges.and(active).output("SRAM.ACTIVE.AUX.2", "SRAM.ACTIVE.AUX.2 : ACTIVE not belonging to an SRAM cell may not touch the SRAMDRC layer")
176 | active.notch(1.mm, projection).with_angle(0).output("ACTIVE.AUX.3", "ACTIVE.AUX.3 : notch in ACTIVE along vertical axis is not allowed")
177 | (active.interacting(gate) & nselect).sized(30.um).not_interacting(active & pselect - nwell).size(-30.um).output("ACTIVE.LUP.1" , "ACTIVE.LUP.1 : Maximum distance, to prevent latch-up, between ACTIVE forming a MOS device and ACTIVE forming a bulk/substrate contact within the same WELL/substrate : 30um")
178 | (active.interacting(gate) & pselect).sized(30.um).not_interacting(active & nselect & nwell).size(-30.um).output("ACTIVE.LUP.1" , "ACTIVE.LUP.1 : Maximum distance, to prevent latch-up, between ACTIVE forming a MOS device and ACTIVE forming a bulk/substrate contact within the same WELL/substrate : 30um")
179 |
180 | ### GCUT
181 | gcut.width(17.nm, projection).with_angle(0).output("GCUT.W.1", "GCUT.W.1 : Min. vertical width of GCUT : 17nm")
182 | gcut.separation(active, 4.nm, projection).output("GCUT.ACTIVE.S.1", "GCUT.ACTIVE.S.1 : Min. vertical spacing between GCUT and channel : 4nm")
183 | gcut.enclosing(gate.and(gcut), 17.nm, projection).with_angle(90).polygons.without_area(0).output("GCUT.GATE.EX.1", "GCUT.GATE.EX.1 : Min. horizontal extension of GCUT past GATE : 17nm")
184 | gcut.separation(gate, 17.nm, projection).output("GCUT.GATE.S.2", "GCUT.GATE.S.2 : Minimum spacing of GCUT to GATE : 17nm")
185 | gcut.space(35.nm, projection).with_angle(0).output("GCUT.S.3", "GCUT.S.3 : Min. vertical spacing between GCUT : 35nm")
186 | gcut.not_interacting(gate).output("GCUT.AUX.1", "GCUT.AUX.1 : GCUT layer may not exist without the layer GATE")
187 | gcut.edges.with_angle(90).and(gate).output("GCUT.AUX.2", "GCUT.AUX.2 : GCUT layer vertical edge may not lie inside, or coincide with, the GATE layer")
188 | gcut.edges.and(active).output("GCUT.AUX.3", "GCUT.AUX.3 : GCUT may not interact with channel")
189 |
190 | ### NSELECT/PSELECT LVT/SLVT/SRAMVT
191 | nselect.width(108.nm, projection).with_angle(90).output("NSELECT.W.1", "NSELECT.W.1 : Min. horizontal width of NSELECT : 108nm")
192 | nselect.width(54.nm, projection).with_angle(0).output("NSELECT.W.2", "NSELECT.W.2 : Min. vertical width of NSELECT : 54nm")
193 | nselect.enclosing(activenosram, 46.nm, projection).with_angle(90).output("NSELECT.ACTIVE.EN.1", "NSELECT.ACTIVE.EN.1 : Min. horizontal enclosure of ACTIVE by NSELECT : 46nm")
194 | nselect.enclosing(activenosram, 27.nm, projection).with_angle(0).output("NSELECT.ACTIVE.EN.2", "NSELECT.ACTIVE.EN.2 : Min. vertical enclosure of ACTIVE by NSELECT : 27nm")
195 | nselect.enclosing(activesram, 13.5.nm, projection).output("SRAM.NSELECT.ACTIVE.EN.3-4", "SRAM.NSELECT.ACTIVE.EN.3-4 : Min. enclosure of ACTIVE in SRAM by NSELECT : 13.5nm")
196 | nselect.enclosing(gatenogcut, 7.nm, projection).with_angle(90).polygons.without_area(0).output("NSELECT.GATE.EX.1-2", "NSELECT.GATE.EX.1-2 : Min. horizontal extension of NSELECT past GATE : 7nm")
197 | pselect.width(108.nm, projection).with_angle(90).output("PSELECT.W.1", "PSELECT.W.1 : Min. horizontal width of PSELECT : 108nm")
198 | pselect.width(54.nm, projection).with_angle(0).output("PSELECT.W.2", "PSELECT.W.2 : Min. vertical width of PSELECT : 54nm")
199 | pselect.enclosing(activenosram, 46.nm, projection).with_angle(90).output("PSELECT.ACTIVE.EN.1", "PSELECT.ACTIVE.EN.1 : Min. horizontal enclosure of ACTIVE by PSELECT : 46nm")
200 | pselect.enclosing(activenosram, 27.nm, projection).with_angle(0).output("PSELECT.ACTIVE.EN.2", "PSELECT.ACTIVE.EN.2 : Min. vertical enclosure of ACTIVE by PSELECT : 27nm")
201 | pselect.enclosing(activesram, 13.5.nm, projection).output("SRAM.PSELECT.ACTIVE.EN.3-4", "SRAM.PSELECT.ACTIVE.EN.3-4 : Min. enclosure of ACTIVE in SRAM by PSELECT : 13.5nm")
202 | pselect.enclosing(gatenogcut, 7.nm, projection).with_angle(90).polygons.without_area(0).output("PSELECT.GATE.EX.1-2", "PSELECT.GATE.EX.1-2 : Min. horizontal extension of PSELECT past GATE : 7nm")
203 | (nselect & pselect).output("NSELECT.PSELECT.AUX.1", "NSELECT.PSELECT.AUX.1 : NSELECT and PSELECT may not overlap")
204 | ((lvt & slvt) + (lvt & sramvt) +(slvt & sramvt)).output("VT.AUX.2", "VT.AUX.2 : VT layers (LVT, SLVT, and SRAMVT) may not overlap")
205 |
206 | ### SDT
207 | sdt.width(24.nm, projection).with_angle(90).output("SDT.W.1", "SDT.W.1 : Min. horizontal width of SDT : 24nm")
208 | sdt.not(sramdrc).width(27.nm, projection).with_angle(0).output("SDT.W.2", "SDT.W.2 : Min. vertical width of SDT : 27nm")
209 | sdt.without_bbox_height(27.nm).and(sdt.without_bbox_height(2*27.nm)).and(sdt.without_bbox_height(3*27.nm)).and(sdt.without_bbox_height(4*27.nm)).and(sdt.without_bbox_height(5*27.nm)).and(sdt.without_bbox_height(6*27.nm)).and(sdt.without_bbox_height(7*27.nm)).and(sdt.without_bbox_height(8*27.nm)).and(sdt.without_bbox_height(9*27.nm)).and(sdt.without_bbox_height(10*27.nm)).and(sdt.without_bbox_height(11*27.nm)).and(sdt.without_bbox_height(12*27.nm)).output("SDT.W.3" , "SDT.W.3 : SDT vertical height increment is an integer multiple of : 27nm")
210 | sdt.and(sramdrc).width(17.nm, projection).with_angle(0).output("SRAM.SDT.W.4", "SRAM.SDT.W.4 : Min. vertical width of SDT in SRAM : 17nm")
211 | sdt.space(30.nm, projection).with_angle(90).output("SDT.S.1", "SDT.S.1 : Min. vertical spacing between SDT : 30nm")
212 | sdt.separation(gate, 5.nm, projection).output("SDT.GATE.S.2", "SDT.GATE.S.2 : Min. horizontal spacing between SDT and GATE : 5nm")
213 |
214 | ### LISD
215 | lisd.width(24.nm).output("LISD.W.1", "LISD.W.1 : Min. width of LISD : 24nm")
216 | lisd.space(18.nm).polygons.not_interacting(lisd.edges.with_length(0..36.nm)).output("LISD.S.1", "LISD.S.1 : Min. spacing between two LISD' edges, when both edges are > 36 nm : 18nm")
217 | lisd.space(25.nm).polygons.not_interacting(lisd.edges.with_length(36.nm..100.mm)).output("LISD.S.2", "LISD.S.2 : Min. spacing between two LISD' edges, when one edge is > 36 nm : 25nm")
218 | lisd.space(27.nm, euclidian).polygons.not_interacting(lisd.edges.with_length(36.nm..100.mm)).output("LISD.S.3-4", "LISD.S.3-4 : Min. spacing between two LISD' edges, when both edge are =< 36 nm : 27nm")
219 | lisd.with_area(0 .. 0.000648).output("LISD.A.1", "LISD.A.1 : Min. area of LISD : 648nm2")
220 | lisd.and(sramdrc).with_area(0).output("SRAM.LISD.AUX.1", "SRAM.LISD.AUX.1 : LISD, which are either completely outside the SRAMDRC or which do not intersect the SRAMDRC, may not touch the SRAMDRC")
221 |
222 | ### LIG
223 | lig.width(16.nm).output("LIG.W.1", "LIG.W.1 : Min. width of LIG : 16nm")
224 | lig.space(18.nm).polygons.not_interacting(lig.edges.with_length(0..36.nm)).output("LIG.S.1", "LIG.S.1 : Min. spacing between two LIG' edges, when both edges are > 36 nm : 18nm")
225 | lig.space(25.nm).polygons.not_interacting(lig.edges.with_length(36.nm..100.mm)).output("LISD.S.2", "LIG.S.2 : Min. spacing between two LIG' edges, when one edge is > 36 nm : 25nm")
226 | lig.space(27.nm).polygons.not_interacting(lig.edges.with_length(0..24.nm)).not_interacting(lig.edges.with_length(36.nm..100.mm)).output("LIG.S.3", "LIG.S.3 : Min. spacing between two LIG' edges, when both edges are >=24nm and =< 36 nm : 27nm")
227 | lig.space(31.nm, euclidian).polygons.not_interacting(lisd.edges.with_length(24.nm..100.mm)).output("LIG.S.4-5", "LISD.S.4-5 : Min. spacing between two LIG' edges, when both edge are =< 24 nm : 31nm")
228 | lig.separation(lisd, 14.nm, projection).output("LIG.LISD.S.6" "LIG.LISD.S.6 : Min. spacing between LIG and LISD not on the same net : 14nm")
229 | lig.separation(lisd, 15.nm, euclidian).output("LIG.LISD.S.7" "LIG.LISD.S.7 : Min. corner-to-corner spacing between LISD and LIG not on the same net : 15nm")
230 | lig.separation(sdt, 14.nm, projection).output("LIG.SDT.S.8" "LIG.SDT.S.8 : Min. spacing between LIG and SDT not on the same net : 14nm")
231 | lig.separation(gatenogcut, 14.nm, projection).with_angle(0).output("LIG.LISD.S.9A" "LIG.LISD.S.9A : Min. vertical spacing between LIG and GATE (not cut using GCUT) : 14nm")
232 | lig.separation(gatenogcut, 17.nm, projection).with_angle(90).output("LIG.LISD.S.9B" "LIG.LISD.S.9B : Min. horizontal spacing between LIG and GATE (not cut using GCUT) : 17nm")
233 | lig.separation(gatenogcut & active, 5.nm, euclidian).output("LIG.GATE.S.10" "LIG.GATE.S.10 : Min. spacing between LIG and GATE (not cut using GCUT) forming a channel : 5nm")
234 | lig.separation(gcut, 5.nm, euclidian).with_angle(0).output("LIG.GCUT.S.11" "LIG.GCUT.S.11 : Min. vertical spacing between LIG and GCUT : 5nm")
235 | lig.with_area(0 .. 0.000324).output("LIG.A.1", "LIG.A.1 : Min. area of LIG : 324nm2")
236 | (lig + lisd).with_area(0 .. 0.000128).output("LIG.LISD.A.2", "LIG.LISD.A.2 : Min. area of overlap between LIG and LISD : 128nm2")
237 | (lignosram + gatenogcut).with_area(0 .. 0.000320).output("LIG.GATE.A.3", "LIG.GATE.A.3 : Min. area of overlap between LIG and and GATE (not cut using GCUT) : 320nm2")
238 | (ligsram + gatenogcut).with_area(0 .. 0.000240).output("LIG.GATE.A.4", "LIG.GATE.A.4 : Min. area of overlap between LIG in SRAM and and GATE (not cut using GCUT) : 240nm2")
239 | lignosram.edges.with_angle(90).and(gate).output("LIG.GATE.AUX.1", "LIG.GATE.AUX.1 : LIG vertical edge may not lie inside, or coincide with, the GATE layer")
240 | ligsram.with_area(0).output("SRAM.LIG.AUX.2", "SRAM.LIG.AUX.2 : LIG, which are either completely outside the SRAMDRC or which do not intersect the SRAMDRC, may not touch the SRAMDRC")
241 | lignosram.enclosing(gatenogcut, 1.nm, projection).polygons.without_area(0).output("LIG.GATE.EX.1", "LIG.GATE.EX.1 : Min. extension of LIG past GATE (not cut using GCUT) : 1nm")
242 | (lig + lisd).width(8.nm).output("LIG.LISD.OV.1", "LIG.LISD.OV.1 : Min. overlap between LIG and LISD connected together : 8nm")
243 | (ligsram + gatenogcut).width(15.nm).output("SRAM.LIG.GATE.OV.2", "SRAM.LIG.GATE.OV.2 : Min. overlap between LIG in SRAM and GATE (not cut using GCUT) : 15nm")
244 |
245 |
246 | ### V0
247 | # rule V0.W.1 not checked for the instance along the length of M1
248 | v0.width(18.nm).output("V0.W.1", "V0.W.1 : Min. width of V0 : 18nm")
249 | v0.space(18.nm, projection).output("V0.S.1", "V0.S.1 : Min. spacing between V0 instances [on the same M1 track or on parallel M1 tracks, if they are fully or partially aligned with each other : 18nm")
250 | v0spaceortho = v0.space(27.nm, projection).polygons
251 | v0.space(27.nm, euclidian).polygons.not_interacting(v0spaceortho).output("V0.S.1", "V0.S.1 : Min. spacing between V0 instances on parallel M1 tracks, if they are not aligned with each other : 27nm")
252 | m1ovlp5v0 = (m1 & v0.sized(5.nm) - v0).sized(-2.5.nm+1.dbu).sized(2.5.nm-1.dbu)
253 | v0.edges.and(m1ovlp5v0).space(23.nm, euclidian).polygons.not(v0spaceortho).output("V0.S.2", "V0.S.2 : Min. corner-to-corner spacing between two V0 instances—both with a 5 nm M1 end-cap : 23nm")
254 | v0.edges.not_interacting(m1ovlp5v0).space(30.nm, euclidian).output("V0.S.3", "V0.S.3 : Min. corner-to-corner spacing between two V0 instances—both without a 5 nm M1 end-cap : 30nm")
255 | v0.edges.and(m1ovlp5v0).separation(v0.edges.not_interacting(m1ovlp5v0), 27.nm, euclidian).output("V0.S.4", "V0.S.4 : Min. corner-to-corner spacing between two V0 instances—one with and another without, a 5 nm M1 end-cap : 27nm")
256 | v0.not_interacting(m1ovlp5v0.sized(2.dbu)).output("V0.M1.EN.1", "V0.M1.EN.1 : enclosure of V0 by M1 on one side : 5nm")
257 | v0spaceortho.forget
258 | m1ovlp5v0.forget
259 | (lisd.enclosing(v0.not_interacting(lig), 3.nm, projection, two_connected_sides_allowed).edges - lisd.enclosing(v0.not_interacting(lig), 3.nm, projection, one_side_allowed).edges).output("V0.LISD.EN.2", "V0.LISD.EN.2 : Min. enclosure of V0 (interacting with LISD, but not with LIG) by LISD on at least two opposite sides is 3 nm and such a V0 must lie completely inside LISD : 3nm")
260 | lisd.enclosing(v0.interacting(lig), 3.nm, projection, one_side_allowed).output("V0.LISD.EN.3", "V0.LISD.EN.3 : Min. enclosure of V0 (sharing some, but not all its area with LISD) by LISD (interacting with LIG) on at least two opposite sides is 3 nm and such a V0 does not need to lie completely inside LISD : 3nm")
261 | (v0.enclosing(lig, 1.nm, projection, two_connected_sides_allowed).edges - v0.enclosing(lig, 1.nm, projection, one_side_allowed).edges).not(lig).output("V0.LIG.EN.4", "V0.LIG.EN.4 : Min. enclosure of LIG by V0 (interacting with LIG and not inside LISD) on two opposite sides is 1 nm : 1nm")
262 | (v0 & lig).with_area(0 .. 0.000288).output("V0.LIG.A.1", "V0.LIG.A.1 : Min. area of overlap between V0 (interacting with LIG and not inside LISD) and LIG : 288nm2")
263 | ((v0 - m1) + (v0 - lig.sized(1.nm) - lisd)).output("V0.AUX.1-2" "V0.AUX.1-2 : V0 must always interact with M1 and [LISD|LIG]")
264 | v0.not_interacting(m1.enclosing(v0, 1.dbu, projection, two_opposite_sides_allowed).edges).output("V0.M1.AUX.3", "V0.M1.AUX.3 : V0 must exactly be the same width as M1 along the direction perpendicular to the M1 length")
265 |
266 |
267 | ### M1
268 | m1.width(18.nm).output("M1.W.1", "M1.W.1 : Min. width of M1 : 18nm")
269 | m1.space(18.nm).polygons.not_interacting(m1.edges.with_length(0..36.nm)).output("M1.S.1", "M1.S.1 : Min. spacing between two M1' edges, when both edges are > 36 nm : 18nm")
270 | m1.space(25.nm).polygons.not_interacting(m1.edges.with_length(36.nm..100.mm)).output("M1.S.2", "M1.S.2 : Min. spacing between two M1' edges, when one edge is > 36 nm : 25nm")
271 | m1.space(27.nm).polygons.not_interacting(m1.edges.with_length(0..24.nm)).not_interacting(m1.edges.with_length(36.nm..100.mm)).output("M1.S.3", "M1.S.3 : Min. spacing between two M1' edges, when both edges are >=24nm and =< 36 nm : 27nm")
272 | m1.space(31.nm).polygons.not_interacting(m1.edges.with_length(24.nm..100.mm)).output("M1.S.4-5", "M1.S.4-5 : Min. spacing between two M1' edges, when both edge are =< 24 nm : 31nm")
273 | m1long = m1.space(20.nm, projection).polygons.interacting(m1.edges.with_length(36.nm..100.mm))
274 | m1.space(20.nm, euclidian).polygons.not_interacting(m1long).output("M1.S.6", "M1.S.6 : Min. corner-to-corner spacing between two M1 : 20nm")
275 | m1long.forget
276 | m1.with_area(0 .. 0.000504).output("M1.A.1", "M1.A.1 : Min. area of M1 : 504nm2")
277 |
278 | ### M2
279 | m2.width(18.nm).output("M2.W.1", "M2.W.1 : Min. width of M2 : 18nm")
280 | m2.space(18.nm).polygons.not_interacting(m2.edges.with_length(0..36.nm)).output("M2.S.1", "M2.S.1 : Min. spacing between two M2' edges, when both edges are > 36 nm : 18nm")
281 | m2.space(25.nm).polygons.not_interacting(m2.edges.with_length(36.nm..100.mm)).output("M2.S.2", "M2.S.2 : Min. spacing between two M2' edges, when one edge is > 36 nm : 25nm")
282 | m2.space(27.nm).polygons.not_interacting(m2.edges.with_length(0..24.nm)).not_interacting(m2.edges.with_length(36.nm..100.mm)).output("M2.S.3", "M2.S.3 : Min. spacing between two M2' edges, when both edges are >=24nm and =< 36 nm : 27nm")
283 | m2.space(31.nm).polygons.not_interacting(m2.edges.with_length(24.nm..100.mm)).output("M2.S.4-5", "M2.S.4-5 : Min. spacing between two M2' edges, when both edge are =< 24 nm : 31nm")
284 | m2long = m2.space(20.nm, projection).polygons.interacting(m2.edges.with_length(36.nm..100.mm))
285 | m2.space(20.nm, euclidian).polygons.not_interacting(m2long).output("M2.S.6", "M2.S.6 : Min. corner-to-corner spacing between two M2 : 20nm")
286 | m2long.forget
287 | m2.with_area(0 .. 0.000504).output("M2.A.1", "M2.A.1 : Min. area of M2 : 504nm2")
288 |
289 | ### M3
290 | m3.width(18.nm).output("M3.W.1", "M3.W.1 : Min. width of M3 : 18nm")
291 | m3.space(18.nm).polygons.not_interacting(m3.edges.with_length(0..36.nm)).output("M3.S.1", "M3.S.1 : Min. spacing between two M3' edges, when both edges are > 36 nm : 18nm")
292 | m3.space(25.nm).polygons.not_interacting(m3.edges.with_length(36.nm..100.mm)).output("M3.S.2", "M3.S.2 : Min. spacing between two M3' edges, when one edge is > 36 nm : 25nm")
293 | m3.space(27.nm).polygons.not_interacting(m3.edges.with_length(0..24.nm)).not_interacting(m3.edges.with_length(36.nm..100.mm)).output("M3.S.3", "M3.S.3 : Min. spacing between two M3' edges, when both edges are >=24nm and =< 36 nm : 27nm")
294 | m3.space(31.nm).polygons.not_interacting(m3.edges.with_length(24.nm..100.mm)).output("M3.S.4-5", "M3.S.4-5 : Min. spacing between two M3' edges, when both edge are =< 24 nm : 31nm")
295 | m3long = m3.space(20.nm, projection).polygons.interacting(m3.edges.with_length(36.nm..100.mm))
296 | m3.space(20.nm, euclidian).polygons.not_interacting(m3long).output("M3.S.6", "M3.S.6 : Min. corner-to-corner spacing between two M3 : 20nm")
297 | m3long.forget
298 | m3.with_area(0 .. 0.000504).output("M3.A.1", "M3.A.1 : Min. area of M3 : 504nm2")
299 |
300 |
301 | ### V1
302 | # rule V1.W.1 not checked for the instance along the length of M2
303 | v1.width(18.nm).output("V1.W.1", "V1.W.1 : Min. width of V1 : 18nm")
304 | v1.space(18.nm, projection).output("V1.S.1", "V1.S.1 : Min. spacing between V1 instances [on the same M2 track or on parallel M2 tracks, if they are fully or partially aligned with each other : 18nm")
305 | v1spaceortho = v1.space(27.nm, projection).polygons
306 | v1.space(27.nm, projection).polygons.not_interacting(v1spaceortho).output("V1.S.1", "V1.S.1 : Min. spacing between V1 instances on parallel M2 tracks, if they are not aligned with each other : 27nm")
307 | m2ovlp5v1 = (m2 & v1.sized(5.nm + 2.dbu) - v1).sized(-2.5.nm).sized(2.5.nm)
308 | v1.edges.and(m2ovlp5v1).space(23.nm, euclidian).polygons.not(v1spaceortho).output("V1.S.2", "V1.S.2 : Min. corner-to-corner spacing between two V1 instances—both with a 5 nm M2 end-cap : 23nm")
309 | v1.edges.not_interacting(m2ovlp5v1).space(30.nm, euclidian).output("V1.S.3", "V1.S.3 : Min. corner-to-corner spacing between two V1 instances—both without a 5 nm M2 end-cap : 30nm")
310 | v1.edges.and(m2ovlp5v1).separation(v1.edges.not_interacting(m2ovlp5v1), 27.nm, euclidian).output("V1.S.4", "V1.S.4 : Min. corner-to-corner spacing between two V1 instances—one with and another without, a 5 nm M2 end-cap : 27nm")
311 | v1spaceortho.forget
312 | m1ovlp5v1 = (m1 & v1.sized(5.nm) - v1).sized(-2.5.nm+1.dbu).sized(2.5.nm-1.dbu)
313 | v1.interacting(m1.enclosing(v1, 2.nm, projection, two_connected_sides_allowed).edges - m1.enclosing(v1, 2.nm, projection, one_side_allowed).edges).output("V1.M1.EN.1", "V1.M1.EN.1 : Min. enclosure of V1 by M1 on at least two opposite sides : 5nm & 2nm")
314 | v1.interacting(m1.enclosing(v1, 5.nm, projection, two_connected_sides_allowed).edges - m1.enclosing(v1, 5.nm, projection, one_side_allowed).edges).not_interacting(m1ovlp5v1.sized(1.dbu)).output("V1.M1.EN.1", "V1.M1.EN.1 : Min. enclosure of V1 by M1 on at least two opposite sides : 5nm & 2nm")
315 | v1.not_interacting(m2ovlp5v1.sized(2.dbu)).output("V1.M2.EN.2", "V1.M2.EN.2 : enclosure of V1 by M2 on one side : 5nm")
316 | m1ovlp5v1.forget
317 | m2ovlp5v1.forget
318 | ((v1 - m2) + (v1 - m1)).output("V1.AUX.1" "V1.AUX.1 : V1 must be inside M1 and M2")
319 | v1.not_interacting(m2.enclosing(v1, 1.dbu, projection, two_opposite_sides_allowed).edges).output("V1.M2.AUX.2", "V1.M2.AUX.2 : V1 must exactly be the same width as M2 along the direction perpendicular to the M2 length")
320 |
321 | ### V2
322 | # rule V2.W.1 not checked for the instance along the length of M3
323 | v2.width(18.nm).output("V2.W.1", "V2.W.1 : Min. width of V2 : 18nm")
324 | v2.space(18.nm, projection).output("V2.S.1", "V2.S.1 : Min. spacing between V2 instances [on the same M3 track or on parallel M3 tracks, if they are fully or partially aligned with each other : 18nm")
325 | v2spaceortho = v2.space(27.nm, projection).polygons
326 | v2.space(27.nm, projection).polygons.not_interacting(v2spaceortho).output("V2.S.1", "V2.S.1 : Min. spacing between V2 instances on parallel M3 tracks, if they are not aligned with each other : 27nm")
327 | m3ovlp5v2 = (m3 & v2.sized(5.nm) - v2).sized(-2.5.nm+1.dbu).sized(2.5.nm)
328 | v2.edges.and(m3ovlp5v2).space(23.nm, euclidian).polygons.not(v2spaceortho).output("V2.S.2", "V2.S.2 : Min. corner-to-corner spacing between two V2 instances—both with a 5 nm M3 end-cap : 23nm")
329 | v2.edges.not_interacting(m3ovlp5v2).space(30.nm, euclidian).output("V2.S.3", "V2.S.3 : Min. corner-to-corner spacing between two V2 instances—both without a 5 nm M3 end-cap : 30nm")
330 | v2.edges.and(m3ovlp5v2).separation(v2.edges.not_interacting(m3ovlp5v2), 27.nm, euclidian).output("V2.S.4", "V2.S.4 : Min. corner-to-corner spacing between two V2 instances—one with and another without, a 5 nm M3 end-cap : 27nm")
331 | v2.interacting(m2.enclosing(v2, 5.nm, projection, two_connected_sides_allowed).edges - m2.enclosing(v2, 5.nm, projection, one_side_allowed).edges).output("V2.M2.EN.1", "V2.M2.EN.1 : Min. enclosure of V2 by M2 on at least two opposite sides : 5nm")
332 | v2.not_interacting(m3ovlp5v2.sized(2.dbu)).output("V2.M3.EN.2", "V2.M3.EN.2 : enclosure of V2 by M3 on one side : 5nm")
333 | m3ovlp5v2.forget
334 | ((v2 - m3) + (v2 - m2)).output("V2.AUX.1" "V2.AUX.1 : V2 must be inside M2 and M3")
335 | v2.not_interacting(m3.enclosing(v2, 1.dbu, projection, two_opposite_sides_allowed).edges).output("V2.M3.AUX.2", "V2.M3.AUX.2 : V2 must exactly be the same width as M3 along the direction perpendicular to the M3 length")
336 |
337 | ### V3
338 | # rule V3.W.1 not checked for the instance along the length of M4
339 | v3.width(18.nm).output("V3.W.1", "V3.W.1 : Min. width of V3 : 18nm")
340 | v3.space(18.nm, projection).output("V3.S.1", "V3.S.1 : Min. spacing between V3 instances [on the same M4 track or on parallel M4 tracks, if they are fully or partially aligned with each other : 18nm")
341 | v3spaceortho = v3.space(27.nm, projection).polygons
342 | v3.space(27.nm, projection).polygons.not_interacting(v3spaceortho).output("V3.S.1", "V3.S.1 : Min. spacing between V3 instances on parallel M4 tracks, if they are not aligned with each other : 27nm")
343 | m4ovlp5v3 = (m4 & v3.sized(5.nm) - v3).sized(-2.5.nm+1.dbu).sized(2.5.nm)
344 | v3.edges.and(m4ovlp5v3).space(23.nm, euclidian).polygons.not(v3spaceortho).output("V3.S.2", "V3.S.2 : Min. corner-to-corner spacing between two V3 instances—both with a 5 nm M4 end-cap : 23nm")
345 | v3.edges.not_interacting(m4ovlp5v3).space(30.nm, euclidian).output("V3.S.3", "V3.S.3 : Min. corner-to-corner spacing between two V3 instances—both without a 5 nm M4 end-cap : 30nm")
346 | v3.edges.and(m4ovlp5v3).separation(v3.edges.not_interacting(m4ovlp5v3), 27.nm, euclidian).output("V3.S.4", "V3.S.4 : Min. corner-to-corner spacing between two V3 instances—one with and another without, a 5 nm M4 end-cap : 27nm")
347 | m4ovlp5v3.forget
348 | v3.interacting(m3.enclosing(v3, 5.nm, projection, two_connected_sides_allowed).edges - m3.enclosing(v3, 5.nm, projection, one_side_allowed).edges).output("V3.M3.EN.1", "V3.M3.EN.1 : Min. enclosure of V3 by M3 on at least two opposite sides : 5nm")
349 | v3.interacting(m4.enclosing(v3, 11.nm, projection, two_connected_sides_allowed).edges - m4.enclosing(v3, 11.nm, projection, one_side_allowed).edges).output("V3.M4.EN.2", "V3.M4.EN.2 : Min. enclosure of V3 by M4 on at least two opposite sides : 11nm")
350 | ((v3 - m4) + (v3 - m3)).output("V3.AUX.1" "V3.AUX.1 : V3 must be inside M3 and M4")
351 | v3.not_interacting(m4.enclosing(v3, 1.dbu, projection, two_opposite_sides_allowed).edges.with_angle(0)).output("V3.M4.AUX.2", "V3.M4.AUX.2 : V3 must exactly be the same width as M4 along the direction perpendicular to the M4 length")
352 |
353 |
354 | ### M4
355 | m4.width(24.nm, projection).with_angle(0).output("M4.W.1", "M4.W.1 : Min. vertical width of M4 : 24nm")
356 | m4.sized(0, -240.nm).sized(0, 240.nm).output("M4.W.2", "M4.W.2 : Max. vertical width of M4 : 480nm")
357 | m4vedg = m4.width(481.nm, projection).edges.with_angle(90)
358 | (m4vedg.with_length(48.nm) + m4vedg.with_length(96.nm) + m4vedg.with_length(144.nm) + m4vedg.with_length(192.nm) + m4vedg.with_length(240.nm) + m4vedg.with_length(288.nm) + m4vedg.with_length(336.nm) + m4vedg.with_length(384.nm) + m4vedg.with_length(432.nm) + m4vedg.with_length(480.nm)).output("M4.W.3", "M4.W.3 : M4 vertical width may not be an even integer multiple of its minimum width")
359 | # rule M4.W.4 not coded
360 | m4.width(44.nm, projection).edges.with_angle(90).output("M4.W.5", "M4.W.5 : Min. horizontal width of M4 : 44nm")
361 | m4.space(24.nm, projection).edges.with_angle(0).output("M4.S.1", "M4.S.1 : Min. vertical spacing between M4 : 24nm")
362 | m4s2 = m4.space(40.nm, projection).edges.with_angle(90)
363 | m4s2.output("M4.S.2", "M4.S.2 : Min. horizontal spacing between M4 : 40nm")
364 | m4.sized(0,48.nm).space(40.nm, projection).edges.with_angle(90).not(m4s2).and(m4).output("M4.S.3", "M4.S.3 : Min. horizontal tip-to-tip spacing between two M4 on adjacent tracks : 40nm")
365 | m4.sized(0,48.nm).notch(40.nm, projection).edges.with_angle(90).not(m4s2).and(m4).output("M4.S.4", "M4.S.4 : Min. horizontal tip-to-tip spacing between two M4 on adjacent tracks : 40nm")
366 | m4.space(25.nm, projection).edges.with_angle(0).with_length(0..44.nm).output("M4.S.5", "M4.S.5 : Min. parallel run length of two M4 on adjacent tracks : 44nm")
367 | # rule M4.AUX.1 coded in ONGRID section
368 | # rule M4.AUX.2 not coded
369 | m4.corners(0..90).sized(1.nm).output("M4.AUX.3", "M4.AUX.3 : M4 may not bend")
370 | # rule M4.AUX.4 not coded because the routing track is not defined
371 |
372 | ### M5
373 | m5.width(24.nm, projection).with_angle(90).output("M5.W.1", "M5.W.1 : Min. horizontal width of M5 : 24nm")
374 | m5.sized(-240.nm, 0).sized(240.nm, 0).output("M5.W.2", "M5.W.2 : Max. horizontal width of M5 : 480nm")
375 | m5vedg = m5.width(481.nm, projection).edges.with_angle(0)
376 | (m5vedg.with_length(48.nm) + m5vedg.with_length(96.nm) + m5vedg.with_length(144.nm) + m5vedg.with_length(192.nm) + m5vedg.with_length(240.nm) + m5vedg.with_length(288.nm) + m5vedg.with_length(336.nm) + m5vedg.with_length(384.nm) + m5vedg.with_length(432.nm) + m5vedg.with_length(480.nm)).output("M5.W.3", "M5.W.3 : M5 horizontal width may not be an even integer multiple of its minimum width")
377 | # rule M5.W.4 not coded
378 | m5.width(44.nm, projection).edges.with_angle(0).output("M5.W.5", "M5.W.5 : Min. vertical width of M5 : 44nm")
379 | m5.space(24.nm, projection).edges.with_angle(90).output("M5.S.1", "M5.S.1 : Min. horizontal spacing between M5 : 24nm")
380 | m5s2 = m5.space(40.nm, projection).edges.with_angle(0)
381 | m5s2.output("M5.S.2", "M5.S.2 : Min. vertical spacing between M5 : 40nm")
382 | m5.sized(0,48.nm).space(40.nm, projection).edges.with_angle(0).not(m5s2).and(m5).output("M5.S.3", "M5.S.3 : Min. vertical tip-to-tip spacing between two M5 on adjacent tracks : 40nm")
383 | m5.sized(0,48.nm).notch(40.nm, projection).edges.with_angle(0).not(m5s2).and(m5).output("M5.S.4", "M5.S.4 : Min. vertical tip-to-tip spacing between two M5 on adjacent tracks : 40nm")
384 | m5.space(25.nm, projection).edges.with_angle(90).with_length(0..44.nm).output("M5.S.5", "M5.S.5 : Min. parallel run length of two M5 on adjacent tracks : 44nm")
385 | # rule M5.AUX.1 coded in ONGRID section
386 | # rule M5.AUX.2 not coded
387 | m5.corners(0..90).sized(1.nm).output("M5.AUX.3", "M5.AUX.3 : M5 may not bend")
388 | # rule M5.AUX.4 not coded because the routing track is not defined
389 |
390 |
391 | ### V4
392 | # rule V4.W.1 not checked for the instance along the length of M5
393 | v4.width(24.nm).output("V4.W.1", "V4.W.1 : Min. width of V4 : 24nm")
394 | v4.space(33.nm, euclidian).output("V4.S.1-2-3", "V4.S.1-2-3 : Min. spacing between V4 : 33nm")
395 | v4.interacting(m4.enclosing(v4, 11.nm, projection, two_connected_sides_allowed).edges - m4.enclosing(v4, 11.nm, projection, one_side_allowed).edges).output("V4.M4.EN.1", "V4.M4.EN.1 : Min. enclosure of V4 by M4 on at least two opposite sides : 11nm")
396 | ((v4 - m4) + (v4 - m5)).output("V4.AUX.1" "V4.AUX.1 : V4 must be inside M4 and M5")
397 | v4.not_interacting(m5.enclosing(v4, 1.dbu, projection, two_opposite_sides_allowed).edges.with_angle(90)).output("V4.M5.AUX.2", "V4.M5.AUX.2 : V4 must exactly be the same width as M5 along the direction perpendicular to the M5 length")
398 |
399 | ### V5
400 | # rule V5.W.1 not checked for the instance along the length of M6
401 | v5.width(24.nm).output("V5.W.1", "V5.W.1 : Min. width of V5 : 24nm")
402 | v5.space(33.nm, euclidian).output("V5.S.1-2-3", "V5.S.1-2-3 : Min. spacing between V5 : 33nm")
403 | v5.interacting(m5.enclosing(v5, 11.nm, projection, two_connected_sides_allowed).edges - m5.enclosing(v5, 11.nm, projection, one_side_allowed).edges).output("V5.M5.EN.1", "V5.M5.EN.1 : Min. enclosure of V5 by M5 on at least two opposite sides : 11nm")
404 | ((v5 - m5) + (v5 - m6)).output("V5.AUX.1" "V5.AUX.1 : V5 must be inside M5 and M6")
405 | v5.not_interacting(m6.enclosing(v5, 1.dbu, projection, two_opposite_sides_allowed).edges.with_angle(90)).output("V5.M6.AUX.2", "V5.M6.AUX.2 : V5 must exactly be the same width as M6 along the direction perpendicular to the M6 length")
406 |
407 |
408 | ### M6
409 | m6.width(32.nm, projection).with_angle(0).output("M6.W.1", "M6.W.1 : Min. vertical width of M6 : 32nm")
410 | m6.sized(0, -320.nm).sized(0, 320.nm).output("M6.W.2", "M6.W.2 : Max. vertical width of M6 : 640nm")
411 | m6vedg = m6.width(641.nm, projection).edges.with_angle(90)
412 | (m6vedg.with_length(64.nm) + m6vedg.with_length(128.nm) + m6vedg.with_length(192.nm) + m6vedg.with_length(256.nm) + m6vedg.with_length(320.nm) + m6vedg.with_length(384.nm) + m6vedg.with_length(448.nm) + m6vedg.with_length(512.nm) + m6vedg.with_length(576.nm) + m6vedg.with_length(640.nm)).output("M6.W.3", "M6.W.3 : M6 vertical width may not be an even integer multiple of its minimum width")
413 | # rule M6.W.4 not coded
414 | m6.width(44.nm, projection).edges.with_angle(90).output("M6.W.5", "M6.W.5 : Min. horizontal width of M6 : 44nm")
415 | m6.space(32.nm, projection).edges.with_angle(0).output("M6.S.1", "M6.S.1 : Min. vertical spacing between M6 : 32nm")
416 | m6s2 = m6.space(40.nm, projection).edges.with_angle(90)
417 | m6s2.output("M6.S.2", "M6.S.2 : Min. horizontal spacing between M6 : 40nm")
418 | m6.sized(0,48.nm).space(40.nm, projection).edges.with_angle(90).not(m6s2).and(m6).output("M6.S.3", "M6.S.3 : Min. horizontal tip-to-tip spacing between two M6 on adjacent tracks : 40nm")
419 | m6.sized(0,48.nm).notch(40.nm, projection).edges.with_angle(90).not(m6s2).and(m6).output("M6.S.4", "M6.S.4 : Min. horizontal tip-to-tip spacing between two M6 on adjacent tracks : 40nm")
420 | m6.space(25.nm, projection).edges.with_angle(0).with_length(0..44.nm).output("M6.S.5", "M6.S.5 : Min. parallel run length of two M6 on adjacent tracks : 44nm")
421 | # rule M6.AUX.1 coded in ONGRID section
422 | # rule M6.AUX.2 not coded
423 | m6.corners(0..90).sized(1.nm).output("M6.AUX.3", "M6.AUX.3 : M6 may not bend")
424 | # rule M6.AUX.4 not coded because the routing track is not defined
425 |
426 | ### M7
427 | m7.width(32.nm, projection).with_angle(90).output("M7.W.1", "M7.W.1 : Min. horizontal width of M7 : 32nm")
428 | m7.sized(-320.nm, 0).sized(320.nm, 0).output("M7.W.2", "M7.W.2 : Max. horizontal width of M7 : 640nm")
429 | m7vedg = m7.width(641.nm, projection).edges.with_angle(0)
430 | (m7vedg.with_length(64.nm) + m7vedg.with_length(128.nm) + m7vedg.with_length(192.nm) + m7vedg.with_length(256.nm) + m7vedg.with_length(320.nm) + m7vedg.with_length(384.nm) + m7vedg.with_length(448.nm) + m7vedg.with_length(512.nm) + m7vedg.with_length(576.nm) + m7vedg.with_length(640.nm)).output("M7.W.3", "M7.W.3 : M7 horizontal width may not be an even integer multiple of its minimum width")
431 | # rule M7.W.4 not coded
432 | m7.width(44.nm, projection).edges.with_angle(0).output("M7.W.5", "M7.W.5 : Min. vertical width of M7 : 44nm")
433 | m7.space(32.nm, projection).edges.with_angle(90).output("M7.S.1", "M7.S.1 : Min. horizontal spacing between M7 : 32nm")
434 | m7s2 = m7.space(40.nm, projection).edges.with_angle(0)
435 | m7s2.output("M7.S.2", "M7.S.2 : Min. vertical spacing between M7 : 40nm")
436 | m7.sized(0,48.nm).space(40.nm, projection).edges.with_angle(0).not(m7s2).and(m7).output("M7.S.3", "M7.S.3 : Min. vertical tip-to-tip spacing between two M7 on adjacent tracks : 40nm")
437 | m7.sized(0,48.nm).notch(40.nm, projection).edges.with_angle(0).not(m7s2).and(m7).output("M7.S.4", "M7.S.4 : Min. vertical tip-to-tip spacing between two M7 on adjacent tracks : 40nm")
438 | m7.space(25.nm, projection).edges.with_angle(90).with_length(0..44.nm).output("M7.S.5", "M7.S.5 : Min. parallel run length of two M7 on adjacent tracks : 44nm")
439 | # rule M7.AUX.1 coded in ONGRID section
440 | # rule M7.AUX.2 not coded
441 | m7.corners(0..90).sized(1.nm).output("M7.AUX.3", "M7.AUX.3 : M7 may not bend")
442 | # rule M7.AUX.4 not coded because the routing track is not defined
443 |
444 |
445 | ### V6
446 | # rule V6.W.1 not checked for the instance along the length of M7
447 | v6.width(32.nm).output("V6.W.1", "V6.W.1 : Min. width of V6 : 32nm")
448 | v6.space(45.nm, euclidian).output("V6.S.1-2-3", "V6.S.1-2-3 : Min. spacing between V6 : 45nm")
449 | v6.interacting(m6.enclosing(v6, 11.nm, projection, two_connected_sides_allowed).edges - m6.enclosing(v6, 11.nm, projection, one_side_allowed).edges).output("V6.M6.EN.1", "V6.M6.EN.1 : Min. enclosure of V6 by M6 on at least two opposite sides : 11nm")
450 | ((v6 - m6) + (v6 - m7)).output("V6.AUX.1" "V6.AUX.1 : V6 must be inside M6 and M7")
451 | v6.not_interacting(m7.enclosing(v6, 1.dbu, projection, two_opposite_sides_allowed).edges.with_angle(90)).output("V6.M7.AUX.2", "V6.M7.AUX.2 : V6 must exactly be the same width as M7 along the direction perpendicular to the M7 length")
452 |
453 | ### V7
454 | # rule V7.W.1 not checked for the instance along the length of M8
455 | v7.width(32.nm).output("V7.W.1", "V7.W.1 : Min. width of V7 : 32nm")
456 | v7.space(45.nm, euclidian).output("V7.S.1-2-3", "V7.S.1-2-3 : Min. spacing between V7 : 45nm")
457 | v7.interacting(m7.enclosing(v7, 11.nm, projection, two_connected_sides_allowed).edges - m7.enclosing(v7, 11.nm, projection, one_side_allowed).edges).output("V7.M7.EN.1", "V7.M7.EN.1 : Min. enclosure of V7 by M7 on at least two opposite sides : 11nm")
458 | ((v7 - m7) + (v7 - m8)).output("V7.AUX.1" "V7.AUX.1 : V7 must be inside M7 and M8")
459 | v7.not_interacting(m8.enclosing(v7, 1.dbu, projection, two_opposite_sides_allowed).edges.with_angle(90)).output("V7.M8.AUX.2", "V7.M8.AUX.2 : V7 must exactly be the same width as M8 along the direction perpendicular to the M8 length")
460 |
461 |
462 | ### M8
463 | m8.width(40.nm).output("M8.W.1", "M8.W.1 : Min. width of M8 : 40nm")
464 | m8.width(60.nm, projection).edges.with_length(0..400.nm).output("M8.W.2", "M8.W.2 : Min. width of M8, when its length >= 400 nm and < 1200 nm : 60nm")
465 | m8.width(80.nm, projection).edges.with_length(400.nm..1200.nm).output("M8.W.3", "M8.W.3 : Min. width of M8, when its length >= 1200 nm and < 1800 nm : 80nm")
466 | m8.width(120.nm, projection).edges.with_length(1200.nm..1800.nm).output("M8.W.4", "M8.W.3 : Min. width of M8, when its length >=1800 nm : 120nm")
467 | m8.sized(-1.um).sized(-1.um).output("M8.W.5", "M8.W.5 : Max. width of M8 : 2000nm")
468 | m8.space(40.nm, projection).edges.with_length(80.nm..100.mm).output("M8.S.1", "M8.S.1 : Min. spacing between two M8' edges, when both edges are >= 80 nm : 40nm")
469 | m8.space(43.nm, projection).polygons.not_interacting(m8.edges.with_length(80.nm..100.mm)).output("M8.S.2", "M8.S.2 : Min. spacing between two M8' edges, when one of the edges is < 80 nm and the other is >= 80 nm : 43nm")
470 | m8.space(46.nm, projection).edges.with_length(0..80.nm).output("M8.S.3", "M8.S.3 : Min. spacing between two M8' edges, when both edges are < 80 nm : 46nm")
471 | m8.space(60.nm, projection).polygons.interacting(m8.edges.with_length(60.nm..80.nm)).output("M8.S.4", "M8.S.4 : Min. spacing between two M8' edges, when one of the edges is >= 60 nm and < 80 nm : 60nm")
472 | m8.space(80.nm, projection).polygons.interacting(m8.edges.with_length(80.nm..120.nm)).output("M8.S.5", "M8.S.5 : Min. spacing between two M8' edges, when one of the edges is >= 80 nm and < 120 nm : 80nm")
473 | m8.space(120.nm, projection).polygons.interacting(m8.edges.with_length(120.nm..500.nm)).output("M8.S.6", "M8.S.6 : Min. spacing between two M8' edges, when one of the edges is >= 120 nm and < 500 nm : 120nm")
474 | m8.space(500.nm, projection).polygons.interacting(m8.edges.with_length(500.nm..1000.nm)).output("M8.S.7", "M8.S.7 : Min. spacing between two M8' edges, when one of the edges is >= 500 nm and < 1000 nm : 500nm")
475 | m8.space(1000.nm, projection).polygons.interacting(m8.edges.with_length(1000.nm..100.mm)).output("M8.S.8", "M8.S.8 : Min. spacing between two M8' edges, when one of the edges is >= 1000 nm : 1000nm")
476 | m8.with_area(0 .. 0.007520).output("M8.A.1", "M8.A.1 : Min. area of M8 : 7520nm2")
477 | m8.edges.without_length(40.nm..100.mm).output("M8.L.1", "M8.L.1 : Minimum feature length of M8 : 40nm")
478 |
479 | ### M9
480 | m9.width(40.nm).output("M9.W.1", "M9.W.1 : Min. width of M9 : 40nm")
481 | m9.width(60.nm, projection).edges.with_length(0..400.nm).output("M9.W.2", "M9.W.2 : Min. width of M9, when its length >= 400 nm and < 1200 nm : 60nm")
482 | m9.width(80.nm, projection).edges.with_length(400.nm..1200.nm).output("M9.W.3", "M9.W.3 : Min. width of M9, when its length >= 1200 nm and < 1800 nm : 80nm")
483 | m9.width(120.nm, projection).edges.with_length(1200.nm..1800.nm).output("M9.W.4", "M9.W.3 : Min. width of M9, when its length >=1800 nm : 120nm")
484 | m9.sized(-1.um).sized(-1.um).output("M9.W.5", "M9.W.5 : Max. width of M9 : 2000nm")
485 | m9.space(40.nm, projection).edges.with_length(80.nm..100.mm).output("M9.S.1", "M9.S.1 : Min. spacing between two M9' edges, when both edges are >= 80 nm : 40nm")
486 | m9.space(43.nm, projection).polygons.not_interacting(m9.edges.with_length(80.nm..100.mm)).output("M9.S.2", "M9.S.2 : Min. spacing between two M9' edges, when one of the edges is < 80 nm and the other is >= 80 nm : 43nm")
487 | m9.space(46.nm, projection).edges.with_length(0..80.nm).output("M9.S.3", "M9.S.3 : Min. spacing between two M9' edges, when both edges are < 80 nm : 46nm")
488 | m9.space(60.nm, projection).polygons.interacting(m9.edges.with_length(60.nm..80.nm)).output("M9.S.4", "M9.S.4 : Min. spacing between two M9' edges, when one of the edges is >= 60 nm and < 80 nm : 60nm")
489 | m9.space(80.nm, projection).polygons.interacting(m9.edges.with_length(80.nm..120.nm)).output("M9.S.5", "M9.S.5 : Min. spacing between two M9' edges, when one of the edges is >= 80 nm and < 120 nm : 80nm")
490 | m9.space(120.nm, projection).polygons.interacting(m9.edges.with_length(120.nm..500.nm)).output("M9.S.6", "M9.S.6 : Min. spacing between two M9' edges, when one of the edges is >= 120 nm and < 500 nm : 120nm")
491 | m9.space(500.nm, projection).polygons.interacting(m9.edges.with_length(500.nm..1000.nm)).output("M9.S.7", "M9.S.7 : Min. spacing between two M9' edges, when one of the edges is >= 500 nm and < 1000 nm : 500nm")
492 | m9.space(1000.nm, projection).polygons.interacting(m9.edges.with_length(1000.nm..100.mm)).output("M9.S.8", "M9.S.8 : Min. spacing between two M9' edges, when one of the edges is >= 1000 nm : 1000nm")
493 | m9.with_area(0 .. 0.007520).output("M9.A.1", "M9.A.1 : Min. area of M9 : 7520nm2")
494 | m9.edges.without_length(40.nm..100.mm).output("M9.L.1", "M9.L.1 : Minimum feature length of M9 : 40nm")
495 |
496 |
497 | ### V8
498 | ((v8.edges.without_length(40.nm) & v8.edges.without_length(120.nm)) + v8.with_area(0.0144).edges).output("V8.W.1", "V8.W.1 : Exact width of a V8 instance")
499 | v8.space(57.nm).output("V8.S.1-2", "V8.S.1-2 : Min. spacing between V8 : 57.nm")
500 | v8.interacting(m8.enclosing(v8, 20.nm, projection, two_connected_sides_allowed).edges - m8.enclosing(v8, 20.nm, projection, one_side_allowed).edges).output("V8.M8.EN.1", "V8.M8.EN.1 : Min. enclosure of V8 by M8 on at least two opposite sides : 20nm")
501 | v8.interacting(m9.enclosing(v8, 20.nm, projection, two_connected_sides_allowed).edges - m9.enclosing(v8, 20.nm, projection, one_side_allowed).edges).output("V8.M9.EN.2", "V8.M9.EN.2 : Min. enclosure of V8 by M9 on at least two opposite sides : 20nm")
502 | ((v8 - m8) + (v8 - m9)).output("V8.AUX.1" "V8.AUX.1 : V8 must be inside M8 and M9")
503 |
504 | ### V9
505 | ((v9.edges.without_length(40.nm) & v9.edges.without_length(120.nm)) + v9.with_area(0.0144).edges).output("V9.W.1", "V9.W.1 : Exact width of a V9 instance")
506 | v9.space(57.nm).output("V9.S.1-2", "V9.S.1-2 : Min. spacing between V9 : 57.nm")
507 | v9.interacting(m9.enclosing(v9, 20.nm, projection, two_connected_sides_allowed).edges - m9.enclosing(v9, 20.nm, projection, one_side_allowed).edges).output("V9.M9.EN.1", "V9.M9.EN.1 : Min. enclosure of V9 by M9 on at least two opposite sides : 20nm")
508 | v9.interacting(pad.enclosing(v9, 20.nm, projection, two_connected_sides_allowed).edges - pad.enclosing(v9, 20.nm, projection, one_side_allowed).edges).output("V9.PAD.EN.2", "V9.PAD.EN.2 : Min. enclosure of V9 by PAD on at least two opposite sides : 20nm")
509 | ((v9 - m9) + (v9 - pad)).output("V9.AUX.1" "V9.AUX.1 : V9 must be inside M9 and PAD")
510 |
511 |
512 | # ONGRID defined in the paper :
513 | # "ASAP7 : A 7-nm finFET predictive process design kit"
514 | ##########################################################
515 | if OFFGRID
516 | info("GRID section")
517 |
518 | # special grids for M4.to M7
519 | m4.ongrid(24.nm, 0).output("M4.AUX.1", "M4.AUX.1 : M4 horizontal edges must be at a grid of : 24nm")
520 | m5.ongrid(0, 24.nm).output("M5.AUX.1", "M5.AUX.1 : M5 vertical edges must be at a grid of : 24nm")
521 | m6.ongrid(32.nm, 0).output("M4.AUX.1", "M4.AUX.1 : M4 horizontal edges must be at a grid of : 32nm")
522 | m7.ongrid(0, 32.nm).output("M5.AUX.1", "M5.AUX.1 : M5 vertical edges must be at a grid of : 32nm")
523 |
524 | grid = 1.nm
525 | all_drawing = [ :nwell, :fin, :gate, :gcut, :active, :sdt, :nselect, :pselect, :slvt, :lvt, :sramdrc, :sramvt, :dummy, :lig, :lisd, :v0, :m1, :v1, :m2, :v2, :m3, :v3, :m4, :v4, :m5, :v5, :m6, :v6, :m7, :v7, :m8, :v8, :m9, :v9, ]
526 | all_drawing.each do |dwg|
527 | # a Ruby idiom to get the value of a variable whose name is in "dwg" (as symbol)
528 | layer = binding.local_variable_get(dwg)
529 | layer.ongrid(grid).polygons(2.nm).output("GRID: vertexes on layer #{dwg} not on grid of #{'%.12g' % grid}")
530 | nonortho_edges = layer.edges - layer.edges.with_angle(0) - layer.edges.with_angle(90)
531 | nonortho_edges.output("#{dwg}.GEOMETRY.NONORTHOGONAL" , "GEOMETRY.NONORTHOGONAL on layer #{dwg}")
532 | end
533 | end
534 |
535 | # time spent for the DRC
536 | time = Time.now
537 | hours = ((time - tstart)/3600).to_i
538 | minutes = ((time - tstart)/60 - hours * 60).to_i
539 | seconds = ((time - tstart) - (minutes * 60 + hours * 3600)).to_i
540 | $stdout.write "DRC finished at : #{time.hour}:#{time.min}:#{time.sec} - DRC duration = #{hours} hrs. #{minutes} min. #{seconds} sec.\n"
541 |
542 |
--------------------------------------------------------------------------------