MOSFET Level 103 PSP model DTA parameter

102 views
Skip to first unread message

Mario Krattenmacher

unread,
Sep 15, 2023, 3:58:03 AM9/15/23
to xyce-users
Hi,

I am currently verifying the usage of the PSP model inside the IHP OpenPDK.
OpenPDK: https://github.com/IHP-GmbH/IHP-Open-PDK
our repo for the verification: https://gitlab.com/dmt-development/ihp_sg13g2_compact_models

During this, I noticed that the PSP model has the Parameter DTA (Temperature offset w.r.t. ambient circuit temperature)  defined as a model parameter. In the commercial PDK DTA is used as an instance parameter, which makes much more sense. Can you change that for the upcoming version of Xyce?

Best regards
Mario

Dietmar Warning

unread,
Sep 15, 2023, 3:20:08 PM9/15/23
to xyce-users
IMO it is more a question to the PSP model authors. For what reason ever they have decided to use DTA as model parameter.
For ADMS/Xyce you have to shift TempInitialize code in version 103.8.0 PSP103_module.include, line 607 ff. from initial_model block to initial_instance block.
Seems no problem with openVAF, see my github rep.

xyce-users

unread,
Sep 16, 2023, 11:56:22 AM9/16/23
to xyce-users
We done this for a few other models, for similar reasons.  Often the original group that develops a model will make a parameter be model-only but then the various commercial simulators will choose to make it an optional instance parameter.  Then, foundry PDKs will make use of the feature.

I agree with Dietmar that it would be best if the PSP developers supported this directly.  However, It generally is easy to do this ourselves, as Dietmar points out.  Usually, when we do this, we make it so that the parameter is supported both on the instance and model levels, with the instance parameter taking priority when specified.

I'll add this to our internal issue tracker.

thanks,
Eric

Tom Russo

