From adb4d2613d0db8aa4b60d529134e62430f907441 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 20 Nov 2019 13:01:14 -0500 Subject: [PATCH 1/2] Added indexed selection to the PDK toolkit script (returns an index from a selection, which can then be used to index into other lists. This lets one selection be made on a list of arbitrary names, and then additional parameters can be linked together with the same index). Also, implemented (finally!) the "offset" parameters of the "slots" function (as advertised in the documentation). --- cif/CIFgen.c | 9 ++++++--- tcltk/toolkit.tcl | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/cif/CIFgen.c b/cif/CIFgen.c index 9c95f983..d2af4afb 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -1790,7 +1790,7 @@ cifSlotsFillArea(op, cellDef, plane) { Tile *tile, *t, *tp; Rect bbox, area, square, cut, llcut; - int nAcross, nUp, left, spitch, lpitch, ssize, lsize; + int nAcross, nUp, left, spitch, lpitch, ssize, lsize, offset; int diff, right; int xpitch, ypitch, xborder, yborder, xdiff, ydiff; int i, j, k, savecount; @@ -2017,10 +2017,11 @@ cifSlotsFillArea(op, cellDef, plane) /* For each contact cut area, check that there is */ /* no whitespace */ + offset = 0; for (i = 0; i < nUp; i++) { - cut.r_xbot = llcut.r_xbot; - cut.r_xtop = llcut.r_xtop; + cut.r_xbot = llcut.r_xbot + offset; + cut.r_xtop = llcut.r_xtop + offset; square.r_ybot = cut.r_ybot - yborder; square.r_ytop = cut.r_ytop + yborder; @@ -2047,6 +2048,8 @@ cifSlotsFillArea(op, cellDef, plane) } cut.r_ybot += ypitch; cut.r_ytop += ypitch; + offset += slots->sl_offset; + if (offset >= xpitch) offset -= xpitch; } if (savecount != CIFTileOps) break; diff --git a/tcltk/toolkit.tcl b/tcltk/toolkit.tcl index 7412277a..9ca83264 100644 --- a/tcltk/toolkit.tcl +++ b/tcltk/toolkit.tcl @@ -628,6 +628,38 @@ proc magic::add_selectlist {pname ptext all_values parameters} { set magic::${pname}_val $value } +#---------------------------------------------------------- +# Add a selectable-list parameter to the gencell window +# Unlike the routine above, it returns the index of the +# selection, not the selection itself. This is useful for +# keying the selection to other parameter value lists. +#---------------------------------------------------------- + +proc magic::add_selectindex {pname ptext all_values parameters} { + + if [dict exists $parameters $pname] { + set value [dict get $parameters $pname] + } else { + set value 0 + } + + set numrows [lindex [grid size .params.edits] 1] + label .params.edits.${pname}_lab -text $ptext + menubutton .params.edits.${pname}_sel -menu .params.edits.${pname}_sel.menu \ + -relief groove -text [lindex ${all_values} ${value}] + grid .params.edits.${pname}_lab -row $numrows -column 0 -sticky ens + grid .params.edits.${pname}_sel -row $numrows -column 1 -sticky wns + menu .params.edits.${pname}_sel.menu -tearoff 0 + set idx 0 + foreach item ${all_values} { + .params.edits.${pname}_sel.menu add radio -label $item \ + -variable magic::${pname}_val -value $idx \ + -command ".params.edits.${pname}_sel configure -text $item" + incr idx + } + set magic::${pname}_val $value +} + #------------------------------------------------------------- # gencell_defaults --- # From be8ba0937392d0996cdcda3e404c1057de4f9b5e Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 20 Nov 2019 13:36:03 -0500 Subject: [PATCH 2/2] Created an additional argument "start" to the "slots" operator, which adds an offset value of "start" to both X and Y from the lower left corner of the fill area. This allows the use of the "offset" (from the previous git commit) to be declared on different layers without creating an exact overlap, as is often required by foundries for fill patterns. --- cif/CIFgen.c | 6 +++--- cif/CIFint.h | 1 + cif/CIFtech.c | 23 +++++++++++++++++++---- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/cif/CIFgen.c b/cif/CIFgen.c index d2af4afb..6de88309 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -2011,13 +2011,13 @@ cifSlotsFillArea(op, cellDef, plane) cifSlotFunc(&bbox, op, &nUp, &nAcross, &llcut, vertical); - cut.r_ybot = llcut.r_ybot; - cut.r_ytop = llcut.r_ytop; + cut.r_ybot = llcut.r_ybot + slots->sl_start; + cut.r_ytop = llcut.r_ytop + slots->sl_start; /* For each contact cut area, check that there is */ /* no whitespace */ - offset = 0; + offset = slots->sl_start; for (i = 0; i < nUp; i++) { cut.r_xbot = llcut.r_xbot + offset; diff --git a/cif/CIFint.h b/cif/CIFint.h index c9280e12..157a3cff 100644 --- a/cif/CIFint.h +++ b/cif/CIFint.h @@ -69,6 +69,7 @@ typedef struct slots_data int sl_lsize; int sl_lsep; int sl_offset; + int sl_start; } SlotsData; typedef struct cifop diff --git a/cif/CIFtech.c b/cif/CIFtech.c index 309b06e0..2040bc7f 100644 --- a/cif/CIFtech.c +++ b/cif/CIFtech.c @@ -1327,6 +1327,7 @@ bloatCheck: slots->sl_lsize = 0; slots->sl_lsep = 0; slots->sl_offset = 0; + slots->sl_start = 0; } if (argc >= 5) { @@ -1361,7 +1362,7 @@ bloatCheck: goto errorReturn; } } - if (argc == 8) + if (argc >= 8) { i = atoi(argv[7]); slots->sl_offset = i; @@ -1371,7 +1372,17 @@ bloatCheck: goto errorReturn; } } - if ((argc < 4) || (argc == 6) || (argc > 8)) + if (argc == 9) + { + i = atoi(argv[8]); + slots->sl_start = i; + if (i < 0) + { + TechError("Slot start must be non-negative.\n"); + goto errorReturn; + } + } + if ((argc < 4) || (argc == 6) || (argc > 9)) goto wrongNumArgs; break; } @@ -1685,7 +1696,7 @@ CIFTechFinal() { slots = (SlotsData *)op->co_client; - for (j = 0; j < 7; j++) + for (j = 0; j < 8; j++) { switch (j) { case 0: bvalue = slots->sl_sborder; break; @@ -1695,6 +1706,7 @@ CIFTechFinal() case 4: bvalue = slots->sl_lsize; break; case 5: bvalue = slots->sl_lsep; break; case 6: bvalue = slots->sl_offset; break; + case 7: bvalue = slots->sl_start; break; } if (bvalue != 0) { @@ -2193,7 +2205,7 @@ CIFTechOutputScale(n, d) else if (op->co_opcode == CIFOP_SLOTS) { slots = (SlotsData *)op->co_client; - for (j = 0; j < 7; j++) + for (j = 0; j < 8; j++) { switch (j) { case 0: bptr = &slots->sl_sborder; break; @@ -2203,6 +2215,7 @@ CIFTechOutputScale(n, d) case 4: bptr = &slots->sl_lsize; break; case 5: bptr = &slots->sl_lsep; break; case 6: bptr = &slots->sl_offset; break; + case 7: bptr = &slots->sl_start; break; } if (*bptr != 0) { @@ -2319,6 +2332,8 @@ CIFTechOutputScale(n, d) slots->sl_lsep /= lexpand; if (slots->sl_offset != 0) slots->sl_offset /= lexpand; + if (slots->sl_start != 0) + slots->sl_start /= lexpand; break; case CIFOP_SQUARES_G: squares = (SquaresData *)op->co_client;