• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Custom IC Design
  3. Is there a way to describe the charge across the device...

Stats

  • Locked Locked
  • Replies 23
  • Subscribers 126
  • Views 22929
  • Members are here 0
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Is there a way to describe the charge across the device as a function of voltage?

funfet
funfet over 7 years ago

Suppose I were to write the current across an ideal capacitor having terminals t1 and t2 and capacitance c. The code might look something like this:

   I(t1,t2) <+ c*ddt(V(t1,t2));


I'm trying to come up with a code that will instead keep track of the charge across the device like this:

Q(t1, t2) <+ .... ;

Where Q would keep track of the charge across the terminals.

Thank you for any feedback.
  • Cancel
  • Frank Wiedmann
    Frank Wiedmann over 7 years ago

    I suggest you take a look at http://www.designers-guide.org/Modeling/varactors.pdf.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • funfet
    funfet over 7 years ago in reply to Frank Wiedmann

    I tried using the ddt function. I think that's what you were suggesting. The ddt function seems to be giving me a value of zero even if the argument is not a constant.

    Below is the code followed by the graphical results captured by the ADE. The polarization variable (blue) is changing while ddt_polarization (red) is constant even though I would suspect that it should be the derivative of the polarization variable.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 7 years ago in reply to funfet

    It would help if you provided the complete code rather than just a two line snippet. Given that the ddt function is used in countless models (and it's a pretty vital part of VerilogA modelling), it's unlikely to be a general problem but a specific issue with how you're using (it could be a bug with the specific usage, or it could be a bug in your model).

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • funfet
    funfet over 7 years ago in reply to Andrew Beckett

    I posted my code before but no one responded. I think it may be difficult to interpret the code but here it is again. Unfortunately the source code feature of the website isn't working so I can't post it in a neat format.

    Basically the device is a capacitor with a hysteresis behavior instead of a linear behavior like an ideal linear capacitor. If this example is too difficult I can come up with something simpler to illustrate my point (let me know). Preisach_175C.csv is a file that describes the hysteresis behavior of the capacitor. The current should be proportional to the time derivative of the variable "polarization". The line I(p,n) <+ ddt(polarization)*0.00000000001135;  sets the current proportional to the derivative of the polarization but even when the polarization is changing the current always remains zero. Please help.

    P.S.

    I would prefer to have the model be implemented using charge instead of current. Is there something which would allow me to write an equation similar to Q(p,n) <+ polarization*0.00000000001135; which would allow me to set the charge across the terminals p and n instead of the current?

    // VerilogA for test_func10, test_func10, veriloga

    `include "constants.vams"
    `include "disciplines.vams"

    module test_func10(p,n);

        inout p,n;
        electrical p,n;

        //files for reading/writing
        integer mcd;//fp originally

        real v_step;

        real preisach_density[0:65536];// all elements should add up to 1
        real domain_states[0:65536];// all elements should be -1 or +1 (depending on polarity)
        real polarization;//polarization (between -Pr and +Pr)
        
        real polarization_prev, polarization_next;
        real time_prev, time_next;
        real v_prev, v_next;

        // for debugging purposes
        real delta_t; // change in time
        real delta_p; // change in polarization
        real delta_v; // change in voltage
        real ddt_polarization;//time derivative polarization

        integer row_offset, column_offset;

        real current_calc;

        real thermal_depolarization_r;//effect of thermal depolarization
        real equivalent_curie_t;//equivalent curie temp
        real ambient_temperature;

        integer i, j, k;//used in loops

        integer rows, columns;//describes area scanned from applied voltage
        integer rows_total, columns_total;//gives number of rows and columns in the grid ("rows" and "columns" should not exceed these values)
        
        analog begin    

            @(initial_step) begin

                //read data from csv file and transfer it to verilog-A array variable
                //data stored in csv file should be preisach distribution
                //csv file should have the same number of elements as arrays "preisach_density" and "domain_states"
                
                // TEST IMPRINT PREISACH
                mcd=$fopen("preisach_175C.csv","r");

                //DEFAULT
                //mcd=$fopen("pzt_256x256_ikeda.csv","r");
                
                //DISREGARD
                //mcd=$fopen("ikeda_256x256_final.csv","r");
                //mcd=$fopen("gold_wafer_256x256.csv","r");

                while (!$feof(mcd)) begin

                    $fscanf(mcd,"%f", preisach_density[i]);
                    domain_states[i] = 0;

                    i = i+1;
                      end

            // steps to change resolution:
            // change file name, "gold_wafer_32x32.csv" e.g.
            // change value of variable v_step (.1 for 32x32, .05 for 64x64, .025 for 128x128)
            // change values of variables row_offset and column offset (17 for 32x32, 33 for 64x64, 65 for 128x128)
            // change size of preisach_density and domain states arrays (1024 for 32x32, 4096 for 64x64, 16384 for 128x128)


            //****************** v_step should be changed, should equal resolution of grid spacing
            v_step = 0.0109375; //arbitrary  -------- NORMALLY .0125 = 3.2/256

            rows_total = 2.8/v_step;//the maximum anticipated applied input voltage swing divided by the resolution of the grid cells ------------ NORMALLY 3.2/v_step
            columns_total = 2.8/v_step;//the maximum anticipated applied input voltage swing divided by the resolution of the grid cells   ----------- NORMALLY 3.2/v_step

            v_next = V(p,n);

            time_prev = 0;
            time_next = 0;
            
            //TESTING for -1.4 V to 1.6 V hysteresis loop 137 and 121 were obtained the following way
            //137 = 129 + .1/.0125
            //121 = 129 - .1/.0125

            // centers the indiciess to the beginning of the fourth quadrant of the Preisach distribution
            row_offset = 129;//129 for symmetric hysteresis
            column_offset = 129;//129 for symmetric hysteresis

            

            //thermal depolarization effect
            //all temperatures in Kelvin
            equivalent_curie_t = 603;
            ambient_temperature = $temperature;
            thermal_depolarization_r = sqrt((equivalent_curie_t - $temperature)/(equivalent_curie_t - 298));
            //thermal_depolarization_r = $temperature;
            
            end



            if (v_next < v_prev) begin // negative voltage derivative

                rows = row_offset + V(p,n)/(-v_step);
                
                //testing
                begin
                if(rows > rows_total)
                    rows = rows_total;
                else if(rows < 0)
                    rows = 0;
                end

                for(j = 0; j < columns_total; j=j+1) begin

                    for(k=0; k<rows; k=k+1) begin

                        //testing 11_19_2017
                        //domain_states[k*columns_total + j] = -1;

                        //ORIGINAL
                        domain_states[rows_total*j + k] = -1;

                    end
                end
            end

            if (v_next > v_prev) begin

                columns = column_offset + V(p,n)/(v_step);

                //testing
                begin
                if(columns > columns_total)
                    columns = columns_total;
                else if(columns < 0)
                    columns = 0;
                end

                //value compared to j should equal number of columns in array
                //for (j=0; j<columns * rows_total ; j=j+1) begin

                //domain_states[j] = 1;

                //end

                //value compared to j should equal number of columns in array
                for (j=0; j<columns; j=j+1) begin
                    
                    for(k=0; k < rows_total; k=k+1) begin

                        //testing 11_19_2017
                        //domain_states[k*columns_total + j] = 1;

                        //ORIGINAL
                        domain_states[rows_total*j + k] = 1;

                    end

                end            

            end

            //@(timer(0,0.3)) begin


                polarization = 0;
                for (i=0; i<columns_total*rows_total; i = i+1) begin

                    polarization = polarization + preisach_density[i]*domain_states[i];

                end

        //end

        //testing timer function
        //@(timer(0,1)) begin //.000001 usecond //.5 seconds

            //polarization_prev = transition(polarization_next, 0, 1);
            //polarization_next = transition(polarization, 0, 1);



                polarization_prev = polarization_next;
                polarization_next = thermal_depolarization_r * polarization;


                v_prev = v_next;
                v_next = V(p,n);
                time_prev = time_next;
                time_next = $abstime;
            
                // debugging purposes
                delta_t = time_next - time_prev;
                delta_p = polarization_next - polarization_prev;
                delta_v = v_next - v_prev;

                
                    //if (time_next == 0)

                        //current_calc = 0;

                    //else


                        //current_calc = (polarization_next - polarization_prev)/(time_next - time_prev)*0.00000000001135; // normally 0000000001135
                        
                        //testing
                        //ddt_polarization = ddt(polarization);
                        //current_calc = ddt(polarization)*0.00000000001135;

                    //end

                
            
            //I(p,n) <+ transition(current_calc);

            //testing
            $bound_step(2e-7);

            I(p,n) <+ ddt(polarization)*0.00000000001135;
            

        end



    endmodule

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 7 years ago in reply to funfet
    funfet said:
    I posted my code before but no one responded

    No idea where you posted it - I can find two previous posts from you (not in this thread) where you provided code, and neither use the ddt function, and neither had no response (well, one you said the issue was resolved, and the other I asked for the test setup too).

    Anyway, putting that aside, can you please provide the Preisach_175C.csv file and also the input.scs that you're testing this with (I'm assuming  you have a schematic and ADE setup and are simulating it that way). If I have the input netlist for spectre, at least I can run the same simulation as you which makes it much easier to debug and understand what you're doing. 

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • mschw
    mschw over 7 years ago in reply to funfet

    Dear Paul,

    i didn't checked it myself, but maybe you can try this variant:

    - define an internal node e.g.
    electrical inner
    -set the inner node to the polarization variable e.g.
    V(inner)<+ polarization;
    -set the current as follows
    I(p,n) <+ ddt(0.00000000001135*V(inner));

    With kinds regards,

    Matthias

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • funfet
    funfet over 7 years ago in reply to Andrew Beckett

    Thank you for the help. I'm working on a server and the input.scs file is inaccessible to me. I will get back to you when I get the file from the network administrator.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • funfet
    funfet over 7 years ago in reply to mschw

    I appreciate the advice but it still doesn't work like how I expect it to. I will work with Andrew to try to resolve the issue but until I can get the requested files I will try to solve the issue along the lines you proposed. Your suggestion gave me some ideas for how to try to get the model to work.

    Thank you

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 7 years ago in reply to funfet

    You ought to be able to do Simulation->Netlist->Display in ADE and then save the netlist from there. I can't really see how you could run the simulation in ADE and yet not have access to the input.scs file - if the tool can access the file, then you should be able to too!

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • funfet
    funfet over 7 years ago in reply to Andrew Beckett

    When I go under simulation->Netlist I only see the following options:

    • Create Raw
    • Display Raw
    • Create Final
    • Display Final

    The path at the top of the two windows is "spectreFinal" and "schematic.c". I cannot see input.scs in the same directory. I get a red message when I try to upload files saying "error" in red above the text "the maximum file size allowed is 750 kb. Filenname should not have more than 15 characters." I don't think either should prevent me from uploading the file since both the file names and sizes are below 15 characters and 750kb. Because of this I don't know of a way to upload the csv file. Below is the content of schematic.c.

    # Generated on Apr 23 12:59:05 2018


    simulator lang=\spectre
    simulator lang=\spectre
    # Include Quantity files


    USE test_func10_schematic_schematic_hysteresis

    # Include file for AHDL
    # HDL text files to be included for this design.
    ahdl_include "/home/UFAD/pchojecki/Desktop/test_func10/test_func10/veriloga/veriloga.va"

    simulator lang=\spice


    simulator lang=\spectre
    simulator lang=\spice

    # Include files





    simulator lang=\spectre

    # End of Netlist

    -------------------------------------------------------------------------------------------------

    Below is the content of SpectreFinal

    --------------------------------------------------------------------------------------------------------

    * # FILE NAME: /HOME/UFAD/PCHOJECKI/CADENCE/SIMULATION/SCHEMATIC/SPECTRES/      

    * begin cppStatements
    #include </home/UFAD/pchojecki/cadence/simulation/schematic/spectreS/schematic_hysteresis/netlist/.cppDefineStatements>
    * end cppStatements

    * schematic_hysteresis/netlist/schematic.c.raw
    * Netlist output for spectreS.
    * Generated on Apr 21 02:10:33 2018
       
       
    simulator lang= spectre
    simulator lang= spectre
    * Include Quantity files
       
       
    * File name: test_func10_schematic_schematic_hysteresis.s.
    * Subcircuit for cell: schematic.
    * Generated for: spectreS.
    * Generated on Apr 21 02:10:34 2018.
       
    ahdli4 (net5 net4) test_func10
    v0 (net5 0)  vsource  type= pwl wave= [ 2e-6 0.0 4e-6 1.6 8e-6 -1.40000000E+00
    +12e-6 1.6 14e-6 0.0 16e-6 0.0 18e-6 1.6 22e-6 -1.60000000E+00 26e-6 1.6 28e-6
    +0.0 30e-6 0.0  ]
    c0 (net4 0)  capacitor c=220e-9 m=1.0
       
    simulator lang= spice
       
       
    simulator lang= spectre
       
    * Include file for AHDL
    * HDL text files to be included for this design.
    ahdl_include "/home/UFAD/pchojecki/Desktop/test_func10/test_func10/veriloga/veriloga.va"
       
    simulator lang= spice
       
       
    simulator lang= spectre
    simulator lang= spice
       
    * Include files
       
       
       
       
       
    simulator lang= spectre
       
    * End of Netlist
    *
    simulator lang=spectre
    tempOptions options
    +       temp=   27.000000    
    keepAllVoltages options save=allpub
    simOptions options
    +          reltol=1m
    +          vabstol=1u
    +          iabstol=1p
    +          tnom=27
    +          scalem=1
    +          scale=1
    +          gmin=1p
    +          rforce=1
    +          maxwarns=5
    +          digits=5
    +          cols=80
    +          pivrel=1m
    +          ckptclock=1.8K
    timeSweep  tran  stop=40e-6  write="spectre.ic"  writefinal="spectre.fc"
    +          annotate=status  compression=no  maxiters=5
    finalTimeOP info what=oppoint where=rawfile
    modelParameter info what=models where=rawfile
    element info what=inst where=rawfile
    outputParameter info what=output where=rawfile

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
>

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information