gnucap-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Gnucap-devel] SPICE to gnucap transition


From: al davis
Subject: Re: [Gnucap-devel] SPICE to gnucap transition
Date: Mon, 19 Mar 2007 20:28:14 -0400
User-agent: KMail/1.9.5

On Monday 19 March 2007 12:38, Scott Dattalo wrote:
> So here's an offer:
>
> Show us how the SPICE inverter circuit needs to be modified
> so that it can work with gnucap. You don't need to be too
> elaborate here. The inverter netlist consists of only 5 lines
> (and with gnucap it should only be 4 lines). Show us how to
> sweep the input voltage and look at the drain-to-source
> current of the transistors.
>
> If you can do this then I'll write a tutorial on how one can
> convert simple SPICE circuits into gnucap circuits.

ok...
Actually, this example does expose a bug, and raises some other 
questions.

Your file (with some lossy compression) 
==========
MOS Inverter Test
.OPTIONS NODE NOPAGE
VDS 3 0  DC=3.0
VGS 2 0  DC=0.0
M1 1 2 0 0 CMOSN
M2 3 2 4 3 CMOSP
VIDS 4 1  DC=0.0
.DC  VGS 0 3 .05
.PRINT DC I(VIDS) V(2)
.PLOT DC I(VIDS)
.include TSMC_025u_Mosis.txt
.END
===========
Problems:
When it does "DC" it doesn't have the model or probes yet.
as if your file was:
=========
MOS Inverter Test
.OPTIONS NODE NOPAGE
VDS 3 0  DC=3.0
VGS 2 0  DC=0.0
M1 1 2 0 0 CMOSN
M2 3 2 4 3 CMOSP
VIDS 4 1  DC=0.0
.DC  VGS 0 3 .05
==========
The fix is to put the include and probes before the DC command.
I commented out "plot" because I don't want it.
==========
MOS Inverter Test
.OPTIONS NODE NOPAGE
.include TSMC_025u_Mosis.txt
VDS 3 0  DC=3.0
VGS 2 0  DC=0.0
M1 1 2 0 0 CMOSN
M2 3 2 4 3 CMOSP
VIDS 4 1  DC=0.0
.PRINT DC I(VIDS) V(2)
*.PLOT DC I(VIDS)
.DC  VGS 0 3 .05
.END
==========
This should work, but there is another problem:
==========
MOS Inverter Test 
M1, CMOSN
model and device parameters are incompatible
M2, CMOSP
model and device parameters are incompatible
#           I(VIDS)    V(2)      
@@#
@@@unreachable:u_limit.h:110:fet_limit_vgs
@@#
@@@unreachable:u_limit.h:110:fet_limit_vgs
@@#
==========
OK ......
The device parameters (length and width) are not compatible with 
the model.
You didn't specify length and width!
The bug:  It picked nonsense default values, ignoring 
the .options defl and defw.
I think this bug was introduced when the ".param" feature was 
added.  I removed it and forgot to put it back.  The regression 
suite didn't catch it, and I didn't see it in other work 
because I always specify length and width.
And ...  that resulted in a numeric overflow, which was not 
properly trapped.
Specifying a length and width, it works now, but with a problem.
(both = 100u, because that should be the default)
===========
See the file "COPYING" for details.
MOS Inverter Test 
#           I(VIDS)    V(2)       IDS(M1)    IDS(M2)   
did not converge
 0.         0.         0.         6.0572p    16.613p   
did not converge
 0.05       0.         0.05       26.337p    6.3118p   
did not converge
 0.1        0.         0.1        113.5p     128.1p    
did not converge
 0.15       0.         0.15       480.74p    445.92p   
 0.2        0.         0.2        1.973n     1.9389n   
 0.25       0.         0.25       7.7037n    7.6796n   
===========
The answers look reasonable, but it reported non-convergence. 
They agree with ng-spice.
What's going on?
I ran it interactively so I could look deeper.
===========
gnucap> print op v(nodes)

gnucap> op

#           v(1)       v(2)       v(3)       v(4)      
did not converge
 27.        3.         0.         3.         3.        
gnucap> op trace iter

#           v(1)       v(2)       v(3)       v(4)      
 0.         0.         0.         0.         0.        
-1.         0.050757   0.         3.         0.050757  
-2.        -0.046671   0.         3.        -0.046671  
-3.         37.025K    0.         3.         37.025K   
-4.         3.0129     0.         3.         3.0129    
-5.         3.         0.         3.         3.        
-6.         3.         0.         3.         3.        
-7.         3.         0.         3.         3.        
-8.         3.         0.         3.         3.        
-9.         3.         0.         3.         3.      
..........
-97.        3.         0.         3.         3.        
-98.        3.         0.         3.         3.        
-99.        3.         0.         3.         3.        
-100.       3.         0.         3.         3.        
did not converge
 27.        3.         0.         3.         3.        
