Corrected the extraction of length and width of devices that are

(truly) missing a terminal (such as a MOSCAP made with a gate
extending into but not crossing a diffusion region).  Added the
most requested GUI feature, which is a vertical scrollbar on the
parameterized device window (could be improved by maximizing
window height without exceeding display height).
This commit is contained in:
Tim Edwards 2023-03-12 16:57:47 -04:00
parent e10901e32b
commit 913c830dee
3 changed files with 111 additions and 65 deletions

View File

@ -1 +1 @@
8.3.377
8.3.378

View File

@ -2099,7 +2099,7 @@ extOutputDevices(def, transList, outFile)
case DEV_SUBCKT:
case DEV_MSUBCKT:
case DEV_ASYMMETRIC:
length = extTransRec.tr_gatelen / 2; /* (default) */
length = 0;
width = 0;
isAnnular = FALSE;
@ -2119,7 +2119,32 @@ extOutputDevices(def, transList, outFile)
extTransRec.tr_termvector[n].p_y == 0)
isAnnular = TRUE;
}
if (n) width /= n;
/* For devices missing a terminal, reduce n accordingly. */
/* This avoids errors in length and width calculations. */
while ((n > 0) && (extTransRec.tr_termnode[n - 1]) &&
(extTransRec.tr_termlen[n - 1] == 0) &&
(extTransRec.tr_termarea[n - 1] == 0) &&
(extTransRec.tr_termperim[n - 1] == 0)) n--;
if (n)
{
width /= n;
if (n > 1)
length = extTransRec.tr_gatelen / n;
else
{
/* Assumption: A device with a single terminal */
/* must be rectangular; an example is a MOSCAP */
/* with poly over three sides of diffusion. */
/* Length in this case is not properly defined, */
/* but it is only necessary for the model to */
/* get the correct area per W * L. If the */
/* device is annular, then this assumption will */
/* get corrected by extComputeEffectiveLW(). */
length = (extTransRec.tr_gatelen - width) / 2;
}
}
/*------------------------------------------------------*/
/* Note that the tr_termvector says a lot about the */
@ -3152,7 +3177,8 @@ extTransPerimFunc(bp)
*/
if (strcmp(extTransRec.tr_devrec->exts_deviceName, "Ignore") &&
strcmp(extTransRec.tr_devrec->exts_deviceName, "Short"))
TxError("Error: Asymmetric device with multiple terminals!\n");
TxError("Warning: Unexpected asymmetric device at %d, %d!\n",
bp->b_outside->ti_ll.p_x, bp->b_outside->ti_ll.p_y);
break;
}

View File

