Open hpretl opened 1 month 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.
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.