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:
parent
e10901e32b
commit
913c830dee
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Reference in New Issue