• 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. Post Trimming Simulation for Oscillator Circuit

Stats

  • Locked Locked
  • Replies 8
  • Subscribers 126
  • Views 10281
  • 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

Post Trimming Simulation for Oscillator Circuit

yoshi777
yoshi777 over 2 years ago

Hello Cadence Support,

Could you please tell me how to perform a post-trim simulation on an oscillator circuit? 

Specifically, post-trim simulation on an oscillator involves:

1) Finding an optimal trimming code for the oscillator circuit, process corner by process corner.

2) Running a simulation with the optimal trimming code process corner by process corner.

I have already read and tried the following Rapid Adoption Kits:

Techniques for Simulating Calibrated Circuits with Virtuoso ADE Assembler (cadence.com),

where an optimal trimming code found in "calibration" (DC simulation test) is passed to the next test, "main_test". Thus, the example used in the RAK above can run the "main_test" with optimal trimming code for each process corner.

I would like to extend the similar simulations with calibration (trimming) plus post-trim simulation for an oscillator circuit. However, in an oscillator simulation, one simulation (one transient analysis) cannot find an optimal trimming code, unlike the example used in the RAK, where one DC simulation can find the optimal trimming code. Instead, even just for calibration, multiple simulations are needed to calibrate (trim) and find the optimal trimming code in an oscillator simulation.

In this case, are there any ways how to 

1) Automatically find the optimal trimming code among the multiple transient simulations for calibration sweeping one parameter.

2) Pass the optimal trimming code found among the multiple transient simulations for calibration to a final simulation.

by extending the method described in the RAK document above?

Best regards,