unread,
Sep 16, 2023, 12:20:19 PM9/16/23
to xyce-users
Just a quick note to add to your internal issue so whoever is saddled with dealing with this has a good picture of the task ahead (it's not an enormous task):

It is very easy to tweak the Verilog-A source code to turn a single parameter from model-only to instance-and-model, and there are numerous examples of where this was done throughout Xyce/utils/ADMS/examples.

You will find this in Xyce/utils/ADMS/examples/psp103/Common103_macrodefs.include:
      `define MPRnb(nam,def,uni,        des) (*units=uni                            , desc=des*) parameter real    nam=def;
and then in PSP103_module_include:
      `MPRnb(DTA            ,0.0        ,"K"                                  ,"Temperature offset w.r.t. ambient temperature")
This is the CMC standard macro for "make this parameter a model parameter with no bounds declared".

The pattern I always used in other devices was simply to add a second macro for "make this parameter both model and instance":
      `define MPRnb_BOTH(nam,def,uni,        des) (*units=uni                            , desc=des, type="instance", xyceAlsoModel="yes" *) parameter real    nam=def;
and change the declaration of the parameter to use the _BOTH version instead.

When Xyce/ADMS sees the "instance" and "xyceAlsoModel" attributes, it creates a model parameter and instance parameter and then emits code linking the two in the instance class processParams function (so if it's not given in the instance, the instance version is set from the version in the model).

As Dietmar notes, however, PSP has a block of code marked as "initial_model" that makes use of this parameter, and so for this model one needs to proceed cautiously --- if one did nothing but the above one would have a problem with model-scoped variables being set from instance parameters (wich is illegal) or not being assigned correct values when the value of the instance parameter differs from the model's.  Specifically, the model attempts to assign a temperature variable (TKA) the value $temperature+DTA.  This is done in a block of code that Xyce/ADMS then puts at model scope (so TKA is a member of the model class, as are all the variables that are set from TKA).  From PSP103_module.include:
`ifdef insideADMS
            @(initial_model)
`endif
            begin : initial_model
...
                // Transistor temperature
                TR_i        = `CLIP_LOW(TR, -273.0);
                TKR         = `KELVINCONVERSION + TR_i;
                TKA         =  $temperature + DTA;
                rTa         =  TKA / TKR;
                delTa       =  TKA - TKR;
                phita       =  TKA * `KBOL / `QELE;
                inv_phita   =  1.0 / phita;
                `ifdef SelfHeating
                // do nothing
                `else // SelfHeating
                TKD         =  TKA;
                `TempInitialize
                `endif // SelfHeating

...
        end // initial_model


All use of any variable that depends even indirectly on DTA in this block would then have to be moved to the other block of code that does instance initialization.

This is entirely an artifact of how Xyce/ADMS places Verilog-a bits into Xyce's two processParameters functions.  Verilog-A itself *has* no concept of model and instance scoping, it is kludged by ADMS and the Xyce/ADMS back-end with the pseudo-events "@(initial_instance)" and "@(initial_model)" to fit the more SPICE-like approach and to deal with ADMS's difficulty in segregating bias-independent computations from bias-dependent.  So for use in Xyce/ADMS the bias-independent computations are collected under the pseudo-events in the Verilog-a source (hence the insideADMS ifdef) .  The code in the pseudo-event blocks are simply placed in the instance- and model-class processParams functions instead of the updateIntermediateVars function.



--
You received this message because you are subscribed to the Google Groups "xyce-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to xyce-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/xyce-users/53daec68-5549-4be8-ae4b-aa9006f565efn%40googlegroups.com.


--
Tom Russo    KM5VY 
Tijeras, NM 

 echo "prpv_a'rfg_cnf_har_cvcr" | sed -e 's/_/ /g' | tr [a-m][n-z] [n-z][a-m]

Tom Russo

unread,
Sep 16, 2023, 12:24:09 PM9/16/23
to xyce-users
OBTW, PSP103 and JUNCAP2000 (in the same directory and sharing some code) both have similar problems, and both would need to be fixed in the same way.

Dietmar Warning

unread,
Sep 18, 2023, 2:51:22 AM9/18/23
to xyce-users
Tom,
thanks for your elaborate analysis.
I used the MPRnb_BOTH() macro in the PSP103 model on the plugin way, Building the shared lib was successful without a flaw but running a test case with DTA as an instance parameter not. The code of the model regarding the temp update in initial_model block was not modified and was accepted by adms.
I can change the instance DTA without effect. Changing model parameter is OK.
Kind Regards,
Dietmar

Tom Russo

unread,
Sep 18, 2023, 9:23:14 AM9/18/23
to Dietmar Warning, xyce-users
The problem you're experiencing ("I can change the instance DTA without effect.") is precisely because you did not move the temperature initialization code from the initialize_model block to initialize_instance.

What's happening is this:  Xyce/ADMS has generated code that defines both a model parameter DTA and an instance parameter DTA, and added code to Xyce's Instance::processParams function that copies the value of the model parameter into the instance if the instance is not specified.  That was accomplished by your having added the 'type="instance",xyceAlsoModel="yes"' attributes to that parameter.

And the initial_model code is put into the Model::processParams function, where it initializes TKA and all of the other temperature dependent variables from the MODEL version of the parameter (which is the only parameter the model class knows about).  Changing the instance parameter will have no effect on any of those downstream variables, and hence will have no effect on any model calculations at all.  You *must* move that code to initialize_instance (probably at the beginning of the block, because if I recall correctly initiali_instance actually references some of the model variables that are set in initial_model like "phita" and "delTa".

Move the whole block of code:
                // Transistor temperature
                TR_i        = `CLIP_LOW(TR, -273.0);
                TKR         = `KELVINCONVERSION + TR_i;
                TKA         =  $temperature + DTA;
                rTa         =  TKA / TKR;
                delTa       =  TKA - TKR;
                phita       =  TKA * `KBOL / `QELE;
                inv_phita   =  1.0 / phita;
                `ifdef SelfHeating
                // do nothing
                `else // SelfHeating
                TKD         =  TKA;
                `TempInitialize
                `endif // SelfHeating
out of initial_model and into initial_instance somewhere before any use of the variables set here, and it should be right.

I wasn't sure if Xyce/ADMS would emit invalid code (Model::processParams accessing instance parameters, which is illegal) or if it would just be wrong like this, which is why I said: " if one did nothing but the above one would have a problem with model-scoped variables being set from instance parameters (wich is illegal) or not being assigned correct values when the value of the instance parameter differs from the model's".  You have shown that it's the second part of that --- not being assigned correct values.




Dietmar Warning

unread,
Sep 18, 2023, 9:58:56 AM9/18/23
to xyce-users
OK - now I rearranged the code:

Common103_macrodefs.include:
`ifdef __XYCE__
`define MPRnb_BOTH(nam,def,uni, des) (*units=uni, desc=des, type="instance", xyceAlsoModel="yes" *) parameter real nam=def;
`endif

PSP103_parlist.include:
`ifdef __OPENVAF__
`IPRnb(DTA            ,0.0        ,"K"                                  ,"Temperature offset w.r.t. ambient temperature")
`elsif __XYCE__
`MPRnb_BOTH(DTA       ,0.0        ,"K"                                  ,"Temperature offset w.r.t. ambient temperature")
`else

`MPRnb(DTA            ,0.0        ,"K"                                  ,"Temperature offset w.r.t. ambient temperature")
`endif
`ALIAS(TRISE, DTA)


PSP103_module.include (only excerpt to show principle of Temp code shift):
   @(initial_model)
    begin : initial_model
    .
    .
`ifndef insideADMS
        //  Transistor temperature
        TKR         = `KELVINCONVERSION + TR;

        TKA         =  $temperature + DTA;
        rTa         =  TKA / TKR;
        delTa       =  TKA - TKR;
        phita       =  TKA * `KBOL / `QELE;
        inv_phita   =  1.0 / phita;
        `ifdef SelfHeating
            // do nothing
        `else // SelfHeating
            TKD         =  TKA;
            `TempInitialize
        `endif // SelfHeating

        // JUNCAP2
        `include "JUNCAP200_InitModel.include"
`endif

    end // initial_model

@(initial_instancel)
    begin : initial_instance
    .
    .
`ifdef insideADMS
        //  Transistor temperature
        TKR         = `KELVINCONVERSION + TR;

        TKA         =  $temperature + DTA;
        rTa         =  TKA / TKR;
        delTa       =  TKA - TKR;
        phita       =  TKA * `KBOL / `QELE;
        inv_phita   =  1.0 / phita;
        `ifdef SelfHeating
            // do nothing
        `else // SelfHeating
            TKD         =  TKA;
            `TempInitialize
        `endif // SelfHeating

        // JUNCAP2
        `include "JUNCAP200_InitModel.include"  <<<<<<<<<<<<<<<<<< needed because of DTA usage
`endif
       .
       .

  end // initial_instance

This works fine for DTA as instance with the IPRnb() macro above, (commenting the __XYCE__ branche above)
But using MPRnb_BOTH() macro code is accepted and compiles but Xyce complains about unknown instance parameter DTA.

Mario Krattenmacher

unread,
Sep 18, 2023, 11:25:00 AM9/18/23
to xyce-users
Also thanks from my side to all.

My intention was less to fix the Verilog-A code (for that, I mailed to the PSP maintainers a similar request), but to have the built-in model changed. Thank you, Eric, for adding this to your issue tracker. For a PDK, Verilog-A models are possible, but as Xyce then changes the command line syntax, I would prefer to avoid that in the long run.

Regarding the Verilog-A code, the PSP development team hinted me towards the next releases:

The definition of DTA parameter as model parameter comes from older versions.
PSP is a standard model. Consequently, we follow the CMC (Compact Model Coalition) recommendation.
To control the device temperature, you can use TRISE or DTEMP instance parameters from PSP103.8.1.

So a final and clean solution to this, is to switch to PSP 103.8.2. It will be publically available starting December 2023 (https://www.cea.fr/cea-tech/leti/pspsupport/CurrentRelease), just in time for the next Xyce release.

Best regards
Mario

Tom Russo

unread,
Sep 18, 2023, 1:54:56 PM9/18/23
to Dietmar Warning, xyce-users
I am not exactly sure why your changes didn't work, but I have just tried it using the built-in PSP model and gotten it to work just fine.  I have not tried to do exactly what you did, I simply hacked on the one in the Xyce source tree, which is PSP 103.4.0, not the more recent version  you have.  The two changes I suggested were all that was needed (changing the declaration of the parameter and moving that little block of temperature dependent code (including the include of juncap model initialization code as you noted was necessary --- this has the unfortunate side effect of elevating all of those  bias-independent JUNCAP calculations from model level to instance level, but without deeper hackage it's the best one can do).

Since I already got it done, I went ahead and created two patches, which I am attaching here.  The first should be applied to your git clone of the Xyce source tree ( cd /path/to/Xyce; patch < /path/to/0001-Make-PSP103-DTA-parameter-be-instance-model.patch) and will change both the PSP103 Verilog-A source *AND* the processed version of it in the DeviceModelPKG to make DTA be an instance parameter as well as model.  It moves the relevant block of code from initial_model to initial_instance.

The second patch should be applied to the Xyce_Regression clone and adds a test of the feature.  The test runs one version of a PSP inverter at T=100°C (using ".options device temp=100"), then runs two other netlists that exercise DTA (one puts DTA=73 in the model cards and .options device temp=27, and the other puts the DTA on the instance line INSTEAD of in the model card).  It compares the three and only passes if they all match.

Since these two patches get this issue to what Mario asked for, I choose to post it here.  Since it is something like 90% of what the Xyce team would have to do for this issue, I am releasing it to the Xyce team with no license restrictions whatsoever so they can simply patch it and call it their own if they wish without concern for GPL licensing restrictions.  The 10% not done would be similar hacks on the JUNCAP200 model (which suffers the same problem) and any release notes changes they'd have to do to call it done.  I have included in my patch an update to the reference guide instance parameter tables for PSP103VA and PSP103TVA (levels 103 and 1031).  Of course, they can also just ignore these patches and do it themselves with all that extra staffing they must have right now :)

Mario, feel free to make use of these patches if you are building Xyce from source.  They should give you what you are asking for while you are waiting for the official update from the Xyce team.

0001-Make-PSP103-DTA-parameter-be-instance-model.patch
0001-Add-a-test-for-PSP-DTA-parameter-on-instance-line.patch

xyce-users

unread,
Sep 18, 2023, 2:01:44 PM9/18/23
to xyce-users
thanks Tom!

Eric

Mehmet Cirit

unread,
Sep 18, 2023, 3:02:25 PM9/18/23
to Mario Krattenmacher, xyce-users
Hi Mario,

I  think it is crazy to use differential temperature as a model parameter, unless these devices are sensitive to temperature gradients. In that case, it can not substitute for temperature even after addition or subtraction.  Temperature is an environment variable, and one should be able
to specify it for each instance, the same way as l and w. It should be named temperature, nothing else.

At one point I had a problem with these models, if I remember it was not simulating correctly for big circuits under some env conditions. I had looked at some literature on this model at the time, and noticed that they had to solve a pair of implicit nonlinear equations to come up with the channel current, and they were using various approximations to do it. Spice has a nonlinear solver already. In principle, it will do a better job than the approximate solution.

If they are still using the approximate method, you can remind them they should formulate
their model in a way to let spice solve their nonlinear equation. That will take one more internal node.



--

Dr. Mehmet A. Cirit                    Phone:  (408) 647-6025
Library Technologies, Inc.        Cell:       (408) 647-6025
19959 Lanark Lane                   http://www.libtech.com
Saratoga, CA 95070                 Email: m...@libtech.com
Message has been deleted
Message has been deleted

Tom Russo

unread,
Sep 22, 2023, 8:26:48 AM9/22/23
to xyce-users
All:  Google Groups is acting up again and starting to flag messages in this thread as spam.  The result is that messages get held for moderation, and even if approved show up in the web-based view as "deleted".  We have never found out why this happens and our support requests go unanswered.  That has happened to the last two posts from Mario and Dietmar.

Dietmar:  We use admsXml exactly as provided by its authors, and as you have noted, it does not support "elsif" at all.  I already commented on your github issue for the ADMS maintainers that it doesn't work, and it is not clear that it is a quick fix to make it work properly.  The preprocessor for ADMS would require some careful modification in the lexer and parser specifications.  Maybe one of its maintainers will jump in and fix it, but I don't think anyone is spending a lot of time on ADMS anymore.

Mario:  Yes, requiring end users not only to use ADMS and the plugin feature *and* patch Xyce to support the PDK is not an option.  Hopefully the Xyce team will have it fixed shortly.  I hope my patches help them out.  The team's standard 6 month release cycle would mean that Xyce 7.8 should come out in November or thereabouts, barring unforeseen delays such as those that delayed 7.7.

On Fri, Sep 22, 2023 at 6:16 AM Dietmar Warning <dietmar...@gmail.com> wrote:
Tom,
I applied your patch only to the VA code and it works very well with latest psp version on the buildxyceplugin way too.
The problem with my code was simple: My admsXml do not handle the "`elsif" compiler directive, same for elseif and elif.
So the block
`ifdef __OPENVAF__
`IPRnb(DTA            ,0.0        ,"K"                                  ,"Temperature offset w.r.t. ambient temperature")
`elsif __XYCE__
`MPRnb_BOTH(DTA       ,0.0        ,"K"                                  ,"Temperature offset w.r.t. ambient temperature")
`else
`MPRnb(DTA            ,0.0        ,"K"                                  ,"Temperature offset w.r.t. ambient temperature")
`endif
landing anytime in MPRnb() macro. Without complaining!

How your admsXml would handle this block?
Reply all
Reply to author
Forward
Message has been deleted
Message has been deleted
0 new messages