Open hpretl opened 4 months ago
@bmurmann what do you think? Maybe this also explains some other model things you identified?
Potentially, but the issues I wrote about where also present for ng=1
.
@hpretl I have followed the $R_G$ implementation and I found the exact lines of code in the file PSP103_module.include
, which define it:
1522: RG_p = RSHG_i * (`oneThird * W_f / NGCON_i + XGWE) / (NGCON_i * L_slif) + (RINT_i + RVPOLY_i) / (W_f * L_f) + NF_i * RGO;
1709: RG_i = `CLIP_LOW(RG_p, 0.0);
3065: rg = RG_i / MULT_i;
Also I found this:
1721: MULT_i = `CLIP_LOW(MULT * NF_i, 0.0); // Note: NF_i is set to 1 for local model
Assuming that $R_G$ scales with m
its value should consider the $N_F$ parameter passed indirectly as mult
Could @miesli or @metroid120 comment on that ?
Hi,
yes the "m" or "ng" or "nf" issue is already well known for the PSP model in this PDK. Check also #25 for this.
Basically, the PDK was extracted and scaled like this in the SG13G2 PDK and somehow they decided that this was the best way to do that. @hpretl you are definitely right, that this does not use the PSP model correctly but without a new extraction with new measurements it is not easy to change since this requires most likely to verify all characteristics again.
Best regards
We are speaking about psp Version 103.6.0.
3065: rg = RG_i / MULT_i;
The RG_i scaling by MULT_i is used here for OP variable calculation - not for contribution.
For that we have around line 1826:
if (RG_i > 0.0) begin ggate = 1.0 / RG_i;
This value is used for matrix entry and noise analysis. The scaling is done in macro CollapsableR by multiplying with MULT_i.
So in the end - even with our confusing instantiation - RG should be correct scaled by NF because NF is part of the mult instance parameter.
@hpretl : Could you provide an simple test case to check our assumptions.
My not-very-sophisticated test is this (so maybe I am just interpreting things wrong):
I take a single MOSFET test bench, and look at the model parameters after op
using show
. Setting ng=1
or ng=2
reports the same Rg
, which should not be the case, I think.
Here the netlist: mosfet_diode_sizing.spice.zip
Thanks for the test case. I think the problem is the reporting of the OP variable rg. I put in few strobes into the va code. For ng=1: OSDI(debug) n.xm1.nsg13_lv_nmos: RG_p 100.192 OSDI(debug) n.xm1.nsg13_lv_nmos: RG_i 100.192 OSDI(debug) n.xm1.nsg13_lv_nmos: RG_i 100.192 MULT_i 1 rg 100.192 OSDI(debug) n.xm1.nsg13_lv_nmos: RG_i 100.192 lp_rg 100.192
For ng=2: OSDI(debug) n.xm1.nsg13_lv_nmos: RG_p 200.385 OSDI(debug) n.xm1.nsg13_lv_nmos: RG_i 200.385 OSDI(debug) n.xm1.nsg13_lv_nmos: RG_i 200.385 MULT_i 2 rg 100.192 OSDI(debug) n.xm1.nsg13_lv_nmos: RG_i 200.385 lp_rg 200.385
From code I see that RG_i goes into ggate. ggate will be then multiplied with MULT_i in CollapsableR and brings the correct current into branch.
rg seems buggy maybe it is repaired in newer versions.
I made a double-check and must correct my self: The calculation of RG is not correct with our actual device instantiation in the Open-PDK lib (and in the spectre lib too). At the moment we have
Nsg13_lv_nmos d g s b sg13g2_lv_nmos_psp w='w/ng' l=l mult='ng*m'
In consequence the model internal NF parameter will any time 1. In the formulae above from the psp manual we see that we have an component in RG which is independent fro NF - the RGO part. After calculation of RG_p the value is divided by (MULT*NF) and in MULT we have NG per instantiation. And so for any NG >1 the RGO part is lowered by the finger count. For NG values > 4 the error can be more then 25% dependent from parameter constellation. I made an experiment with following instantiation
Nsg13_lv_nmos d g s b sg13g2_lv_nmos_psp w='w' l=l nf='ng' mult='m'
and get correct RG values for different finger count and separate device multiplier. All values are double checked per excel, debugging printouts in psp model and S-parameter simulation with ngspice (Rg=re(Z11)-re(Z22)/3) to get an rough estimation. Additional checks are made for junction capacitances and currents which are affected by the different calculation scheme for AD, AS, PD and PS. An test case will be provided to the PDK authors.
I made 2 simulations with qucs-s/ngspice (klu enabled) with the mentioned instantiation schemes. Shown is the RG approximation from s-parameter simulation (Rg=re(Z11)-re(Z22)/3) of a w=10um NG=1...8 lv_nmos device with VG=1.2V and VD=0V. The actual implementation shows RG 65 ... 10Ohm:
The proposed new instantiation shows RG 67 ... 45Ohm:
The values are similar then hand calculated values.
I think from view point of noise analysis the optimistic values of the actual implementation are critical. @hpretl @bmurmann - your opinions?
@dwarning I think we should fix this so that we get most realistic behavior due to RG. A question that I have: Why is RF only going down from 67 to 45Ohm when NG is increased from 1 to 8? I would assume that RG goes down with NG^2 (W per finger = W/NG, so RG/finger = RG/NG), and then NG fingers in parallel, so $R_G(NG) = R_G(NG=1) / NG^2$?
Don't really know. But if you look to the formulae you see an NF independent term (our problem we have). This is the resistance from contact to beginning of fingers I think.
I want show here my testbench for RG from S-parameter:
Would be nice if someone could make same in spectre.
When I do a simple testbench in ngspice simulating just a single LV-NMOS (I assume it is the same for PMOS and HV variants, but I have not checked it), I see that the model parameter
rg
is not reacting to the number of fingers I set. This is not ideal, as the PSP model can model extrinsic resistances.From the PSP model doc:
The calculation of
rg
is:In the model file of IHP's PDK, the PSP model is instantiated like that:
This means that essentially the
nf
(number of fingers, here calledng
, which is not consistent) parameter is never passed on to the PSP model, instead only the width of a single finger is used in the model, and the multiplier parameterm
is then increased bynf
as passed on to the model asmult=ng*m
. In this way, the intrinsic model does not know about the truenf
andm
parameters. This is also confirmed by looking at the model parameters in ngspice, which always showsnf=1
.Maybe this can be changed in a future release? It looks like some capabilities of the PSP model are bypassed in this way.