├── 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 | --------------------------------------------------------------------------------