FVofDiffOpAmp WP
FVofDiffOpAmp WP
Abstract The low-voltage, high-performance IC's employed in modern communication products frequently must employ fully differential signal paths in order to achieve sufficient signal amplitude with a minimum of power. The Differential Amplifier, which is the building block for these signal processing circuits, is the example used in this tutorial which examines simulations and measurements of Typical Characteristics as well as use of advanced environment features in the application of an analog functional verification methodology. Applying standard measurement techniques of basic amplifier characteristics such as Open Loop gain, frequency response, rejection ratios and amplifier circuit stability, specifics of simulation setup and results analysis are included in the example scripts provided. In addition, advanced analyses, such as statistical analysis, and Distortion Analysis are also covered with the view of developing a complete circuit characterization that would be useful in enabling Analog Design Reuse. This tutorial presentation will briefly discuss measurement techniques, the simulation test circuits, simulation, and calculations used to obtain them and will focus on the use simulation script that can reproduce the "circuit data sheet" with a minimum of user interaction, for example when the circuit layout is complete and parasitic elements are extracted. Additionally, automating the script as a part of a design team's Analog Functional Verification Plan will be discussed.
I.
INTRODUCTION
Computer simulation was early used to assist designers to assess circuit performance[1] long before the invention of SPICE[2], now over 30 years old. Stability and frequency response of feedback based systems were predicted with the use of Analog computers. The requirement for Highly linear, High gain elements lead to the commercial use for Operational Amplifiers in Analog computers[3], which then were also applied to modify systems thus studied to improve their performance. Logic simulators, in the form of simple programs to prove out the behavior of complex Boolean expressions, may have been the first to run on digital computers. As specialized applications, however they were almost an afterthought to synthesis programs using HDLs,[4, 22] developed to verify that the system being build behaved as expected. These simulators, however, provided the first opportunity to enhance the simulation into a design verification tool, providing the ability to compare the output of a logic block with its specification, as represented by output vectors and delays. SPICE as the overwhelmingly successful analog circuit simulator running on digital computers, added delay measurement functions allowing gate level timing characterization for use in digital simulation. Completing the picture for the digital design flow, Physical verification tools allowed logic vs. layout checking, and interconnect delay extraction allowing Logic Verification run prior to tapeout to reliably predict silicon functionality, even addressing some signal integrity issues. Significant advancements in Analog simulation have provided us with accurate device models easily extracted from silicon test devices, superb schematic capture and design analysis environments for interactive simulation, physical verification tools that can accurately extract parasitic devices, including substrate resistances and interconnect resistance, inductance, and capacitance, based on 3-dimensional layout information and even mixed-signal and RF simulation capabilities. In spite of this, analog functional verification remained as impossible as analog synthesis until the development of analog behavioral modeling[21] capabilities that worked with the standard analog and mixed signal simulators. This allows the development of signal transformations used to allow signal and circuit characteristics to be checked, and to generate the analog stimuli required to check circuit behavior. Even this wasnt sufficient with out an automated post-simulation analysis capability, currently not supported in the analog HDLs Within the Cadence Custom IC toolset, this requirement is in place with the OCEAN (Open Command Environment for Analysis) scripting capability for the Analog Design Environment (formerly Analog Artist) along with the Spectre Circuit Simulator with its Verilog-A capability + RF analyses + Mixed-Signal Capability. Today utilizing the Spectre simulator with its Verilog-A and Mixed Signal interface capability along with the OCEAN Language, one can take any set of simulations and post simulation calculations and easily turn this into a script to be run automatically, generating Pass/Fail results, Results tables and Plots shown results useful for designer reference or in design reviews.
II.
EXAMPLE CIRCUIT
While the choice of the specific circuit used to demonstrate a verification methodology is not crucial, the selection of the operational amplifier provides one with a significant number of specifications defined extensively in the literature[5,6,7,8], and a circuit that most readers will have studied to some extent at some time in their career. The fully-differential variant chosen is applicable to many designs in progress and in the literature today[9, 10, 11, 12, 13]. The fully-differential op-amp provides a wide signal range and good common-mode, power supply and substrate rejection due to its symmetric construction. This makes it popular wherever fully differential signal paths must be used, for example where the supply voltage is limited due to the process chosen. Circuits used in Mixed-Signal ICs are often subject to this restriction. Another application to use these extensively is communications[11] where switched capacitor type of filters[10] and converters are frequently used, generating significant substrate transients that must be adequately rejected. The circuit topology chosen for this case is a fully differential current mirror opamp with n-channel input devices and a current gain of 6, based on figure 6-14 in Johns & Martin [6], built on the TSMC 0.18u CMOS Technology using the Logic PDK (Process Design Kit) available to TSMC customers on their website. The Schematic is shown in Figure 1. While both Bandwidth and DC gain are important, the DC gain was the primary objective of this design, leading to the selection of N-channel input devices. Again, while some optimization was performed, the primary function of this circuit is to support the development of a verification script.
Figure 1 Fully Differential Current Mirror Opamp with CMFB The following table lists the target specifications for the circuit. The list was collated from a number of published articles, and text books, as well as published Manufacturers Data Sheets. Symbol AOL GBW UGFreq Bwol AMARGIN MARGIN VOS VOSDrift Zin Zout Description DC Gain Gain Bandwidth Product Unity Gain Frequency Open Loop Gain 3dB Bandwidth Gain Margin Phase Margin Input Offset Voltage Offset Voltage Drift Input Impedance Output Impedance Target Specification 60 dB min 50M min 1M Hz min 100k Hz min -20 dB 30 deg 5mv 100n V/deg C 10K min @ 1M Hz 10K max @ 1M Hz
SlewRate FMAX OvrShoot Tsettle VCM min VCM max ISC VOL VOH IDD VDD PDISS ENV fBV ENI fBI CMRR PSRR THD SFDR IP3
Slew Rate Maximum Frequency (Large Signal) Overshoot Settling Time Common Mode Voltage Common Mode Voltage Short Circuit Current Output Compliance Low Output Compliance High Supply Current Supply Voltage Power Dissipation Equivalent Noise Voltage Bandwidth of Noise Voltage Equivalent Noise Current Bandwidth of Noise Current Common Mode Rejection Ratio Power Supply Rejection Ratio Total Harmonic Distortion Spurious Free Dynamic Range 3rd Order Intermodulation Product Power
20M V/sec min N/A 10% max 125n sec 0.75 V 1.5 V N/A 100m V max Vdd 100m V max 10 mA max 1.6v 2.2v 20 mW 20 nV/Hz Max@ 1kHz 1k Hz max N/A N/A 120 dB min 100 dB min 1% max at 1Mhz 80 dB at 1Mhz 20 dB
III.
VERIFICATION SCRIPT
While our objective is an automatic functional verification, this cannot currently be developed automatically. In the development we will start with the Simulation Plan to match the specifications to the simulations. Next we will review the associated circuitry required to drive our Device Under Test (DUT). We will then visit the subject of capturing the interactive simulations in OCEAN script format. We will finish by demonstrating the use of the script and examine the results generated by the script.
A. Simulation Plan
All of the specifications will be measured at the typical process, voltage and temperature. In addition a set of plots will be created for reference by circuit designers, consisting of Frequency Response, Rejection Ratios, Step Response and Vos drift vs. Temp. Typical DC sweep VOSDrift, IDD Typical AC sweep AOL, GBW, UGF, f3dB, AMARGIN, MARGIN, Zin Typical XF sweep CMRR, PSRR Typical Transient %OS, SR, Tsettle Designers Data sheet - Typical PVT Plot OL Freq Response, Measure AOL AMARGIN, & MARGIN Plot CMRR & PSRR and measure DC values Plot Step Response and measure SR and %OS Plot Vos vs. Temp for a maximum input transistor Size Mismatch Corner Simulations repeat of above tests at 0 C, 1.6 v Slow Process, 100 C, 2.2v Fast Models and 27 C, 1.8v for Typical, Slow/Fast and Fast/Slow models. Plot Aol, and bar chart of Ad, CMRR, PSRR and Iss AC Sweep Zout AC Sweep CMFB Aol, Gm PhaseM, f3dB, UGF Transient Sweep Overdriven Square Wave Voh Vol Transient Sweep 1M Hz Sine THD, Plot Output Spectrum Noise ENV, fBV Parametric AC sweep Vcm Min and Vcm Max (Common Mode Range) Monte Carlo VOS, yield on Typical Specs
Figure 3 Testbench for IP3 and SFDR measurements Using the behavioral model written in Verilog-A[21] (See Appendix B Verilog-A Models ) this element has been made to block AC, and to have unity gain for transient simulations.
Since the DC bias is set with an amplification of gain thru the feedback amplifier, the error at the output of the DUT is = Vos/gain. With gain = 100 this error signal = 1% of Vos. In the AC simulation, the output of the feedback amplifier is effectively a DC source, thus opening the loop around the amplifier. Allowing direct measurement of the Open Loop characteristics at the DUT outputs. The XF analysis is perfectly suited for measurement of the Rejection Ratios[18]. By setting the DUT input nodes (Where the Voltage represents the Offset) as the XF output nodes the gain from each source represents the change in the input voltage due to a change in that supply, or wVin/wVsupply. The Common Mode Rejection Ratio is classically defined as Vd/Vc or wVout/wVin/wVout/wVcm which reduces to wVcm/wVin, the inverse of the XF result from the Common Mode Source. Similar results apply to the other Rejection Ratios. The Common Mode Feedback circuit measurements can be made by setting the variable for the AC voltage on the source at the amplifier output to one, leaving the others set to zero, and using an equation to calculate the It is generally a good idea to keep circuit test benches with the circuit itself, distinguishing it with a specific name extension. I like to use <circuitname>_TB. Numeric extensions can be added where more than one test bench is required.
C. Script Development
The script development for a circuit generally would be completed along with the detailed schematic design, with a successful test along with interactive simulations proving both the design and the Verification program. Once it has been completed, the test program can be re-used after layout and Physical verification, and again after any ECOs. Scripts for variants of the basic design can be re-used most easily by copying the test bench and replacing the element under test with the new circuit. Then most of the script can be re-used with changes only to the top cell, results paths and specifications. The critical features of a useful verification program are: Completeness: It must test All of the circuit specifications Identification/Reporting of failures: To aid troubleshooting Reporting of results: In the form of a summary at the end, as well as in results file Must be capable of running without user interaction. Must be easily created or configured The majority of the simulation script used can be automatically generated based on the interactive simulation setup. Using the simulation testbench shown above in Figure 2, the various simulations are setup interactively using the Analog Design Environment (ADE). The first Setup is the one for the 4 typical sweeps that generate the designers data sheet. Once the simulations and the measurements and plot commands are setup, the state of the ADE window is saved for later use. In addition the state is saved in an OCEAN script like that shown in Appendix C Sample Generated Script that can be used to repeat the simulation non-interactively. This is repeated for all of the other simulation setups in the simulation plan. The resulting ocean scripts are the starting point for the verification script. While the basic simulation and measurement functions are part of the OCEAN language, some additional utility functions shown in Appendix D SKILL AFV Utility Functions were developed to simplify the process of checking measurements, recording Pass/Fail results, and configuring the plots generated. These functions can be loaded into the users environment during initialization, by the .cdsinit file for use during script development, or by the .oceanrc file for use in batch mode. The resulting verification script shown in Appendix E OCEAN script for CmirDiffAmp4 can be summarized in the Psuedo-Code description shown in Figure 4. While there is possible improvement in the ease of creation area, the script does meet all of the requirements laid out at the beginning of this section.
Initialize the Specification Limits database For Typical Corner with input transistor Size Mismatch generate plots OL Freq Response, Measure AOL AMARGIN, & MARGIN CMRR & PSRR vs Frequency Step Response Vos vs Temp For each Corner(Typ, Fast/hot, Slow/cold, Slow/fast and Fast/slow) Run Dcsweep, AC, XF and transient simulations For each Measurement( VOSDrift, IDD,AOL, GBW, UGF, f3dB, AMARGIN, MARGIN, Zin,CMRR, PSRR, %OS, SR, Tsettle ) Calculate result and compare to specification For Typical corner run AC sweep and measure Zout compared to specification For Typical corner run AC sweep and measure CMFB parameters compared to specification: Aol, Gm PhaseM, f3dB, UGF Run Transient Simulations with Overdriven Square Wave test Voh Vol Run Transient Sweep with 1M Hz Sine measure and test THD, Plot Output Spectrum Run Noise test ENV, fBV Run Parametric AC sweep measure and test Vcm Min and Vcm Max (Common Mode Range) Run Monte Carlo est VOS, yield on Typical Specs ( VOSDrift, IDD,AOL, GBW, UGF, f3dB, AMARGIN, MARGIN, Zin,CMRR, PSRR, %OS, SR, Tsettle ) Run PSS + PAC measure IP3, SFDR. Generate report and failure summary(if not passing) Figure 4 Psuedo-code of Amplifier Verification
Likewise the script can be used to verify that a behavioral model generated for the cell is satisfactory, or perhaps to optimize the model to match the extracted layout results. For larger designs, using standard building blocks verified with scripts similar to those presented here, one could run faster simulations using the verified analog behavioral models for increased confidence of behavioral results, reducing the need to simulate the full design at the transistor level, and allowing simulations to be done where simulations at the transistor level would not be practical. At the least, one can verify each specification of a circuit at an appropriate level. Knowing that the amplifier has been fully characterized, one need not re-verify the stability or the output compliance, merely that the gain is correct or, for communications applications, that the eye-opening is sufficient.
E. Output Results
In addition to the log file, and the results summary, the script generates 4 plots with typical conditions and a summary plot from the corners simulation. A summary table of measured results from the simulations is also generated. The outputs generated are shown in Appendix A Script Generated Results. At the time paper submission the script was run on the schematic view of the amplifier completing in 14 min showing 50 failures out of 127 measurements made.
IV.
FUTURE DEVELOPMENTS
Cadence Design Systems will be enhancing the measurement capabilities of the Spectre simulator in upcoming releases. This will provide for a tighter integration of the measurements with the simulator, even allowing simulations to terminate when all required measurements have been obtained. At this point the techniques used will need to be extended to take advantage of these features. Measurement of some simulation results is also possible within the Verilog-A and Verilog-AMS languages. These are primarily useful during transient simulations in a manner similar to that used in Verilog for functional verification of digital circuits. However the availability of alternate quantities allows results to be treated as signals for other stimulus and measurement modules, or to be saved in the results database. Values of Verilog-A module variables can be saved in the results database, and read using OCEAN commands. Verilog-A modules can write measurement results to a file, which can be read and parsed by SKILLTM functions in the OCEAN script to log results in the summary. Other potential improvements could be the inclusion of limits and limits checking in the Corners tool and the ADE output pane, as well as Cadence defined functions similar to those defined in Appendix D SKILL AFV Utility Functions. The development of wrapper scripts to compare results to design, re-netlist and re-simulate is a task that also remains for future work, but one for which few significant challenges would be envisioned, given the similar methodology currently in use on all-digital designs.
V.
CONCLUSIONS
Due to the more complicated nature of analog specifications, development of scripts for Analog Functional Verification is more difficult than for Digital Functional Verification, but not impossible, and is not really that difficult using the Analog Design Environment, as shown in the example script. The utility functions presented simplify this further. Verification of the extracted layout of the design was accomplished by simply rerunning the script. An automated methodology for verifying analog cells by simulation has been presented. Design teams using such a methodology at various levels of hierarchy will be able to tape-out large mixed-signal designs with increased confidence of silicon functionality and performance.
ACKNOWLEDGEMENTS
The Author would like to thank Hank Jones for the assistance with the utility functions. Without his help, the functional wish list would still be just that. The Author would like to thank the following companies for supporting various portions of this work, for asking the how do I questions that lead to this work and for the opportunity to test out some of these ideas in practice: National Semiconductor, Xicor, Burr-Brown (now part of Texas Instruments), Motorola and Vitesse.
REFERENCES
[1] J. A. G. Jess, Designing Electronic Engines with Electronic Engines: 40 Years of Bootstrapping of a Technology Upon Itself, IEEE Trans.Computer-Aided Design, vol. CAD-19, pp 1404-1427, Dec. 2000. [2] L. W. Nagel, SPICE2: A Computer Program to Simulate Semiconductor Circuits, University of California, Berkeley, Memo. no. ERL-M250, May 1975. [3] R. A. Pease, The Story of the P2 The First Successful Solid-State Operational Amplifier with Picoampere Input Currents in Analog Circuit Design: Art, Science and Personalities, J. Williams, Ed. Boston, MA: Butterworth-Heinemann, 1991, ch. 9, pp 67-78. [4] Y.Chu, D. L. Dietmeyer, J. R. Duley, F. J. Hill. M. R. Barbacci, C. W. Rose, G. Order, B. Johnson, and M. Roberts, Three Decades of HDLs Part I: CDL through TI-HDL, IEEE Design Test Comput., vol. 9, pp 6981, June 1992. [5] J.E. Solomon. "The monolithic op amp: a tutorial study," IEEE J. Solid-State Circuits, vol. SC-9.6, pp 314332, Dec. 1974 . [6] David Johns and Ken Martin, Analog Integrated Circuit Design, New York: Wiley & Sons, 1997. [7] Jacob Millman, MicroElectronics: Digital and Analog Circuits and Systems, New York: McGraw-Hill, 1979 [8] Paul Gray and Robert Meyer, Analysis and Design of Analog Integrated Circuits: 2nd Ed, New York: Wiley & Sons, 1984 [9] G.Ferri and W. Sansen A Rail-toRail Constant-gm Low-Voltage CMOS Operational Transconductance Amplifier, IEEE J. Solid-State Circuits, vol 32, pp 1563-1567, Oct. 1997. [10] K. Bult& G.J.G.M. Geelen, A Fast-Settling CMOS Op Amp for SC Circuits with 90-dB DC gain, IEEE J. Solid-State Circuits, Vol. 25, No. 6, pp 1379-1384, Dec. 1990. [11] T.C. Choi, R.T. Kaneshiro, R.W. Brodersen, P.R. Gray W.B. Jett & M. Wilcox, High-Frequency CMOS Switched Capacitor Filters for Communications Application IEEE J. Solid-State Circuits, vol. 18, pp 652663, Dec. 1983. [12] M. Banu, J.M. Khoury & Y. Tsividis Fully Differential Operational Amplifiers with Accurate Output Balancing. IEEE J. Solid-State Circuits, Vol. 23, No. 6, pp. 1410-1414, Dec. 1988 [13] K.R. Laker & W.M.C. Sansen, Design of Analog Integrated Circuits and Systems New York: McGraw-Hill, 1994 [14] C.F. Wojslaw and E.A. Moustakas, Operational Amplifiers, New York: Wiley & Sons, 1986 [15] Don Lewis Testing Operational Amplifiers Electronics Test (Benwill Publishing) January 1979 [16] Don Lewis Compensation of Linear IC Test Loops Electronics Test (Benwill Publishing) May 1979 [17] M. Yamatke, A Simplified Test-Set for Op Amp Characterization National Semiconductor Application Note 24, April 1986 [18] Ken Kundert, The Designers Guide to Spice & Spectre, Boston: Kluwer, 1995 [19] P.E. Allen and D.R. Holberg, CMOS Analog Circuit Design, New York: Oxford Univ. Press, 1987 [20] J. Vandenbussche, G. Van der Plas, W. Daemes, A. Van den Bosch, G. Gielen, M. Steyart and W. Sansen, Systematic Design of High-Accuracy Current-Steering D/A Converter Macrocells for Integrated VLSI Systems, IEEE Trans Ciruits Syst II, vol. 48, pp 300-309, Mar. 2001. [21] Dan Fitzpatrick, Ira Miller, Analog Behavioral Modeling with the Verilog-A Language Boston: Kluwer, 1998 [22] Samir Palnitkar, Verilog HDL Mountain View: SunSoft, 1996
File 1: CmirDiffAmp4.spec Aol GainMargin PhaseMargin GBW UGFreq BWol CMRR CmRefRR PSRRdd PSRRss SlewRate Tsettle OvrShoot ComplncOut Zout Zin VcommonLow VcommonHigh CMFBPhMar CMFBAol ENV Fbv THD Idd Vos VosDrift Pdiss SFDR IP3 min max min min min min min min min min min max max max max min max max min min max max max max range max max min min 60 -20 30 25M 1M 25K 120 120 100 100 20M 125n 10 0.1 10K 10K 0.5 0.7 30 20 20n 1K 1 10m -5m 5m 100n 20m 80 20 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; dB dB deg dB -Hz Hz Hz dB dB dB dB V/s S % V Ohms Ohms @ 1MHz Volts Volts (from supply) deg dB V/sqrt(Hz) @ Fbv Hz % at typical amps V V/degC W dB dB
File 2 CmirDiffAmp4.fail ANALOG TEST RESULTS FROM RUN CmirDiffAmp4 TEST PASS FAIL RUNS Idd 6 0 6 VosDrift 1 0 1 THD 0 1 1 GainMargin 6 0 6 CMRR 4 2 6 Zout 2 0 2 PSRRss 6 0 6 Zin 0 1 1 SlewRate 0 12 12 GBW 0 6 6 ENV 1 0 1 Vos 6 0 6 PhaseMargin 0 6 6 BWol 0 6 6 Fbv 1 0 1
PSRRdd ComplncOut IP3 SFDR CmRefRR VcommonLow VcommonHigh Aol UGFreq OvrShoot CMFBPhMar Pdiss CMFBAol Tsettle ---------TOTALS
6 0 0 0 4 1 1 6 6 10 2 6 2 0 -------77
0 0 0 0 2 0 0 0 0 2 0 0 0 12 -------50
6 0 0 0 6 1 1 6 6 12 2 6 2 12 -------127
value(dB20((VFgainBwProd((VF gainMargin((VFphaseMargin((Vcross(dB20((VFbandwidth((VF( 62.3743 62.4565 62.6292 62.4745 62.5099 23.5706M 24.0718M 21.8673M 18.4523M 22.8865M -26.9213 -27.5728 -27.4202 -27.3845 -27.9983 16.8194 17.2979 17.6961 18.4147 17.674 7.04916M 7.38016M 6.83722M 6.07812M 7.1341M 17.8894K 18.098K 16.117K 13.8458K 17.1027K
Idd (A)
Pdiss (W)
CMRR(dB)
CmRefRR(dB) PSRRdd(dB)
PSRRss(dB)
IDC("/VDD/MINU IDC("/VDD/MINU value(dB20((1 value(dB20((1 value(dB20((1 value(dB20((1 7.46168m 7.23494m 6.67777m 5.86347m 7.06937m 14.9234m 13.0229m 12.02m 9.38155m 12.7249m 136.997 137.744 116.536 113.478 123.139 137.114 137.77 116.612 113.854 123.224 116.466 115.262 116.333 115.108 115.875 115.685 114.633 110.413 108.234 112.748
Tsettle1N(s)
SlRtp(V/s)
SlRtn(V/s)
overshoot((VT( overshoot((VT( settlingTime(( settlingTime(( abs(slewRate(( abs(slewRate(( 578.519m 421.13m 610.425m 370.662m 555.055m 579.667m 422.409m 611.165m 372.252m 556.263m 392.702n 393.472n 336.877n 380.535n 363.963n 392.711n 393.52n 336.958n 381.647n 364.018n 9.36282M 8.70094M 10.9525M 8.56432M 9.96758M 9.36244M 8.69862M 10.9469M 8.52218M 9.96487M
File 4 OLFreqResp.gif
File 5 RejRatios.gif
File 6 StepResponse.ps
File 7 VosDrift.ps
File 8 Corners.gif
File 9 CMRange.ps
File 10 CMFB.ps
File 11 Noise.ps
File 12 Zout.ps
File 13 SineTrans.ps
File 14 THDplot.ps
include "constants.h" include "discipline.h" module acOpenDiff( inp, inn, inref, outp, outn, vos); input inp, inn, inref; output outp, outn, vos; electrical inp, inn, inref, outp, outn, vos; parameter real gain = 1; // sets dc gain for closed loop tests. real vin, vbias; analog begin @(initial_step("static")) begin vin = gain*V(inp,inn); vbias = (V(inp,inref)+V(inn,inref))/2; end if (analysis("ac","noise")) begin V(vos) <+ vin; V(outp,inref) <+ vbias; V(outn,inref) <+ vbias; end else if (analysis("static","xf")) begin V(vos) <+ gain*V(inp,inn); // the difference goes here V(outp,inref) <+ (V(inp,inref)+V(inn,inref))/2; // average V(outn,inref) <+ (V(inp,inref)+V(inn,inref))/2; // average end else begin // transient and large signal analyses V(outp,inref) <+ V(inp,inref); V(outn,inref) <+ V(inn,inref); V(vos) <+ 0; end end endmodule
option( reltol "1e-5" ) temp( 27 ) run() Stage1Gain = (OP("/I0/NM0" "gm") / (OP("/I0/NM0" "gds") + OP("/I0/PM0" "gds"))) plot( Stage1Gain ?expr ( "Stage1Gain" ) ) Acmfbn = dB20((VF("/outn") / (VF("/outn") - VF("/cmout")))) plot( Acmfbn ?expr ( "Acmfbn" ) ) PhMarginNcmfbcl = phaseMargin(VF("/outn")) plot( PhMarginNcmfbcl ?expr ( "PhMarginNcmfbcl" ) ) AclPcmfb = dB20(VF("/outp")) plot( AclPcmfb ?expr ( "AclPcmfb" ) ) PhclNcmfb = phase(VF("/outn")) plot( PhclNcmfb ?expr ( "PhclNcmfb" ) ) PhclPcmfb = phase(VF("/outp")) plot( PhclPcmfb ?expr ( "PhclPcmfb" ) ) AclNcmfb = dB20(VF("/outn")) plot( AclNcmfb ?expr ( "AclNcmfb" ) ) PhMarginPcmfbcl = phaseMargin(VF("/outp")) plot( PhMarginPcmfbcl ?expr ( "PhMarginPcmfbcl" ) ) Acmfbp = dB20((VF("/outp") / (VF("/outp") - VF("/cmout")))) plot( Acmfbp ?expr ( "Acmfbp" ) ) BWcmfbN = bandwidth(VF("/outn") 0.5 "low") plot( BWcmfbN ?expr ( "BWcmfbN" ) ) BWcmfbP = bandwidth(VF("/outp") 0.5 "low") plot( BWcmfbP ?expr ( "BWcmfbP" ) ) PhiCmfbN = phase((VF("/outn") / (VF("/outn") - VF("/cmout")))) plot( PhiCmfbN ?expr ( "PhiCmfbN" ) ) PhiCmfbP = phase((VF("/outp") / (VF("/outp") - VF("/cmout")))) plot( PhiCmfbP ?expr ( "PhiCmfbP" ) )
* the following database allows users to specify analog limits * for various tests. This table of values is keyed on the test * name given by user. * * The values will be checked against one of five tests: * min <= value * max >= value * range ; min <= value <= max * */ procedure(AFVtestInit(file "t") let((ps line key (fp infile(file)) (count 0)) AnalogTests = unbound AnalogTests = makeTable(AnalogTests nil) if(fp then while((line=lineread(fp)) println(line) count++ ;;AnalogTests is equivilent to a record which is indexed on a key ;; that contains a value and two other fields, pass and fail ;; value@keyslot pass fail ps = line when(length(ps) < 3 printf("Field formats are:\n testkey m value\n testkey x value\n testkey r lowerLimit upperLimit\n") printf("Where testkey is the name of the test.\n character m means minimum value\n character x means maximum value\n character r means range of 2 values\n") error("Test specification requires THREE or more fields; line %d\n contains %s\n" count line) ) key = get_pname(car(ps)) AnalogTests[key] = tconc(AnalogTests[key] get_pname(cadr(ps))) AnalogTests[key] = lconc(AnalogTests[key] cddr(ps)) AnalogTests[key] = lconc(AnalogTests[key] list(0)) AnalogTests[key] = lconc(AnalogTests[key] list(0)) AnalogTests[key] = lconc(AnalogTests[key] list(0)) ;;this gets the tconc formatted list and stuffs it in the table AnalogTests[key] = car(AnalogTests[key]) ) else error("Cannot OPEN file %s \n" file) ) ) )
;;AnalogTests is equivilent to a record which is indexed on a key ;; that contains a value initially as in this example ;;once initialized we call the following routine to populate the pass fail count
;;AFVtestInit("./myFile") procedure(AFVtest(test value) let(((testValue AnalogTests[test])) case(car(testValue) ;;minimum value test ("min" ;;if the value is too small we count an error if(aelNumber(value) < cadr(testValue) then AnalogTests[test] = list(car(testValue) cadr(testValue) caddr(testValue) cadddr(testValue)+1 nth(4 testValue)+1) cadr(testValue) else AnalogTests[test] = list(car(testValue) cadr(testValue) caddr(testValue)+1 cadddr(testValue) nth(4 testValue)+1) nil ) );"min" ;;maximum value test ("max" ;;if the value is too large we count an error if(aelNumber(value) > cadr(testValue) then AnalogTests[test] = list(car(testValue) cadr(testValue) caddr(testValue) cadddr(testValue)+1 nth(4 testValue)+1) cadr(testValue) else AnalogTests[test] = list(car(testValue) cadr(testValue) caddr(testValue)+1 cadddr(testValue) nth(4 testValue)+1) nil ) );"max" ;;value range test ("range" let(((lowerLimit cadr(testValue)) (upperLimit caddr(testValue))) ;;if the value is too if(aelNumber(value) < aelNumber(value) > AnalogTests[test] = cadddr(testValue) small or large we count an error lowerLimit || upperLimit then list(car(testValue) lowerLimit upperLimit
nth(4 testValue)+1 nth(5 testValue)+1) list(lowerLimit upperLimit) else AnalogTests[test] = list(car(testValue) lowerLimit upperLimit cadddr(testValue)+1 nth(4 testValue) nth(5 testValue)+1) nil ) );let );"range" ("pcnt"
let(((lowerLimit cadr(testValue)) (upperLimit caddr(testValue)/100.0) temp) when(zerop(lowerLimit) error("Initial value for \"pcnt\" should be non-zero: %n\n" lowerLimit) ) ;;get the absolute limit for this test temp = lowerLimit * upperLimit ;; add temp to get the upperlimit upperLimit = lowerLimit + temp ;; subtract from lowerlimit to get the absolute lower limit lowerLimit = lowerLimit - temp ;;if the value is too small or large we count an error if(aelNumber(value) < lowerLimit || aelNumber(value) > upperLimit then AnalogTests[test] = list(car(testValue) cadr(testValue) caddr(testValue) cadddr(testValue) nth(4 testValue)+1 nth(5 testValue)+1) list(lowerLimit upperLimit) else AnalogTests[test] = list(car(testValue) cadr(testValue) caddr(testValue) cadddr(testValue)+1 nth(4 testValue) nth(5 testValue)+1) nil ) );let );"pcnt" ("porm" let(((lowerLimit cadr(testValue)) (upperLimit caddr(testValue)) temp) ;;get the absolute limit for this test ;; add temp to get the upperlimit temp = lowerLimit + upperLimit ;; subtract from lowerlimit to get the absolute lower limit lowerLimit = lowerLimit - upperLimit upperLimit = temp ;;if the value is too small or large we count an error if(aelNumber(value) < lowerLimit || aelNumber(value) > upperLimit then AnalogTests[test] = list(car(testValue) cadr(testValue) caddr(testValue) cadddr(testValue) nth(4 testValue)+1 nth(5 testValue)+1) list(lowerLimit upperLimit) else AnalogTests[test] = list(car(testValue) cadr(testValue) caddr(testValue) cadddr(testValue)+1 nth(4 testValue) nth(5 testValue)+1) nil ) );let );"porm"
(t error("Test not defined in input file: %L\n" test) ) );case ) ) procedure(AFVlogReport(runName "t") "Prints AnaFuncVerif Test Summary to CIW, Returns t if Tests OK" let((len AnaTestRuns AnaTestPasses AnaTestFails) when(runName printf(" ANALOG TEST RESULTS FROM RUN %s\n" runName) printf("%-25s %-10s %-10s %-10s\n" "TEST" "PASS" "FAIL" "RUNS") AnaTestRuns = 0 AnaTestPasses = 0 AnaTestFails = 0 foreach(key AnalogTests len = length(AnalogTests[key]) ;unless(zerop(nth(len-1 AnalogTests[key])) printf("%-25s %-10n %-10n %-10n\n" key nth(len-3 AnalogTests[key]) nth(len-2 AnalogTests[key]) nth(len-1 AnalogTests[key])) AnaTestRuns = AnaTestRuns + nth(len-1 AnalogTests[key]) AnaTestPasses = AnaTestPasses + nth(len-3 AnalogTests[key]) AnaTestFails = AnaTestFails + nth(len-2 AnalogTests[key]) ;) );foreach AnalogTests printf("----------------- -------- --------\n") printf("%-25s %-10n %-10n %-10n\n" "TOTALS" AnaTestPasses AnaTestFails AnaTestRuns ) if((AnaTestFails > 0) then printf("%-10n Failures %s Tests did Not pass\n" AnaTestFails runName) else printf("%-25s All Tests PASS\n" runName) ) );when (AnaTestFails == 0) ; Return value nil => Failures ) ) /* this procedure is an enhanced version of AFVlogReport * that also creates a file - in <ResultsDir>/<runName>.[pass|fail] * using the extenstion pass only if all tests passed. * Jonathan David [email protected] */ procedure(AFVreport(@key runName (ResultsDir "./RESULTS") "tt") "Prints AnaFuncVerif Test Summary to CIW and file, Returns t if Tests OK" let((len AnaTestRuns AnaTestPasses AnaTestFails AnaRsltsFile RsltsPort) when(runName printf(" ANALOG TEST RESULTS FROM RUN %s\n" runName) printf("%-25s %-10s %-10s %-10s\n" "TEST" "PASS" "FAIL" "RUNS") AnaTestRuns = 0 AnaTestPasses = 0 AnaTestFails = 0 foreach(key AnalogTests len = length(AnalogTests[key]) ;unless(zerop(nth(len-1 AnalogTests[key]))
printf("%-25s %-10n %-10n %-10n\n" key nth(len-3 AnalogTests[key]) nth(len-2 AnalogTests[key]) nth(len-1 AnalogTests[key])) AnaTestRuns = AnaTestRuns + nth(len-1 AnalogTests[key]) AnaTestPasses = AnaTestPasses + nth(len-3 AnalogTests[key]) AnaTestFails = AnaTestFails + nth(len-2 AnalogTests[key]) ;) );foreach AnalogTests printf("----------------- -------- --------\n") printf("%-25s %-10n %-10n %-10n\n" "TOTALS" AnaTestPasses AnaTestFails AnaTestRuns ) if((AnaTestFails > 0) then printf("%-10n Failures %s Tests did Not pass\n" AnaTestFails runName) AnaRsltsFile = strcat( ResultsDir "/" runName ".fail" ) else printf("%-25s All Tests PASS\n" runName) AnaRsltsFile = strcat( ResultsDir "/" runName ".pass" ) ) RsltsPort = outfile( AnaRsltsFile ); when(RsltsPort fprintf( RsltsPort " ANALOG TEST RESULTS FROM RUN %s\n" runName) fprintf( RsltsPort "%-25s %-10s %-10s %-10s\n" "TEST" "PASS" "FAIL" "RUNS") foreach(key AnalogTests len = length(AnalogTests[key]) ;unless(zerop(nth(len-1 AnalogTests[key])) fprintf(RsltsPort "%-25s %-10n %-10n %-10n\n" key nth(len-3 AnalogTests[key]) nth(len-2 AnalogTests[key]) nth(len-1 AnalogTests[key]) ) );foreach AnalogTests fprintf( RsltsPort "----------------- -------- --------\n") fprintf( RsltsPort "%-25s %-10n %-10n %-10n\n" "TOTALS" AnaTestPasses AnaTestFails AnaTestRuns ) close( RsltsPort ) );when RsltsPort );when runName (AnaTestFails == 0) ; Return value nil => Failures ) ) procedure(AFVtestVerilog(fileName "t") let((line (fp infile(fileName))) if(fp then while((line=lineread(fp)) AFVtest(get_pname(car(line)) cadr(line)) ) printf("Done processing file %s\n" fileName) else error("Cannot OPEN file %s \n" fileName) ) ) ) procedure(AFVtestDump() foreach(key AnalogTests
desVar( "ACout" 0 ) desVar( "VswngP" 1 ) desVar( "VswngN" "-VswngP" ) ;; designvars for the design desVar( "wpmirr" 1m ) desVar( "lmir" 2u ) desVar( "K" 6 ) desVar( "wnout" 100u ) desVar( "wpcmir" 500u ) desVar( "wndiff" 3m ) desVar( "lnout" 10u ) desVar( "lndiff" 1.5u ) desVar( "lpcmir" 5u ) desVar( "wp" .5m ) desVar( "wmir" 12u ) desVar( "lpmirr" 10u ) desVar( "Iref" 300u ) desVar( "lp" 1u ) desVar( "wndiffa" "wndiff+30n" ) desVar( "lndiffa" "lndiff+1n" ) option( reltol "1e-5" ) temp( 27 ) ;********************************Run the Typical Simulation run() ;******************* ; Process the Results ;********** insert Plot Win setup commands here ; OL Freq Response First ;************************ AFVsetPlot( ?plotterName "ps2" ?outputFile "RESULTS/CmirDiffAmp4/OLFreqResp.ps" ?title strcat("Typical Amplifier Characteristics CmirDiffAmp4" getCurrentTime()) ?subTitle "Open Loop Freq Response" ) ;*************************************** ; Reorder Outputs to get just the AC results ;***************** ; displayMode( "composite") Aolf = dB20((VF("/outp") - VF("/outn"))) plot( Aolf ?expr ( "Aol" ) ) PHol = phase(((VF("/outp") - VF("/outn")) / (VF("/inp") - VF("/inn")))) plot( PHol ?expr ( "PHol" ) ) Aol = value(dB20((VF("/outp") - VF("/outn"))) 0) Zin = (VF("/inp") / IF("/E2/PLUS")) Zin1M = mag(value(Zin 1M)) ; if((TestVal = AFVtest("Aol" Aol)) then printf("SPECFAIL: Typical Aol = %2.2f Min Aol = %n dB\n" Aol TestVal) ) GBW = gainBwProd((VF("/outp") - VF("/outn"))) Gmargin = gainMargin((VF("/outp") - VF("/outn"))) if((TestVal = AFVtest("GainMargin" Gmargin)) then
printf("SPECFAIL: Typical Gain Margin = %2.2f Max = %2.2f dB\n" Gmargin TestVal) ) if((TestVal = AFVtest("GBW" GBW)) then printf(strcat("SPECFAIL: Gain BW (typ) = " aelSuffixWithUnits(GBW "dB-Hz" ) " Minimum specified = " aelSuffixWithUnits(TestVal "dB-Hz" ) "\n" ) ) ) ; if((TestVal = AFVtest("Zin" Zin1M)) then printf(strcat("SPECFAIL: Zin @1MHz (typ) = " aelSuffixWithUnits(Zin1M "Ohms" ) " Minimum specified = " aelSuffixWithUnits(TestVal "Ohms" ) "\n" ) ) ) Pmargin = phaseMargin((VF("/outp") - VF("/outn"))) if((TestVal = AFVtest("PhaseMargin" Pmargin)) then printf(strcat("SPECFAIL: Phase Margin (typ) = " aelSuffixWithUnits(Pmargin "deg" ) " Minimum specified = " aelSuffixWithUnits(TestVal "deg" ) "\n" ) ) ) UGF = cross(dB20((VF("/outp") - VF("/outn"))) 0 1 "either") if((TestVal = AFVtest("UGFreq" UGF)) then printf(strcat("SPECFAIL: UGF (typ) = " aelSuffixWithUnits(UGF "Hz" 4 ) " Minimum specified = " aelSuffixWithUnits(TestVal "Hz" 4 ) "\n" ) ) ) DomPoleFreq = bandwidth((VF("/outp") - VF("/outn")) 3 "low") if((TestVal = AFVtest("BWol" DomPoleFreq)) then printf(strcat("SPECFAIL: OpLp 3dB BW (typ) = " aelSuffixWithUnits(DomPoleFreq "Hz" 4 ) " Minimum specified = " aelSuffixWithUnits(TestVal "Hz" 4 ) "\n" ) ) ) ; ;//**** Add Scalar Outputs to Plot ** ;
addWaveLabel( 1 list( 1000 Aol) ; // point on the wave for the label sprintf(nil "DC OL Gain = %2.2f dB" Aol ) ?textOffset 10:-30 ?justify "lowerLeft" ) addWaveLabel( 1 list( UGF 0) ; // point on the wave for the label strcat("Unity Gain Fr. = " aelSuffixWithUnits(UGF "Hz" 4 ) ) ?textOffset -50:-30 ?justify "lowerLeft" ) addWindowLabel( list(0.15 0.2 ) strcat("Gain Margin = " aelSuffixWithUnits(Gmargin "dB") "\nPhase Margin = " aelSuffixWithUnits(Pmargin "deg") "\nGain BandWidth = " aelSuffixWithUnits(GBW "dB_Hz") "\nDominant Pole = " aelSuffixWithUnits(DomPoleFreq "Hz") ) ) ; ;//***** Plot this window and setup a new one ; hardCopy() ;************************************* AFVsetPlot( ?plotterName "ps2" ?outputFile "RESULTS/CmirDiffAmp4/RejRatios.ps" ?title strcat("Typical Amplifier Characteristics CmirDiffAmp4" getCurrentTime()) ?subTitle "Rejection Ratios" ) ;************************************* CMRR = dB20((1 / getData("/VCM" ?result "xf-xf"))) plot( CMRR ?expr ( "CMRR" ) ) PSRRdd = dB20((1 / getData("/VDD" ?result "xf-xf"))) plot( PSRRdd ?expr ( "PSRR+" ) ) PSRRss = dB20((1 / getData("/VSS" ?result "xf-xf"))) plot( PSRRss ?expr ( "PSRR-" ) ) CmRefRR = dB20((1 / getData("/VOUT" ?result "xf-xf"))) plot( CmRefRR ?expr ( "CmRef_RR" ) ) dcCMRR = value(dB20((1 / getData("/VCM" ?result "xf-xf"))) 0) dcCmRefRR = value(dB20((1 / getData("/VOUT" ?result "xf-xf"))) 0) dcPSRRdd = value(dB20((1 / getData("/VDD" ?result "xf-xf"))) 0) dcPSRRss = value(dB20((1 / getData("/VSS" ?result "xf-xf"))) 0) addWindowLabel( list(0.15 0.2 ) ;// the relative location for the Text strcat("CMRR = " aelSuffixWithUnits(dcCMRR "dB") "\nPSRR+ = " aelSuffixWithUnits(dcPSRRdd "dB") "\nPSRR- = " aelSuffixWithUnits(dcPSRRss "dB") "\nCmRefRR = " aelSuffixWithUnits(dcCmRefRR "dB") ) ) if((TestVal = AFVtest("CMRR" dcCMRR)) then printf(strcat("SPECFAIL: CMRR(DC) (typ) = " aelSuffixWithUnits(dcCMRR "dB" ) " Minimum specified = " aelSuffixWithUnits(TestVal "dB" ) "\n" )
) ) if((TestVal = AFVtest("CmRefRR" dcCmRefRR)) then printf(strcat("SPECFAIL: CMFB RR(DC) (typ) = " aelSuffixWithUnits(dcCmRefRR "dB" ) " Minimum specified = " aelSuffixWithUnits(TestVal "dB" ) "\n" ) ) ) if((TestVal = AFVtest("PSRRdd" dcPSRRdd)) then printf(strcat("SPECFAIL: PSRR Vdd(DC) (typ) = " aelSuffixWithUnits(dcPSRRdd "dB" ) " Minimum specified = " aelSuffixWithUnits(TestVal "dB" ) "\n" ) ) ) if((TestVal = AFVtest("PSRRss" dcPSRRss)) then printf(strcat("SPECFAIL: PSRR Vss(DC) (typ) = " aelSuffixWithUnits(dcPSRRss "dB" ) " Minimum specified = " aelSuffixWithUnits(TestVal "dB" ) "\n" ) ) ) ; ;//***** Plot this window and setup a new one ; hardCopy() ;************************************* AFVsetPlot( ?plotterName "ps2" ?outputFile "RESULTS/CmirDiffAmp4/StepResponse.ps" ?title strcat("Typical Amplifier Characteristics CmirDiffAmp4" getCurrentTime()) ?subTitle "Large Signal Step Response" ) ;************************************* displayMode( "strip") TranOutput = (VT("/outp") - VT("/outn")) plot( TranOutput ?expr ( "TranOutput" ) ) TranInput = (VT("/uginp") - VT("/uginn")) plot( TranInput ?expr ( "TranInput" ) ) plot( VT("/outp") ) plot( VT("/outn") ) ;SlewRate = slewRate((VT("/outp") - VT("/outn")) 2.5e-06 t 3.5e-06 t 10 90) OvershootP = overshoot((VT("/outp") - VT("/outn")) 4e-06 t 5e-06 t) OvershootN = overshoot((VT("/outp") - VT("/outn")) 3e-06 t 4e-06 t) ;Slewsinglep = slewRate(VT("/outp") 2.5e-06 t 3.5e-06 t 10 90) ;Slewsinglem = slewRate(VT("/outp") 3.5e-06 t 4.5e-06 t 10 90) ;OvershootPp = overshoot(VT("/outp") 2.5e-06 t 3.5e-06 t) ;OvershootPm = overshoot(VT("/outp") 3.5e-06 t 4.125e-06 t) ;RiseTime = riseTime((VT("/outp") - VT("/outn")) 3.5e-06 t 4.5e-06 t 10 90) ;OvershootN = overshoot(VT("/outn") 3e-06 t 3.125e-06 t)
;Tsettle0r1 = (settlingTime((VT("/outp") - VT("/outn")) 3e-06 t 4e-06 t 0.1) cross((VT("/uginp") - VT("/uginn")) 0 2 "rising")) Tsettle1P = (settlingTime((VT("/outp") - VT("/outn")) 4e-06 t 5e-06 t 1) - cross((VT("/uginp") - VT("/uginn")) 0 2 "rising")) Tsettle1N = (settlingTime((VT("/outp") - VT("/outn")) 3e-06 t 4e-06 t 1) - cross((VT("/uginp") - VT("/uginn")) 0 2 "falling")) SlewRateP = abs(slewRate((VT("/outp") - VT("/outn")) 3.5e-06 t 4.5e-06 t 10 90)) SlewRateN = abs(slewRate((VT("/outp") - VT("/outn")) 2.5e-06 t 3.5e-06 t 10 90)) addWindowLabel( list(0.6 0.7 ) ;// the relative location for the Text strcat("Overshoot = " aelSuffixWithUnits(OvershootP "%") "\nSlewRate = " aelSuffixWithUnits(SlewRateP "V/s") "\nTsettle1% = " aelSuffixWithUnits(Tsettle1P "s") ) ) if((TestVal = AFVtest("SlewRate" SlewRateP)) then printf(strcat("SPECFAIL: SlewRate/ (typ) = " aelSuffixWithUnits(SlewRateP "V/s" ) " Minimum specified = " aelSuffixWithUnits(TestVal "V/s" ) "\n" ) ) ) if((TestVal = AFVtest("SlewRate" SlewRateN)) then printf(strcat("SPECFAIL: SlewRate\\ (typ) = " aelSuffixWithUnits(SlewRateN "V/s" ) " Minimum specified = " aelSuffixWithUnits(TestVal "V/s" ) "\n" ) ) ) if((TestVal = AFVtest("OvrShoot" OvershootP)) then printf(strcat("SPECFAIL: Overshoot/ (typ) = " aelSuffixWithUnits(OvershootP "%%" ) " Maximum specified = " aelSuffixWithUnits(TestVal "%%" ) "\n" ) ) ) if((TestVal = AFVtest("OvrShoot" OvershootN)) then printf(strcat("SPECFAIL: Overshoot\\ (typ) = " aelSuffixWithUnits(OvershootN "%%" ) " Maximum specified = " aelSuffixWithUnits(TestVal "%%" ) "\n" ) ) ) if((TestVal = AFVtest("Tsettle" Tsettle1P)) then printf(strcat("SPECFAIL: Tsettle/ (typ) = " aelSuffixWithUnits(Tsettle1P "%%" ) " Maximum specified = "
aelSuffixWithUnits(TestVal "%%" ) "\n" ) ) ) if((TestVal = AFVtest("Tsettle" Tsettle1N)) then printf(strcat("SPECFAIL: Tsettle\\ (typ) = " aelSuffixWithUnits(Tsettle1N "%%" ) " Maximum specified = " aelSuffixWithUnits(TestVal "%%" ) "\n" ) ) ) ; ;//***** Plot this window and setup a new one ; hardCopy() ;************************************* AFVsetPlot( ?plotterName "ps2" ?outputFile "RESULTS/CmirDiffAmp4/VosDrift.ps" ?title strcat("Typical Amplifier Characteristics CmirDiffAmp4" getCurrentTime()) ?subTitle "Offset Voltage Drift" ) ;************************************* displayMode( "composite") plot( VS("/vos") ?expr ( "Vos" )) Vos = VDC("/vos") VosDrift = value(deriv(VS("/vos")) 27) addWaveLabel( 1 list( 27 Vos) ; // point on the wave for the label strcat("Vos Drift = " aelSuffixWithUnits(VosDrift "V/deg C" 4 ) ) ?textOffset 20:30 ?justify "lowerLeft" ) if((TestVal = AFVtest("VosDrift" VosDrift)) then printf(strcat("SPECFAIL: VosDrift (typ) = " aelSuffixWithUnits(VosDrift "V/deg C" ) " Maximum specified = " aelSuffixWithUnits(TestVal "V/deg C" ) "\n" ) ) ) if((TestVal = AFVtest("Vos" Vos)) then printf(strcat("SPECFAIL: Vos (typ) = " aelSuffixWithUnits(Vos "V" ) " Maximum specified = " aelSuffixWithUnits(TestVal "V" ) "\n" ) ) ) Idd = IDC("/VDD/MINUS") if((TestVal = AFVtest("Idd" Idd)) then printf(strcat("SPECFAIL: Idd (typ) = " aelSuffixWithUnits(Idd "A" )
" Maximum specified = " aelSuffixWithUnits(TestVal "A" ) "\n" ) ) ) Pdiss = Idd*VAR("Vdd") if((TestVal = AFVtest("Pdiss" Pdiss)) then printf(strcat("SPECFAIL: Pdiss (typ) = " aelSuffixWithUnits(Pdiss "W" ) " Maximum specified = " aelSuffixWithUnits(TestVal "W" ) "\n" ) ) ) ;//***** Plot this window and setup New Analyses and run them.. hardCopy() resultsDir( "~/proj446/icu/simulation/CmirDiffAmp_TB4/spectre/schematic" ) desVar( "VswngP" "Vdd" ) loadPcf("./OCEAN/OpampVerif.pcf") loadDcf("./OCEAN/OpampVerif.dcf") cornerRun() AFVsetPlot( ?plotterName "ps2" ?outputFile "RESULTS/CmirDiffAmp4/Corners.ps" ?title "" ) cornerMeas() addTitle(strcat("Amplifier PVT Characteristics CmirDiffAmp4" getCurrentTime()) ) currentSubwindow( 1 ) awvSetXLimit( awvGetCurrentWindow() list( 1K 1G ) ?subwindow 1 ) addSubwindowTitle( "Open Loop Gain") ; ; awvRedisplayWindow( awvGetCurrentWindow() ) ; hardCopy() ; /*********************************************** * * these results will be vectors or waves as shown here: * ocean> ocnPrint(Aol) C value(dB20((VF("outp") - VF("outn"))) 0) (dB)
FFhHi 62.3743 FS 62.4565 SF 62.6292 SScLo 62.4745 TT 62.5099 t * ** use the value command to get the individual values
* ocean> value(Aol "TT") 62.50989 *********************************************/ Idd = IDC("/VDD/MINUS") Pdiss = Idd*VDC("/vdd!") Vos = VDC("/vos") Aol = value(dB20((VF("/outp") - VF("/outn"))) 0) GBW = gainBwProd((VF("/outp") - VF("/outn"))) Gmargin = gainMargin((VF("/outp") - VF("/outn"))) Pmargin = phaseMargin((VF("/outp") - VF("/outn"))) UGF = cross(dB20((VF("/outp") - VF("/outn"))) 0 1 "either") DomPoleFreq = bandwidth((VF("/outp") - VF("/outn")) 3 "low") dcCMRR = value(dB20((1 / getData("/VCM" ?result "xf-xf"))) 0) dcCmRefRR = value(dB20((1 / getData("/VOUT" ?result "xf-xf"))) 0) dcPSRRdd = value(dB20((1 / getData("/VDD" ?result "xf-xf"))) 0) dcPSRRss = value(dB20((1 / getData("/VSS" ?result "xf-xf"))) 0) OvershootP = overshoot((VT("/outp") - VT("/outn")) 4e-06 t 5e-06 t) OvershootN = overshoot((VT("/outp") - VT("/outn")) 3e-06 t 4e-06 t) Tsettle1P = (settlingTime((VT("/outp") - VT("/outn")) 4e-06 t 5e-06 t 10) - cross((VT("/uginp") - VT("/uginn")) 0 2 "rising")) Tsettle1N = (settlingTime((VT("/outp") - VT("/outn")) 3e-06 t 4e-06 t 10) - cross((VT("/uginp") - VT("/uginn")) 0 2 "falling")) SlewRateP = abs(slewRate((VT("/outp") - VT("/outn")) 3.5e-06 t 4.5e-06 t 10 90)) SlewRateN = abs(slewRate((VT("/outp") - VT("/outn")) 2.5e-06 t 3.5e-06 t 10 90)) ; ; now get the corner values selectResults( dcOp ) ; first print the data files Crnrfile = outfile( "RESULTS/CmirDiffAmp4/CornerData.txt" ) ocnPrint( ?output Crnrfile ?numSpaces 4 "Corner" "Aol (dB) " "GBW (dB-Hz) " "Gmargin(dB) " "Pmargin(deg) " "UGFreq(Hz)" "BWol (dB)") ocnPrint( ?output Crnrfile Aol GBW Gmargin Pmargin UGF DomPoleFreq) ocnPrint( ?output Crnrfile ?numSpaces 4 "Corner " "Idd (A) " "Pdiss (W) " "CMRR(dB) " "CmRefRR(dB) " "PSRRdd(dB) " "PSRRss(dB) " ) ocnPrint( ?output Crnrfile Idd Pdiss dcCMRR dcCmRefRR dcPSRRdd dcPSRRss) ocnPrint( ?output Crnrfile ?numSpaces 4 "Corner" "OvershootP (%)" "OvershootN (%)" "Tsettle1P(s)" "Tsettle1N(s)" "SlRtp(V/s)" "SlRtn(V/s)" ) ocnPrint( ?output Crnrfile OvershootP OvershootN Tsettle1P Tsettle1N SlewRateP SlewRateN) close(Crnrfile) Corners = sweepValues(); foreach(Corner Corners ; first print the data files if((TestVal = AFVtest("Idd" value(Idd Corner))) then printf(strcat("SPECFAIL: Idd = " aelSuffixWithUnits(value(Idd Corner) "A" ) " Maximum specified = " aelSuffixWithUnits(TestVal "A" ) " Corner: " Corner "\n"
) ) ) if((TestVal = AFVtest("Pdiss" value(Pdiss Corner))) then printf(strcat("SPECFAIL: Pdiss = " aelSuffixWithUnits(value(Pdiss Corner) "W" ) " Maximum specified = " aelSuffixWithUnits(TestVal "W" ) " Corner: " Corner "\n" ) ) ) if((TestVal = AFVtest("Vos" value(Vos Corner))) then printf(strcat("SPECFAIL: Vos = " aelSuffixWithUnits(value(Vos Corner) "V" ) " Maximum specified = " aelSuffixWithUnits(TestVal "V" ) " Corner: " Corner "\n" ) ) ) if((TestVal = AFVtest("Aol" value(Aol Corner))) then printf("SPECFAIL: Aol = %2.2f Min Aol = %n dB Corner: %s\n" value(Aol Corner) TestVal Corner) ) if((TestVal = AFVtest("GainMargin" value(Gmargin Corner))) then printf("SPECFAIL: Gain Margin = %2.2f Max = %2.2f dB Corner: %s\n" value(Gmargin Corner) TestVal Corner) ) if((TestVal = AFVtest("GBW" value(GBW Corner))) then printf(strcat("SPECFAIL: Gain BW = " aelSuffixWithUnits(value(GBW Corner) "dB-Hz" ) " Minimum specified = " aelSuffixWithUnits(TestVal "dB-Hz" ) " Corner: " Corner "\n" ) ) ) if((TestVal = AFVtest("PhaseMargin" value(Pmargin Corner))) then printf(strcat("SPECFAIL: Phase Margin = " aelSuffixWithUnits(value(Pmargin Corner) "deg" ) " Minimum specified = " aelSuffixWithUnits(TestVal "deg" ) " Corner: " Corner "\n" ) ) ) if((TestVal = AFVtest("UGFreq" value(UGF Corner))) then printf(strcat("SPECFAIL: UGF = " aelSuffixWithUnits(value(UGF Corner) "Hz" 4 ) " Minimum specified = " aelSuffixWithUnits(TestVal "Hz" 4 )
" Corner: " Corner "\n" ) ) ) if((TestVal = AFVtest("BWol" value(DomPoleFreq Corner))) then printf(strcat("SPECFAIL: OpLp 3dB BW = " aelSuffixWithUnits(value(DomPoleFreq Corner) "Hz" 4 ) " Minimum specified = " aelSuffixWithUnits(TestVal "Hz" 4 ) " Corner: " Corner "\n" ) ) ) if((TestVal = AFVtest("CMRR" value(dcCMRR Corner))) then printf(strcat("SPECFAIL: CMRR(DC) = " aelSuffixWithUnits(value(dcCMRR Corner) "dB" ) " Minimum specified = " aelSuffixWithUnits(TestVal "dB" ) " Corner: " Corner "\n" ) ) ) if((TestVal = AFVtest("CmRefRR" value(dcCmRefRR Corner))) then printf(strcat("SPECFAIL: CMFB RR(DC) = " aelSuffixWithUnits(value(dcCmRefRR Corner) "dB" ) " Minimum specified = " aelSuffixWithUnits(TestVal "dB" ) " Corner: " Corner "\n" ) ) ) if((TestVal = AFVtest("PSRRdd" value(dcPSRRdd Corner))) then printf(strcat("SPECFAIL: PSRR Vdd(DC) = " aelSuffixWithUnits(value(dcPSRRdd Corner) "dB" ) " Minimum specified = " aelSuffixWithUnits(TestVal "dB" ) " Corner: " Corner "\n" ) ) ) if((TestVal = AFVtest("PSRRss" value(dcPSRRss Corner))) then printf(strcat("SPECFAIL: PSRR Vss(DC) = " aelSuffixWithUnits(value(dcPSRRss Corner) "dB" ) " Minimum specified = " aelSuffixWithUnits(TestVal "dB" ) " Corner: " Corner "\n" ) ) ) if((TestVal = AFVtest("SlewRate" value(SlewRateP Corner))) then
printf(strcat("SPECFAIL: SlewRate/ = " aelSuffixWithUnits(value(SlewRateP Corner) "V/s" ) " Minimum specified = " aelSuffixWithUnits(TestVal "V/s" ) " Corner: " Corner "\n" ) ) ) if((TestVal = AFVtest("SlewRate" value(SlewRateN Corner))) then printf(strcat("SPECFAIL: SlewRate\\ = " aelSuffixWithUnits(value(SlewRateN Corner) "V/s" ) " Minimum specified = " aelSuffixWithUnits(TestVal "V/s" ) " Corner: " Corner "\n" ) ) ) if((TestVal = AFVtest("OvrShoot" value(OvershootP Corner))) then printf(strcat("SPECFAIL: Overshoot/ = " aelSuffixWithUnits(value(OvershootP Corner) "%%" ) " Maximum specified = " aelSuffixWithUnits(TestVal "%%" ) " Corner: " Corner "\n" ) ) ) if((TestVal = AFVtest("OvrShoot" value(OvershootN Corner))) then printf(strcat("SPECFAIL: Overshoot\\ = " aelSuffixWithUnits(value(OvershootN Corner) "%%" ) " Maximum specified = " aelSuffixWithUnits(TestVal "%%" ) " Corner: " Corner "\n" ) ) ) if((TestVal = AFVtest("Tsettle" value(Tsettle1P Corner))) then printf(strcat("SPECFAIL: Tsettle/ = " aelSuffixWithUnits(value(Tsettle1P Corner) "%%" ) " Maximum specified = " aelSuffixWithUnits(TestVal "%%" ) " Corner: " Corner "\n" ) ) ) if((TestVal = AFVtest("Tsettle" value(Tsettle1N Corner))) then printf(strcat("SPECFAIL: Tsettle\\ = " aelSuffixWithUnits(value(Tsettle1N Corner) "%%" ) " Maximum specified = " aelSuffixWithUnits(TestVal "%%" ) " Corner: " Corner "\n" )
) ) ); foreach delete(analysis) ; now to find the Common Mode Range resultsDir( "~/proj446/icu/simulation/CmirDiffAmp_TB4/spectre/CMRange" ) analysis(dc ?saveOppoint t ) analysis(ac ?start "1K" ?stop "1G" ?dec "20" ) desVar( "inCMFB" 0 ) desVar( "DCgain" 100 ) desVar( "inDist" 0 ) desVar( "Fdist" 1M ) desVar( "ACin" 1 ) desVar( "VswngP" 1.5 ) desVar( "Tpin" 2u ) desVar( "Tr" 10n ) desVar( "gain" 1 ) desVar( "inAmp" .5 ) desVar( "Vss" 0 ) desVar( "Vdd" 1.8 ) desVar( "Vcm" 0.9 ) desVar( "Iref" 300u ) desVar( "ACout" 0 ) desVar( "VswngN" "-VswngP" ) option( reltol "1e-5" ) temp( 27 ) paramAnalysis("Vcm" ?values (0.1 0.15 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.95 1 1.05 1.10 1.15 1.20 1.25 1.30 1.35 1.40 1.45 1.50 1.55 1.60 1.65 1.70 1.75 1.80 ) ) paramRun() ;************************************* AFVsetPlot( ?plotterName "ps2" ?outputFile "RESULTS/CmirDiffAmp4/CMrange.ps" ?title strcat("Typical Amplifier Characteristics CmirDiffAmp4" getCurrentTime()) ?subTitle "Common Mode Range" ) ;************************************* Aol_DC = value(dB20((VF("/outp") - VF("/outn"))) 1000) plot( Aol_DC ?expr ( "Aol_DC" ) ) CMRmin = root(value(db20(VF("/outp")-VF("/outn")),1K), ymax(value(db20(VF("/outp")-VF("/outn")),1K))-3,1) CMRmax = root(value(db20(VF("/outp")-VF("/outn")),1K), ymax(value(db20(VF("/outp")-VF("/outn")),1K))-3,2) VcommonHigh = value(VAR("Vdd") 0.5) - CMRmax; addWindowLabel( list(0.4 0.4 ) ;// the relative location for the Text strcat("CMRmin = " aelSuffixWithUnits(CMRmin "V") "\nCMRmax = " aelSuffixWithUnits(CMRmax "V") ) ) if((TestVal = AFVtest("VcommonLow" CMRmin)) then printf(strcat("SPECFAIL: Vcm Low (typ) = " aelSuffixWithUnits(CMRmin "V" ) " Maximum specified = "
aelSuffixWithUnits(TestVal "V" ) "\n" ) ) ) if((TestVal = AFVtest("VcommonHigh" VcommonHigh)) then printf(strcat("SPECFAIL: Vcm High (from Vdd) = " aelSuffixWithUnits(VcommonHigh "V" ) " Maximum specified = " aelSuffixWithUnits(TestVal "V" ) "\n" ) ) ) hardCopy() ; now the cmfb circuit ; this next section is the modified version of the ; code from Appendix C Sample Generated Script resultsDir( "~/proj446/icu/simulation/CmirDiffAmp_TB4/spectre/schematic" ) analysis('dc ?saveOppoint t ) analysis('ac ?start "1" ?stop "100G" ?dec "20" ) desVar( "Fdist" 1M ) desVar( "DCgain" 100 ) desVar( "inDist" 0 ) desVar( "inCMFB" 1 ) desVar( "VswngP" 1 ) desVar( "Tpin" 2.5u ) desVar( "gain" 1 ) desVar( "inAmp" .5 ) desVar( "Vcm" 0.9 ) desVar( "Iref" 300u ) desVar( "ACin" 0 ) desVar( "ACout" 0 ) desVar( "VswngN" "-VswngP" ) option( 'reltol "1e-5" ) temp( 27 ) run() ;************************************* AFVsetPlot( ?plotterName "ps2" ?outputFile "RESULTS/CmirDiffAmp4/CMFB.ps" ?title strcat("Typical Amplifier Characteristics CmirDiffAmp4" getCurrentTime()) ?subTitle "Common Mode Feedback" ) ;************************************* displayMode( "strip") ;AclPcmfb = dB20(VF("/outp")) ;plot( AclPcmfb ?expr '( "AclPcmfb" ) ) ;PhclNcmfb = phase(VF("/outn")) ;plot( PhclNcmfb ?expr '( "PhclNcmfb" ) ) ;PhclPcmfb = phase(VF("/outp")) ;plot( PhclPcmfb ?expr '( "PhclPcmfb" ) ) ;AclNcmfb = dB20(VF("/outn")) ;plot( AclNcmfb ?expr '( "AclNcmfb" ) ) ;PhMarginPcmfbcl = phaseMargin(VF("/outp")) ;plot( PhMarginPcmfbcl ?expr '( "PhMarginPcmfbcl" ) )
;PhMarginNcmfbcl = phaseMargin(VF("/outn")) ;plot( PhMarginNcmfbcl ?expr ( "PhMarginNcmfbcl" ) ) Acmfbn = dB20((VF("/outn") / (VF("/outn") - VF("/cmout")))) plot( Acmfbn ?expr ( "Acmfbn" ) ) Acmfbp = dB20((VF("/outp") / (VF("/outp") - VF("/cmout")))) plot( Acmfbp ?expr ( "Acmfbp" ) ) BWcmfbN = bandwidth(VF("/outn") 3 "low") ;plot( BWcmfbN ?expr ( "BWcmfbN" ) ) BWcmfbP = bandwidth(VF("/outp") 3 "low") ;plot( BWcmfbP ?expr ( "BWcmfbP" ) ) PhiCmfbN = phase((VF("/outn") / (VF("/outn") - VF("/cmout")))) plot( PhiCmfbN ?expr ( "PhiCmfbN" ) ) PhiCmfbP = phase((VF("/outp") / (VF("/outp") - VF("/cmout")))) plot( PhiCmfbP ?expr ( "PhiCmfbP" ) ) PhMarginNcmfbol = phaseMargin((VF("/outn") / (VF("/outn") - VF("/cmout")))) PhMarginPcmfbol = phaseMargin((VF("/outp") / (VF("/outp") - VF("/cmout")))) CMFBAolP = value( Acmfbp 0) CMFBAolN = value( Acmfbn 0) addWindowLabel( list(0.4 0.4 ) ;// the relative location for the Text strcat("BW Pside = " aelSuffixWithUnits(BWcmfbP "Hz") "\nBW Nside = " aelSuffixWithUnits(BWcmfbN "Hz") "\nPhMar Pside = " aelSuffixWithUnits(PhMarginPcmfbol "deg") "\nPhMar Nside = " aelSuffixWithUnits(PhMarginPcmfbol "deg") "\nAol cmfb Pside = " aelSuffixWithUnits(CMFBAolP "dB") "\nAol cmfb Nside = " aelSuffixWithUnits(CMFBAolN "dB") ) ) if((TestVal = AFVtest("CMFBAol" CMFBAolP)) then printf(strcat("SPECFAIL: CMFBAol (P) = " aelSuffixWithUnits(CMFBAolP "V" ) " Minimum specified = " aelSuffixWithUnits(TestVal "V" ) "\n" ) ) ) if((TestVal = AFVtest("CMFBAol" CMFBAolN)) then printf(strcat("SPECFAIL: CMFBAol (N) = " aelSuffixWithUnits(CMFBAolN "V" ) " Minimum specified = " aelSuffixWithUnits(TestVal "V" ) "\n" ) ) ) if((TestVal = AFVtest("CMFBPhMar" PhMarginPcmfbol)) then printf(strcat("SPECFAIL: CMFBPhMar (P) = " aelSuffixWithUnits(PhMarginPcmfbol "V" ) " Minimum specified = " aelSuffixWithUnits(TestVal "V" ) "\n" ) ) ) if((TestVal = AFVtest("CMFBPhMar" PhMarginNcmfbol)) then printf(strcat("SPECFAIL: CMFBPhMar (N) = "
aelSuffixWithUnits(PhMarginNcmfbol "V" ) " Minimum specified = " aelSuffixWithUnits(TestVal "V" ) "\n" ) ) ) hardCopy() ;;*************************** NOISE delete(analysis) path( "./models" ) ; to use models with noimod = 3 resultsDir( "~/proj446/icu/simulation/CmirDiffAmp_TB4/spectre/noise" ) analysis(noise ?start "1" ?stop "1G" ?dec "20" ?p "/outp" ?n "/outn" ?oprobe "" ?iprobe "/VIN" ) analysis(dc ?saveOppoint t ) analysis(ac ?start "1" ?stop "1G" ?dec "20" ) desVar( "Fdist" 1M ) desVar( "DCgain" 100 ) desVar( "inDist" 0 ) desVar( "inCMFB" 0 ) desVar( "VswngP" 1 ) desVar( "Tpin" 2.5u ) desVar( "Tdin" 0 ) desVar( "Tr" 10n ) desVar( "Cload" 100p ) desVar( "Rload" 10M ) desVar( "gain" 1 ) desVar( "inAmp" .5 ) desVar( "Vss" 0 ) desVar( "Vdd" 2 ) desVar( "Vcm" 1.0 ) desVar( "Iref" 300u ) desVar( "ACin" 1 ) desVar( "ACout" 0 ) desVar( "VswngN" "-VswngP" ) option( reltol "1e-5" ) temp( 27 ) run() ;************************************* AFVsetPlot( ?plotterName "ps2" ?outputFile "RESULTS/CmirDiffAmp4/Noise.ps" ?title strcat("Typical Amplifier Characteristics CmirDiffAmp4" getCurrentTime()) ?subTitle "Noise" ) ;************************************* displayMode("composite") ENV = ymin(getData("in" ?result "noise-noise")) plot( getData("out" ?result "noise-noise") ) plot( getData("in" ?result "noise-noise") ) Fbv = bandwidth(clip((1 / getData("in" ?result "noise-noise")) 1 10000000) 6 "high") addWindowLabel( list(0.4 0.4 ) ;// the relative location for the Text strcat("ENV = " aelSuffixWithUnits(ENV "V/sqrt(Hz)") "\nFbv = " aelSuffixWithUnits(Fbv "Hz") )
) if((TestVal = AFVtest("ENV" ENV)) then printf(strcat("SPECFAIL: ENV input = " aelSuffixWithUnits(ENV "V/sqrt(Hz)" ) " Maximum specified = " aelSuffixWithUnits(TestVal "V/sqrt(Hz)" ) "\n" ) ) ) if((TestVal = AFVtest("Fbv" Fbv)) then printf(strcat("SPECFAIL: Fbv input = " aelSuffixWithUnits(Fbv "Hz" ) " Maximum specified = " aelSuffixWithUnits(TestVal "Hz" ) "\n" ) ) ) hardCopy() ;;******************************** ZOUT delete(analysis) resultsDir( "~/proj446/icu/simulation/CmirDiffAmp_TB4/spectre/ImpeadOut" ) analysis(dc ?saveOppoint t ) analysis(ac ?start "1" ?stop "100G" ?dec "20" ) desVar( "inCMFB" 0 ) desVar( "DCgain" 100 ) desVar( "inDist" 0 ) desVar( "Fdist" 1M ) desVar( "ACin" 0 ) desVar( "Tpin" 2u ) desVar( "Tdin" 10n ) desVar( "Tr" 10n ) desVar( "Cload" 100p ) desVar( "Rload" 1M ) desVar( "gain" 1 ) desVar( "inAmp" .5 ) desVar( "Vss" 0 ) desVar( "Vdd" 1.8 ) desVar( "Vcm" 0.9 ) desVar( "Iref" 300u ) desVar( "ACout" 1 ) desVar( "VswngP" 1 ) desVar( "VswngN" "-VswngP" ) temp( 27 ) run() ;************************************* AFVsetPlot( ?plotterName "ps2" ?outputFile "RESULTS/CmirDiffAmp4/Zout.ps" ?title strcat("Typical Amplifier Characteristics CmirDiffAmp4" getCurrentTime()) ?subTitle "Output Impedance" ) ;************************************* Zoutn = (VF("/von") / IF("/V8/PLUS")) plot( Zoutn ?expr ( "Zoutn" ) ) Zoutp = (VF("/vop") / IF("/V7/PLUS"))
plot( Zoutp ?expr ( "Zoutp" ) ) Zoutn1M = value(real((VF("/von") / IF("/V8/PLUS"))) 1M) ;plot( Zoutn1M ?expr ( "Zoutn1M" ) ) Zoutp1M = value(real((VF("/vop") / IF("/V7/PLUS"))) 1M) ;plot( Zoutp1M ?expr ( "Zoutp1M" ) ) if((TestVal = AFVtest("Zout" Zoutp1M)) then printf(strcat("SPECFAIL: Zout@1M P = " aelSuffixWithUnits(Zoutp1M "Ohms" ) " Maximum specified = " aelSuffixWithUnits(TestVal "Ohms" ) "\n" ) ) ) if((TestVal = AFVtest("Zout" Zoutn1M)) then printf(strcat("SPECFAIL: Zout@1M N = " aelSuffixWithUnits(Zoutn1M "Ohms" ) " Maximum specified = " aelSuffixWithUnits(TestVal "Ohms" ) "\n" ) ) ) hardCopy() ;;********************************** THD ;and Sinusoid outputs resultsDir( "~/proj446/icu/simulation/CmirDiffAmp_TB4/spectre/THD" ) analysis(noise ?start "100" ?stop "10M" ?dec "20" ?p "/outp" ?n "/outn" ?oprobe "" ?iprobe "/VIN" ) analysis(tran ?stop "5u" ?skipdc "no" ?maxiters "10" ?restart "no" ) desVar( "inCMFB" 0 ) desVar( "DCgain" 100 ) desVar( "inDist" 1 ) desVar( "Fdist" 1M ) desVar( "ACin" 1 ) desVar( "VswngP" 0 ) desVar( "Tpin" 2u ) desVar( "Tdin" 0 ) desVar( "Tr" 10n ) desVar( "Cload" 100p ) desVar( "Rload" 100K ) desVar( "gain" 1 ) desVar( "inAmp" .5 ) desVar( "Vss" 0 ) desVar( "Vdd" 1.8 ) desVar( "Vcm" 1.0 ) desVar( "Iref" 300u ) desVar( "ACout" 0 ) desVar( "VswngN" "-VswngP" ) option( reltol "1e-5" ) temp( 27 ) run() ;************************************* AFVsetPlot( ?plotterName "ps2"
?outputFile "RESULTS/CmirDiffAmp4/SineTrans.ps" ?title strcat("Typical Amplifier Characteristics CmirDiffAmp4" getCurrentTime()) ?subTitle "Sinusoid Response (for THD)" ) ;************************************* TranOutput = (VT("/outp") - VT("/outn")) plot( TranOutput ?expr ( "TranOutput" ) ) TranInput = (VT("/uginp") - VT("/uginn")) plot( TranInput ?expr ( "TranInput" ) ) plot( VT("/outp") ) plot( VT("/outn") ) hardCopy() ;************************************* AFVsetPlot( ?plotterName "ps2" ?outputFile "RESULTS/CmirDiffAmp4/thd.ps" ?title strcat("Typical Amplifier Characteristics CmirDiffAmp4" getCurrentTime()) ?subTitle "Distortion at 1M Hz" ) ;************************************* plotStyle(bar) Fourier_Spectrum = dB20((v "/outp" ?result "FOUR1-tran.test_fourier" )) plot( Fourier_Spectrum ?expr ( "Fourier Spectrum" ) ) THD = thd((VT("/outp") - VT("/outn")) 4e-06 5e-06 64) plot( THD ?expr ( "THD" ) ) addWindowLabel( list(0.4 0.4 ) ;// the relative location for the Text strcat("THD = " aelSuffixWithUnits(THD "%") "\n") ) ) awvSetXLimit( awvGetCurrentWindow() list(0 100M) ) hardCopy() if((TestVal = AFVtest("THD" THD)) then printf(strcat("SPECFAIL: THD = " aelSuffixWithUnits(THD "%%" ) ; first "%" is Format Spec " Maximum specified = " aelSuffixWithUnits(TestVal "%%" ) "\n" ) ) )
corAddCorner( "TSMC18" "FFhHi" ) corSetCornerGroupVariant( "TSMC18" "FFhHi" "log018.scs" "ff" ) corSetCornerRunTempVal( "TSMC18" "FFhHi" 100 ) corSetCornerVarVal( "TSMC18" "FFhHi" "Vdd" "2" ) corSetCornerVarVal( "TSMC18" "FFhHi" "Vcm" "1.1" ) corAddCorner( "TSMC18" "SF" ) corSetCornerGroupVariant( "TSMC18" "SF" "log018.scs" "sf" ) corSetCornerVarVal( "TSMC18" "SF" "Vdd" "1.8" ) corSetCornerVarVal( "TSMC18" "SF" "Vcm" "900m" ) corAddCorner( "TSMC18" "FS" ) corSetCornerGroupVariant( "TSMC18" "FS" "log018.scs" "fs" ) corSetCornerRunTempVal( "TSMC18" "FS" 27 ) corSetCornerVarVal( "TSMC18" "FS" "Vdd" "1.8" ) corSetCornerVarVal( "TSMC18" "FS" "Vcm" "900m" )
corAddMeas( "Vdd" ) corSetMeasExpression( "Vdd" "VDC(\"/vdd!\")" ) corSetMeasEnabled( "Vdd" t ) corSetMeasGraphicalOn( "Vdd" nil ) corSetMeasTextualOn( "Vdd" nil )
corAddMeas( "CmRefRR" ) corSetMeasExpression( "CmRefRR" "value(dB20((1 / getData(\"/VOUT\" ?result \"xf-xf\"))) 0)" ) corSetMeasEnabled( "CmRefRR" t ) corSetMeasGraphicalOn( "CmRefRR" nil ) corSetMeasTextualOn( "CmRefRR" nil )
corAddMeas( "VoutSwing" ) corSetMeasExpression( "VoutSwing" "(ymax((VT(\"/outp\")-VT(\"/outn\")))-ymin((VT(\"/outp\")-VT(\"/outn\"))))" ) corSetMeasEnabled( "VoutSwing" t ) corSetMeasGraphicalOn( "VoutSwing" nil ) corSetMeasTextualOn( "VoutSwing" nil )
corAddMeas( "Vhi_diffP" ) corSetMeasExpression( "Vhi_diffP" "value((VT(\"/vdd!\") - VT(\"/outp\")) 3e-06)" ) corSetMeasEnabled( "Vhi_diffP" t ) corSetMeasGraphicalOn( "Vhi_diffP" nil ) corSetMeasTextualOn( "Vhi_diffP" nil )
corAddMeas( "Vlo_diffN" ) corSetMeasExpression( "Vlo_diffN" "value((VT(\"/outn\") - VT(\"/vss!\")) 3e-06)" ) corSetMeasEnabled( "Vlo_diffN" t ) corSetMeasGraphicalOn( "Vlo_diffN" nil ) corSetMeasTextualOn( "Vlo_diffN" nil )
corAddMeas( "Aol_dB" ) corSetMeasExpression( "Aol_dB" "dB20((VF(\"/outp\") - VF(\"/outn\")))" ) corSetMeasEnabled( "Aol_dB" t ) corSetMeasGraphicalOn( "Aol_dB" t ) corSetMeasTextualOn( "Aol_dB" nil )
corAddMeas( "Isc-n" ) corSetMeasExpression( "Isc-n" "ymax(clip(IT(\"/V8/PLUS\") 1e-06 5e-06))" ) corSetMeasEnabled( "Isc-n" t ) corSetMeasGraphicalOn( "Isc-n" nil ) corSetMeasTextualOn( "Isc-n" nil )
corAddMeas( "PhaseMargin" ) corSetMeasExpression( "PhaseMargin" "phaseMargin((VF(\"/outp\") - VF(\"/outn\")))" ) corSetMeasEnabled( "PhaseMargin" t ) corSetMeasGraphicalOn( "PhaseMargin" nil ) corSetMeasTextualOn( "PhaseMargin" nil )
corAddMeas( "UGFreq" ) corSetMeasExpression( "UGFreq" "cross(dB20((VF(\"/outp\") - VF(\"/outn\"))) 0 1 \"either\")" ) corSetMeasEnabled( "UGFreq" t ) corSetMeasGraphicalOn( "UGFreq" nil ) corSetMeasTextualOn( "UGFreq" nil )
corAddMeas( "Pdiss" ) corSetMeasExpression( "Pdiss" "(IDC(\"/VSS/PLUS\") * (VAR(\"Vdd\") + VAR(\"Vss\")))" ) corSetMeasEnabled( "Pdiss" t ) corSetMeasGraphicalOn( "Pdiss" nil ) corSetMeasTextualOn( "Pdiss" nil )
corAddMeas( "Vos" ) corSetMeasExpression( "Vos" "VDC(\"/vos\")" ) corSetMeasEnabled( "Vos" t ) corSetMeasGraphicalOn( "Vos" nil ) corSetMeasTextualOn( "Vos" nil )
corAddMeas( "PSRRdd" ) corSetMeasExpression( "PSRRdd" "value(dB20((1 / getData(\"/VDD\" ?result \"xf-xf\"))) 0)" ) corSetMeasLower( "PSRRdd" 100 ) corSetMeasTarget( "PSRRdd" 110 ) corSetMeasEnabled( "PSRRdd" t ) corSetMeasGraphicalOn( "PSRRdd" t ) corSetMeasTextualOn( "PSRRdd" nil )
corAddMeas( "Aol" ) corSetMeasExpression( "Aol" "value(dB20((VF(\"/outp\") - VF(\"/outn\"))) 0)" ) corSetMeasLower( "Aol" 60 ) corSetMeasTarget( "Aol" 70 ) corSetMeasEnabled( "Aol" t )
corAddMeas( "PSRRss" ) corSetMeasExpression( "PSRRss" "value(dB20((1 / getData(\"/VSS\" ?result \"xf-xf\"))) 0)" ) corSetMeasLower( "PSRRss" 100 ) corSetMeasTarget( "PSRRss" 110 ) corSetMeasEnabled( "PSRRss" t ) corSetMeasGraphicalOn( "PSRRss" nil ) corSetMeasTextualOn( "PSRRss" nil )
corAddMeas( "GBW" ) corSetMeasExpression( "GBW" "gainBwProd((VF(\"/outp\") - VF(\"/outn\")))" ) corSetMeasEnabled( "GBW" t ) corSetMeasGraphicalOn( "GBW" nil ) corSetMeasTextualOn( "GBW" nil )
corAddMeas( "SlewRateP" ) corSetMeasExpression( "SlewRateP" "slewRate((VT(\"/outp\") - VT(\"/outn\")) 3.5e-06 t 4.5e-06 t 10 90)" ) corSetMeasEnabled( "SlewRateP" t ) corSetMeasGraphicalOn( "SlewRateP" nil ) corSetMeasTextualOn( "SlewRateP" nil )
corAddMeas( "SlewRateN" ) corSetMeasExpression( "SlewRateN" "slewRate((VT(\"/outp\") - VT(\"/outn\")) 2.5e-06 t 3.5e-06 t 10 90)" ) corSetMeasEnabled( "SlewRateN" t ) corSetMeasGraphicalOn( "SlewRateN" nil ) corSetMeasTextualOn( "SlewRateN" nil )
corAddMeas( "GainMargin" ) corSetMeasExpression( "GainMargin" "gainMargin((VF(\"/outp\") - VF(\"/outn\")))" ) corSetMeasEnabled( "GainMargin" t ) corSetMeasGraphicalOn( "GainMargin" nil ) corSetMeasTextualOn( "GainMargin" nil )
corAddMeas( "CMRR" ) corSetMeasExpression( "CMRR" "value(dB20((1 / getData(\"/VCM\" ?result \"xf-xf\"))) 0)" ) corSetMeasLower( "CMRR" 100 ) corSetMeasTarget( "CMRR" 110 ) corSetMeasEnabled( "CMRR" t ) corSetMeasGraphicalOn( "CMRR" t ) corSetMeasTextualOn( "CMRR" nil ) corAddMeas( "VosTemp" ) corSetMeasExpression( "VosTemp" "VS(\"/vos\")" ) corSetMeasEnabled( "VosTemp" t )
corSetMeasGraphicalOn( "VosTemp" nil ) corSetMeasTextualOn( "VosTemp" nil ) ;corAddMeas( "VosDrift" ) ;corSetMeasExpression( "VosDrift" "value(deriv(VS(\"/vos\")) 27)" ) ;corSetMeasEnabled( "VosDrift" t ) ;corSetMeasGraphicalOn( "VosDrift" nil ) ;corSetMeasTextualOn( "VosDrift" nil )
corAddMeas( "Isc+p" ) corSetMeasExpression( "Isc+p" "ymin(clip(IT(\"/V7/PLUS\") 1e-06 5e-06))" ) corSetMeasEnabled( "Isc+p" t ) corSetMeasGraphicalOn( "Isc+p" nil ) corSetMeasTextualOn( "Isc+p" nil )