gnucap> 
============
It looks like it does converge.
Keep looking.. find out what is happening..
============
gnucap> print op ids(m2) gm(m2) vds(m2)

gnucap> op

#           ids(M2)    gm(M2)     vds(M2)   
did not converge
 27.        16.613p    5.0558p   -92.313n   
gnucap> op trace iter

#           ids(M2)    gm(M2)     vds(M2)   
 0.         16.613p    5.0558p    0.        
-1.         0.         0.         2.9492    
-2.         7.787f     256.17f    3.0467    
-3.         21.475u    37.359u   -37.022K   
-4.         49.615u    13.935u   -0.012887  
-5.         1.2425u    377.33n   -10.415u   
-6.         1.0034n    305.36p    47.816n   
-7.         4.6039p    1.4012p    150.88n   
-8.         14.528p    4.4213p   -151.78n   
-9.         14.614p    4.4475p   -71.466n   
-10.        6.881p     2.0942p    9.1773n   
-11.        883.63f    268.92f    94.368n   
-12.        9.0861p    2.7653p   -234.44n   
-13.        22.572p    6.8697p   -154.47n   
-14.        14.873p    4.5264p   -74.169n   
-15.        7.1413p    2.1734p    6.4631n   
.......
-95.        11.144p    3.3915p   -203.18n   
-96.        19.563p    5.9537p   -123.08n   
-97.        11.851p    3.6066p   -42.651n   
-98.        4.1066p    1.2498p    38.112n   
-99.        3.6695p    1.1168p    136.69n   
-100.       13.161p    4.0053p   -172.54n   
did not converge
 27.        16.613p    5.0558p   -92.313n   
gnucap> 
===========
Ah ...  Numerical noise.
Loosen "abstol" and it is ok.
============
gnucap> opt abstol=10p

gnucap> op

#           ids(M2)    gm(M2)     vds(M2)   
 27.        14.528p    4.4213p   -151.78n   
gnucap> op trace iter

#           ids(M2)    gm(M2)     vds(M2)   
 0.         14.528p    4.4213p    0.        
-1.         0.         0.         2.9492    
-2.         7.787f     256.17f    3.0467    
-3.         21.475u    37.359u   -37.022K   
-4.         49.615u    13.935u   -0.012887  
-5.         1.2425u    377.33n   -10.415u   
-6.         1.0034n    305.36p    47.816n   
-7.         4.6039p    1.4012p    150.88n   
-8.         14.528p    4.4213p   -151.78n   
 27.        14.528p    4.4213p   -151.78n   
gnucap> 
==========

ok ....  (This is the developer list so I went a bit deeper than 
I would for a newbie.)

Why does gnucap have the convergence problem but not spice?

Reason: Because Spice doesn't check the parameter that didn't 
converge.

This is an issue that has come up several times.  I had one a 
while back (ngspice converged, gnucap didn't) where ngspice 
converged to a believable wrong answer, with not even a 
warning.  This prompted improvements to gnucap time step 
control, so now for that case, gnucap converges to the correct 
answer, ng-spice (PSPICE too!) converged to a believable 
incorrect answer, without any hint of a problem.

This is a tradeoff ...  Gnucap convergence checking is very 
strict, and sometimes reports non-convergence when there is 
really no problem.  Spice convergence checking is weak, and 
sometimes allows bad results through without even a hint of a 
problem.  Which would you rather have?

Back to your example ...  100u feature size with a .25u process?  
In this case, those parameters should be required, and a 
warning issued that they are missing.  Here's room for 
improvement.  Actually, a warning is issued, but it could be 
improved.

How's this?

al.


---  I fixed the bug so the defaults are filled in now.  It's 
in "d_mos.model":
line 289:
  common {
    raw_parameters {
      double m "device multiplier"
        name=M default=1.0 positive print_test="m != 1.";
      double l_in "drawn (optical) channel length"
        name=L positive default="OPT::defl";
      double w_in "channel width (drawn)" 
        name=W positive default="OPT::defw";
      double ad_in "drain area, drawn"
        name=AD positive default="OPT::defad"
        print_test="has_hard_value(ad_in)";
      double as_in "source area, drawn" 
        name=AS positive default="OPT::defas"
        print_test="has_hard_value(as_in)";





reply via email to

[Prev in Thread] Current Thread [Next in Thread]