@ -588,13 +588,13 @@ proc magic::gencell_makecell {gencell_fullname args} {
proc magic::gencell_getparams {} {
set parameters [dict create]
set slist [grid slaves .params.edits]
set slist [grid slaves .params.body.area.edits]
foreach s $slist {
if {[regexp {^.params.edits.(.*)_ent$} $s valid pname] != 0} {
if {[regexp {^.params.body.area.edits.(.*)_ent$} $s valid pname] != 0} {
set value [subst \$magic::${pname}_val]
} elseif {[regexp {^.params.edits.(.*)_chk$} $s valid pname] != 0} {
} elseif {[regexp {^.params.body.area.edits.(.*)_chk$} $s valid pname] != 0} {
set value [subst \$magic::${pname}_val]
} elseif {[regexp {^.params.edits.(.*)_sel$} $s valid pname] != 0} {
} elseif {[regexp {^.params.body.area.edits.(.*)_sel$} $s valid pname] != 0} {
set value [subst \$magic::${pname}_val]
}
dict set parameters $pname $value
@ -610,25 +610,25 @@ proc magic::gencell_getparams {} {
proc magic::gencell_setparams {parameters} {
if {[catch {set state [wm state .params]}]} {return}
set slist [grid slaves .params.edits]
set slist [grid slaves .params.body.area.edits]
foreach s $slist {
# ignore .params.edits.gencell_sel, as that does not exist in the
# ignore .params.body.area.edits.gencell_sel, as that does not exist in the
# parameters dictionary
if {$s == ".params.edits.gencell_sel"} {continue}
if {[regexp {^.params.edits.(.*)_ent$} $s valid pname] != 0} {
if {$s == ".params.body.area.edits.gencell_sel"} {continue}
if {[regexp {^.params.body.area.edits.(.*)_ent$} $s valid pname] != 0} {
set value [dict get $parameters $pname]
set magic::${pname}_val $value
} elseif {[regexp {^.params.edits.(.*)_chk$} $s valid pname] != 0} {
} elseif {[regexp {^.params.body.area.edits.(.*)_chk$} $s valid pname] != 0} {
set value [dict get $parameters $pname]
set magic::${pname}_val $value
} elseif {[regexp {^.params.edits.(.*)_sel$} $s valid pname] != 0} {
} elseif {[regexp {^.params.body.area.edits.(.*)_sel$} $s valid pname] != 0} {
set value [dict get $parameters $pname]
set magic::${pname}_val $value
.params.edits.${pname}_sel configure -text $value
} elseif {[regexp {^.params.edits.(.*)_txt$} $s valid pname] != 0} {
.params.body.area.edits.${pname}_sel configure -text $value
} elseif {[regexp {^.params.body.area.edits.(.*)_txt$} $s valid pname] != 0} {
if {[dict exists $parameters $pname]} {
set value [dict get $parameters $pname]
.params.edits.${pname}_txt configure -text $value
.params.body.area.edits.${pname}_txt configure -text $value
}
}
}
@ -1016,14 +1016,14 @@ proc magic::add_entry {pname ptext parameters} {
set value ""
}
set numrows [lindex [grid size .params.edits] 1]
label .params.edits.${pname}_lab -text $ptext
entry .params.edits.${pname}_ent -background white -textvariable magic::${pname}_val
grid .params.edits.${pname}_lab -row $numrows -column 0 \
set numrows [lindex [grid size .params.body.area.edits] 1]
label .params.body.area.edits.${pname}_lab -text $ptext
entry .params.body.area.edits.${pname}_ent -background white -textvariable magic::${pname}_val
grid .params.body.area.edits.${pname}_lab -row $numrows -column 0 \
-sticky ens -ipadx 5 -ipady 2
grid .params.edits.${pname}_ent -row $numrows -column 1 \
grid .params.body.area.edits.${pname}_ent -row $numrows -column 1 \
-sticky ewns -ipadx 5 -ipady 2
.params.edits.${pname}_ent insert end $value
.params.body.area.edits.${pname}_ent insert end $value
set magic::${pname}_val $value
}
@ -1033,7 +1033,7 @@ proc magic::add_entry {pname ptext parameters} {
#----------------------------------------------------------
proc magic::add_check_callbacks {gencell_type library} {
set wlist [winfo children .params.edits]
set wlist [winfo children .params.body.area.edits]
foreach w $wlist {
if {[regexp {\.params\.edits\.(.+)_ent} $w valid pname]} {
# Add callback on enter or focus out
@ -1068,20 +1068,20 @@ proc magic::add_dependency {callback gencell_type library args} {
{*}[dict keys $parameters]
return
}
set clist [winfo children .params.edits]
set clist [winfo children .params.body.area.edits]
foreach pname $args {
if {[lsearch $clist .params.edits.${pname}_ent] >= 0} {
if {[lsearch $clist .params.body.area.edits.${pname}_ent] >= 0} {
# Add callback on enter or focus out
bind .params.edits.${pname}_ent <Return> \
bind .params.body.area.edits.${pname}_ent <Return> \
"magic::update_dialog $callback $pname $gencell_type $library"
bind .params.edits.${pname}_ent <FocusOut> \
bind .params.body.area.edits.${pname}_ent <FocusOut> \
"magic::update_dialog $callback $pname $gencell_type $library"
} elseif {[lsearch $clist .params.edits.${pname}_chk] >= 0} {
} elseif {[lsearch $clist .params.body.area.edits.${pname}_chk] >= 0} {
# Add callback on checkbox change state
.params.edits.${pname}_chk configure -command \
.params.body.area.edits.${pname}_chk configure -command \
"magic::update_dialog $callback $pname $gencell_type $library"
} elseif {[lsearch $clist .params.edits.${pname}_sel] >= 0} {
set smenu .params.edits.${pname}_sel.menu
} elseif {[lsearch $clist .params.body.area.edits.${pname}_sel] >= 0} {
set smenu .params.body.area.edits.${pname}_sel.menu
set sitems [${smenu} index end]
for {set idx 0} {$idx <= $sitems} {incr idx} {
set curcommand [${smenu} entrycget $idx -command]
@ -1129,11 +1129,11 @@ proc magic::add_checkbox {pname ptext parameters} {
set value ""
}
set numrows [lindex [grid size .params.edits] 1]
label .params.edits.${pname}_lab -text $ptext
checkbutton .params.edits.${pname}_chk -variable magic::${pname}_val
grid .params.edits.${pname}_lab -row $numrows -column 0 -sticky ens
grid .params.edits.${pname}_chk -row $numrows -column 1 -sticky wns
set numrows [lindex [grid size .params.body.area.edits] 1]
label .params.body.area.edits.${pname}_lab -text $ptext
checkbutton .params.body.area.edits.${pname}_chk -variable magic::${pname}_val
grid .params.body.area.edits.${pname}_lab -row $numrows -column 0 -sticky ens
grid .params.body.area.edits.${pname}_chk -row $numrows -column 1 -sticky wns
set magic::${pname}_val $value
}
@ -1152,12 +1152,12 @@ proc magic::add_message {pname ptext parameters {color blue}} {
set value ""
}
set numrows [lindex [grid size .params.edits] 1]
label .params.edits.${pname}_lab -text $ptext
label .params.edits.${pname}_txt -text $value \
set numrows [lindex [grid size .params.body.area.edits] 1]
label .params.body.area.edits.${pname}_lab -text $ptext
label .params.body.area.edits.${pname}_txt -text $value \
-foreground $color -textvariable magic::${pname}_val
grid .params.edits.${pname}_lab -row $numrows -column 0 -sticky ens
grid .params.edits.${pname}_txt -row $numrows -column 1 -sticky wns
grid .params.body.area.edits.${pname}_lab -row $numrows -column 0 -sticky ens
grid .params.body.area.edits.${pname}_txt -row $numrows -column 1 -sticky wns
}
#----------------------------------------------------------
@ -1174,16 +1174,16 @@ proc magic::add_selectlist {pname ptext all_values parameters {itext ""}} {
set value $itext
}
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 \
set numrows [lindex [grid size .params.body.area.edits] 1]
label .params.body.area.edits.${pname}_lab -text $ptext
menubutton .params.body.area.edits.${pname}_sel -menu .params.body.area.edits.${pname}_sel.menu \
-relief groove -text ${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
grid .params.body.area.edits.${pname}_lab -row $numrows -column 0 -sticky ens
grid .params.body.area.edits.${pname}_sel -row $numrows -column 1 -sticky wns
menu .params.body.area.edits.${pname}_sel.menu -tearoff 0
foreach item ${all_values} {
set cmdtxt ".params.edits.${pname}_sel configure -text $item"
.params.edits.${pname}_sel.menu add radio -label $item \
set cmdtxt ".params.body.area.edits.${pname}_sel configure -text $item"
.params.body.area.edits.${pname}_sel.menu add radio -label $item \
-variable magic::${pname}_val -value $item \
-command $cmdtxt
}
@ -1205,18 +1205,18 @@ proc magic::add_selectindex {pname ptext all_values parameters {ival 0}} {
set value $ival
}
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 \
set numrows [lindex [grid size .params.body.area.edits] 1]
label .params.body.area.edits.${pname}_lab -text $ptext
menubutton .params.body.area.edits.${pname}_sel -menu .params.body.area.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
grid .params.body.area.edits.${pname}_lab -row $numrows -column 0 -sticky ens
grid .params.body.area.edits.${pname}_sel -row $numrows -column 1 -sticky wns
menu .params.body.area.edits.${pname}_sel.menu -tearoff 0
set idx 0
foreach item ${all_values} {
.params.edits.${pname}_sel.menu add radio -label $item \
.params.body.area.edits.${pname}_sel.menu add radio -label $item \
-variable magic::${pname}_val -value $idx \
-command ".params.edits.${pname}_sel configure -text $item"
-command ".params.body.area.edits.${pname}_sel configure -text $item"
incr idx
}
set magic::${pname}_val $value
@ -1350,7 +1350,7 @@ proc magic::gencell_dialog {instname gencell_type library parameters} {
.params.title.glab configure -foreground blue -text "$gname"
.params.title.ient delete 0 end
.params.title.ient insert 0 "$itext"
foreach child [winfo children .params.edits] {
foreach child [winfo children .params.body.area.edits] {
destroy $child
}
foreach child [winfo children .params.buttons] {
@ -1368,7 +1368,9 @@ proc magic::gencell_dialog {instname gencell_type library parameters} {
entry .params.title.ient -foreground brown -background white
.params.title.ient insert 0 "$itext"
ttk::separator .params.sep
frame .params.edits
frame .params.body
canvas .params.body.area
scrollbar .params.body.sb -command {.params.body.area yview}
frame .params.buttons
grid .params.title.lab1 -padx 5 -row 0 -column 0
@ -1382,12 +1384,26 @@ proc magic::gencell_dialog {instname gencell_type library parameters} {
grid .params.title.ient -padx 5 -row 1 -column 3 -sticky ew
grid columnconfigure .params.title 3 -weight 1
pack .params.title -fill x -expand true
pack .params.sep -fill x -expand true
pack .params.edits -side top -fill both -expand true -ipadx 5
pack .params.buttons -fill x
grid .params.body.area -row 0 -column 0 -sticky nsew
grid .params.body.sb -row 0 -column 1 -sticky ns
grid columnconfigure .params.body 0 -weight 1
grid columnconfigure .params.body 1 -weight 0
grid rowconfigure .params.body 0 -weight 1
grid columnconfigure .params.edits 1 -weight 1
grid .params.title -row 0 -column 0 -sticky nsew
grid .params.sep -row 1 -column 0 -sticky nsew
grid .params.body -row 2 -column 0 -sticky nsew
grid .params.buttons -row 3 -column 0 -sticky nsew
grid rowconfigure .params 0 -weight 0
grid rowconfigure .params 1 -weight 0
grid rowconfigure .params 2 -weight 1
grid rowconfigure .params 3 -weight 0
grid columnconfigure .params 0 -weight 1
frame .params.body.area.edits
.params.body.area create window 0 0 -anchor nw -window .params.body.area.edits
.params.body.area config -yscrollcommand {.params.body.sb set}
}
if {$instname == {}} {
@ -1425,6 +1441,10 @@ proc magic::gencell_dialog {instname gencell_type library parameters} {
# Make sure the window is raised
raise .params
# Wait for window to become visible to set the scroll region
tkwait visibility .params.body.area
.params.body.area config -scrollregion [.params.body.area bbox all]
}
#-------------------------------------------------------------