Yoshi

  • Cancel
  • ShawnLogan
    ShawnLogan over 2 years ago

    Dear Yoshi,

    Did you explore the use of a Run plan to perform your multiple simulation calibration process? I don't know the details of the mechanism for choosing your "optimal trim" code from the multiple simulations, but you could use a pre-run ocean script to select the optimal code following your run plan and set the code for the post-calibration simulation.

    Shawn

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • yoshi777
    yoshi777 over 2 years ago in reply to ShawnLogan

    Dear Shawn,

    Thank you for your comment. 

    As for the mechanism of choosing the "optimal trim" code for the oscillator simulation, let's suppose it's a frequency trimming code with which the oscillator frequency is the closest to the target frequency.

    For example, if trimming is done at 1.8V/25deg and trim code is 3bit (trim = 0, 1, 2, ...., 7), targeting 1MHz oscillator frequency.

    Point here is that when sweeping the trim code in the transient simulations, each trim code (trim = 0, 1, 2, ...., 7) is treated as a sort of different "corner" so that I cannot extract the optimal trim code automatically among the multiple transient simulations using measurement function.

    One possible way I can come up with is using a verilog-A code to sweep the trim code in a single transient simulation, to use measurement function. However, in this case, the trim search for an oscillator turns out to be very time-consuming because it cannot be parallelized.


    Do you think in this case above the combination of a Run plan and a pre-run ocean script can solve the issue? 

    I have not used a Run plan and a pre-run ocean script yet. I will search the information for the newly added function in the ADE assembler.

    Best regards,
    Yoshi

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • ShawnLogan
    ShawnLogan over 2 years ago in reply to yoshi777

    Dear yoshi777,

    yoshi777 said:
    Point here is that when sweeping the trim code in the transient simulations, each trim code (trim = 0, 1, 2, ...., 7) is treated as a sort of different "corner" so that I cannot extract the optimal trim code automatically among the multiple transient simulations using measurement function.

    If the individual transient simulations are time consuming, I might suggest you consider using a binary search algorithm in lieu of performing the 8 simulations as long as the relationship between oscillator frequency error and trim code is monotonic. This will reduce the number of simulations from 8 to 3 or 4.

    You might also consider using a simple verilog-A based ADC to create the 8 binary trim code from a single decimal design variable. I posted an example 8 bit ADC verilog-A compatible with transient simulations at the Forum post:

    https://community.cadence.com/cadence_technology_forums/f/mixed-signal-design/52025/verilog-a-analog-event-needed-to-create-a-decimal-to-binary-block

    Use this code as the veriloga view of an 8 bit ADC symbol you create with the appropriate inputs and outputs and instantiate it in your schematic. One input to the ADC will be a voltage source whose value is a design variable, for example, "code_val_decimal" and will be swept using either my suggested binary search or your exhaustive search.

    yoshi777 said:
    Do you think in this case above the combination of a Run plan and a pre-run ocean script can solve the issue? 

    There is an example of using a binary search to trim a voltage reference using a pre-run script in the Jul 2020 RAK "Techniques for Simulating Calibrated Circuits, Virtuoso ADE Assembler at URL:

    support.cadence.com/.../ArticleAttachmentPortal

    referred to on page 67.

    I think you mentioned you viewed this document. Is there a reason why this might not satisfy your calibration methodology that I might be overlooking?

    Shawn

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • yoshi777
    yoshi777 over 2 years ago in reply to ShawnLogan
    ShawnLogan said:
    I think you mentioned you viewed this document. Is there a reason why this might not satisfy your calibration methodology that I might be overlooking?

    I believe the difference in the oscillator trimming simulation from the example in the RAK is NOT fully delivered.


    1) Voltage Reference Trim

    1-1) Trimming Search
    In case of voltage reference trim, trimming simulation can be done in one single DC simulation. From the single DC analysis sweeping the trimming code, the optimal trimming code can be extracted by using measurement statement like:
    CTRL_calibrate = round(cross(VS("/V_REF") 1.25 1 "rising" nil nil nil))

    1-2) Post-Trim Simulaiton
    Then this optimal trimming code, "CTRL_calibrate", can be passed to the next testbench or the post-trim simulation by using "calcVal" function, as discribed in the RAK.

    Of course, using binary search algorithms can make the trimming search more efficient. However, the search algorithm is NOT the essential difficulty in the oscillator frequency trimming in the ADE Assembler as below.

    2) Oscillator Frequency Trim
    2-1) Trimming Search
    On the other hand, oscillator frequency trim CANNOT be done in one single TRAN simulation. Let's use the example of a frequency trimming at 1.8V/25deg with 3 bit trim code (trim = 0, 1, 2, ...., 7), targeting 1MHz oscillator frequency:

    In this case, one frequency is obtained for one TRAN analysis by using the measurement statement below:
    freq_meas = average(freq(VT("/CLK_OUT") "rising" ?xName "time" ?mode "auto" ?threshold 0.45))
    In other words, one transient simulation with a single trim code returns only one frequency measurement value. By parametrize the trimming code, 8 transient simulations cover all frequency trimming range. Let's suppose as a result of the 8 transient simulations, the following table is obtained:
    Transient Sim. # 1 2 3 4 5 6 7 8
    Trimming Code 0 1 2 3 4 5 6 7
    Measured Frequency (freq_meas) 0.7MHz 0.8MHz 0.9MHz 1MHz 1.1MHz 1.2MHz 1.3MHz 1.4MHz

    Note that one transient simulation with a single trim code returns only one frequency measurement value!

    Here comes the biggest question which is NOT covered in the RAK for this oscillator frequency calibration:
    What kind of measurement statement can be used to extract the optimal trim code automatically for the oscillator frequency among the 8 separated transient simulations?

    → Something equivalent to the "CTRL_calibrate = round(cross(VS("/V_REF") 1.25 1 "rising" nil nil nil))" in case of voltage reference trim cannot be used naively because:

    • the only one trim code is used for one transient simulation.
    • the measurement statement is defined for one transient simulation, not for the 8 transient simulations.


    In case of voltage reference trim, the trim code is swept in one single DC simulation. Therefore, a measurement statement "inside CTRL_calibrate = round(cross(VS("/V_REF") 1.25 1 "rising" nil nil nil))" inside the one DC simulation can return the optimal trim code.

    On the other hand, in case of oscillator frequency trim, one transient simulation returns one frequency value for one trimming code. To obtain the 8 frequency value, we need to run 8 separated transient simulations. From the 8 separated transient simulations, how can we obtain a trim value for a frequency value closest to the target?

    This is what I mean to say by the following statement:

    yoshi777 said:
    Point here is that when sweeping the trim code in the transient simulations, each trim code (trim = 0, 1, 2, ...., 7) is treated as a sort of different "corner" so that I cannot extract the optimal trim code automatically among the multiple transient simulations using measurement function.

     

    Manually, it's possible. But in order to automate the calibration search for each process corner, the measurement statement applicable to the 8 measured values in the 8 separated transient simulation results is necessary, which is unknown to me.  

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • ShawnLogan
    ShawnLogan over 2 years ago in reply to yoshi777

    Dear yoshi777,

    yoshi777 said:
    I believe the difference in the oscillator trimming simulation from the example in the RAK is NOT fully delivered.

    I reviewed the code shown on pages 69 and 70 of the Calibration RAK and find it appears to be both complete and quite compatible with your trimming algorithm. Your output frequency increases monotonically with trim code, so a binary search algorithm is a possible choice.

    Further, prior to the availability of ADE-XL, Assembler, and Explorer, I developed a similar ocean script to perform a VCO frequency calibration using  a binary search algorithm that works in the same fashion.

    You mentioned, again, the need to perform 8 simulations after stating:

    "Of course, using binary search algorithms can make the trimming search more efficient. "

    In your case, the binary search algorithm will run 3 simulations and following each simulation it will check the VCO frequency to determine if it is greater or less than the target frequency. Depending on the result of this comparison, it will retain or remove the increment of the code applied. In your case, with 8 bits, the first simulation runs with a code of 4, the and determines if the frequency is greater or less than 1 MHz. The measured frequency is 1.1 MHz and hence it will run a second simulation with the code set to (4 - 2) = 2. The measured frequency is 0.90 MHz. The frequency is less than the 1.0 MHz target and hence it will retain the code value of 2, and It will run a third (and final) simulation with the code incremented by 1 (1 is the LSB) or (4 - 2) + 1 = 3. SInce 1 is the "least significant bit" of your 3 bit code word, this is the last simulation. The measured frequency is 1 MHz and the code value is decimal 3. The code value is then passed on to the "performance" simulation as the calibrated code.

    If you continue to insist on running all 8 transient simulations (an "exhaustive" search), you can do the same thing with the ocean script and save the 8 different values in 8 variables. With a series of ocean of SKILL if() statements using the 8 values and your target frequency, you can determine the code that produces a frequency closest to your target and pass it to the final "performance" simulation. The RAK, however, does not include the "exhaustive" search algorithm.

    If you have any interest in running your calibration algorithm outside of the Assembler environment, I have attached a compressed file that contains an ocean script for a binary search algorithm using N bits. You can replace the swept code variable with your design variable name for the code and your outputs, your output expression for frequency, and your transient analysis command for those in the script. The script also produces a record of each trial and places it in a comma-separated file. I've include it as well as the output log of the script in the compressed file. To examine the compressed file, type "unzip ocn_scripts_022321.zip" and it will create a directory with the script, runline, sample output log and comma-separated output file.

    In summary, I find the use of binary search algorithm in the pre-run script or as a standalone ocean script is 100% compatible with your trimming algorithm. Further, if you prefer to run an exhaustive search, the pre-run script or ocean script can both be modified to perform an exhaustive search.

    Shawn

    030508_bin_search.zip

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • yoshi777
    yoshi777 over 2 years ago in reply to ShawnLogan

    Hi Shawn,

    ShawnLogan said:
    I reviewed the code shown on pages 69 and 70 of the Calibration RAK and find it appears to be both complete and quite compatible with your trimming algorithm. Your output frequency increases monotonically with trim code, so a binary search algorithm is a possible choice.

    I have just tried the lab-1 method: Calibration Using calcVal() only. I forgot to take a look at the lab-2 and lab-3 with pre-run OCEAN scripts. Let me try to apply them and get back here.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • yoshi777
    yoshi777 over 2 years ago in reply to yoshi777

    Hi Shawn,


    Thanks to your help, my issue has been resolved.

    Below is my binary search Pre-Run script for a oscillator with 9-bit "CTRL" trimming, targeting the 60MHz oscillator frequency.


    Thanks again for your help. 


    Best regards,
    Yoshi

    --


    (let (cornerName pointID pointIDMC i simResult err bestVal
    (leasterr defMathConstants('m)->DBL_MAX) (bitWord 0)
    (noOfBits 9) ; Number of bits (CTRL variable bitWord)
    (target 60e6) ; Vref target 60MHz
    (debug nil)) ; t to enable additional debug printf()


    printf("\n\n")
    printf("pre run: =======================================================\n")
    printf("pre run: Starting pre run\n\n")


    ;Initialize and inherit the test setup from the current point
    ocnxlLoadCurrentEnvironment()

    when( debug
    printf("pre run: resultsDir() = %s\n" resultsDir())
    printf("pre run: modelFile = %L\n" modelFile())
    printf("pre run: desVar() = %L\n" desVar()))

    ;Binary search
    for( n 1 noOfBits
    i = noOfBits - n
    bitWord = bitWord + 2**i
    printf("pre run: i=%d, bitWord + 2**i = %d\n" i bitWord)
    desVar( "CTRL" bitWord )

    ;Run a simulation
    ocnxlRunCalibration()

    simResult = frequency(clip(VT("/CLK60M") 1.8e-05 2e-05))
    printf("pre run:\t simResult = %L\n" simResult)

    err = abs(target - simResult)
    when( err < leasterr
    leasterr = err
    bestVal = bitWord)

    ;increase CTRL increases Rarray increases vref
    when( simResult > target
    bitWord = bitWord - 2**i
    printf("pre run:\t (> target) bitWord - 2**i = %d\n" bitWord))

    ); for

    printf("pre run: Least error = %e, bitWord = %d\n" leasterr bestVal)

    ;Add to the Results table
    ocnxlAddOrUpdateOutput("CTRL_calibrate" bestVal)

    ;Add to the Results table
    ocnxlAddOrUpdateOutput("trim_calibrate" bestVal-256)

    ;Update the main simulation environment with the calibrated result
    ocnxlUpdatePointVariable("CTRL" aelEngNotation(bestVal))

    ocnCloseSession()
    printf("\n\n")
    ;printf("pre run: Completed sample point = %d, corner = %s\n" pointIDMC cornerName)
    )

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • ShawnLogan
    ShawnLogan over 2 years ago in reply to yoshi777

    Dear yoshi777,

    yoshi777 said:

    my issue has been resolved.

    Below is my binary search Pre-Run script for a oscillator with 9-bit "CTRL" trimming, targeting the 60MHz oscillator frequency.

    Excellent - you have made great progress Yoshi!! Thank you for letting us know and providing your solution. Good luck!

    Shawn

    • 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