For the loop will set you free!

One thing I forgot to mention in the previous post is that if you can get it to work, we’re just one tiny step away from the ultimate purpose of OCEAN Script which is automation – run multiple simulations with different settings and/or design values, automatically. We will master that step in this post.

The loop …

The basic concept for simulation loop, in OCEAN Script, can be broken down in few following sub-steps:

  • Firstly, we’ll need to define a list of values that would be applied to the simulation.
  • Secondly, set up a “foreach” loop to access and get one value a time from the defined list. Then, the acquired value is applied to the design parameter.
  • Finally, we’ll run the simulation with new value for the parameter, with in the loop.

Below is simplified example for commonly used loops which sweep values of design parameter (ib) and different temperatures, respectively.

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
; ...
; Run simulation with various values for "ib"
; List declaration with 3 values to be swept
ibias_list = list(8.5u 10u 11.5u)

; Loop declaration and start
foreach(
; Get a value in list and store in ibias_val
ibias_val ibias_list
; Assign ibias_val to design parameter "ib"
desVar("ib" ibias_val)

; Code for other setups, loops run simulation is here
) ; Stop loop for "ib" values

; Run simulation with different temperature values
temp_list = list(-40 25 90)

foreach(
; Get a value in list and store in temp_val
temp_val temp_list
; Set temperature of temp_val for simulation
temp(temp_val)

; ...
) ; Stop loop for temperature values
; ...

Looping for corner takes a little bit more work but still very much manageable. Below is the code sample for it. Again, it’s always the best practice to check model file and corner settings with your CAD support.

 1
2
3
4
5
6
7
8
9
10
11
12
13
; ...
; Run simulation with different corner values
corner_list = list("TYP" "SLOW" "FAST" "SLOWFAST" "FASTSLOW")

foreach(
; Get value in list and store in corner_val
corner_val corner_list
; Set new corner value
modelFile(list("~/corner.scs" strcat(corner_val)))

; ...
)
; ...

and the freedom it brings.

At this point, you might think that this is pretty good to have all of the above loops running. If so, I’m glad to let you know that thing is still looking up from here, since OCEAN allows nested loops which means you can set up loop inside another loop. 

This alone enables simulation running with a lot of combinations of values from different parameters and settings. For example, nesting three above implemented loops into each other yields  a script that would run 45(3*3*5) simulations, automatically! Imagine if you have to run all that manually would give you a sense of the freedom OCEAN Script brings – Once setup properly, it works diligently so that you’re free to do other stuffs. 

The large number of simulations would run in the new script yields in a large number of  result sets. Thus, it raises a pleasant challenge that is we need to be able to discern between one result set and another. One way to achieve this is writing the condition applied to the simulation with its results. Below is the full code for the opamp characterization.

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
; File: Opamp_tb.ocn
; Author: Pham Duy Dong
; Purpose: Operation amplifier characterization
; License: Creative Commons Attribution 3.0 Unported License

simulator('spectre)
design("DI3_CVC_PDD" "Opamp_tb" "schematic")
createNetlist(?recreateAll t)

analysis('ac ?start "0.1" ?stop "1G")
analysis('dc ?saveOppoint t)

desVar("CL" 5p)

; Define, create the output file and write the first line into it.
out = outfile("~/Opamp.txt" "w")
fprintf(out, "Corner IBias Temp. GBW PM GM OLGain IDC FOM\n")
close(out)

; List definitions
ibias_list = list(8.5u 10u 11.5u)
temp_list = list(-40 25 90)
corner_list = list("NOM" "SLOW" "FAST" "SLOWFAST" "FASTSLOW")

foreach(
corner_val corner_list
; Set new corner value
modelFile(list("~/corner.scs" strcat(corner_val)))

foreach(
ibias_val ibias_list
desVar("ib" ibias_val)

foreach(
temp_val temp_list
            temp(temp_val) 

; Save the current going through port VDD of component I1,
; for estimating current consumption of the opamp.
saveOption('save "selected")
save('v "/OUT")
save('i "/I1/VDD")

; Execute the simulation
run()

; Calculate Gain-Bandwidth, Phase Margin, Gain Margin, Open Loop Gain,
; and DC current using built-in functions and store results in variables.
GBW = gainBwProd(VF("/OUT"))
PM = phaseMargin(VF("/OUT"))
GM = gainMargin(VF("/OUT"))
OLGain = ymax(dB20(real(VF("/OUT"))))
IDC = IDC("/I1/VDD")

CL = evalstring(desVar("CL"))

; Calculate Figure-of-Merit of opamp. FOM = GBW(MHz) * CL(pF) / IDC(mA)
; GBW(MHz) = GBW * 1e-6; CL(pF) = CL * 1e12; IDC(mA) = IDC * 1e3.
FOM = 1e3 * GBW * CL / IDC

; Open ouput file in append mode.
out = outfile("~/Opamp.txt" "a")
; Print out the simulation condition.
fprintf(out,"%8s %8.2e %3d",corner_val,ibias_val,temp_val)
; Print out the calculated results.
fprintf(out," %8.2e %8.2e %8.2e %8.2e %8.2e %8.2e\n",GBW,PM,GM,OLGain,IDC,FOM)
close(out)

) ; End of temperature loop
) ; End of biasing current loop
) ; End of corner loop


Happy designing!

Dive into OCEAN Script

I’ve been prepared this post with the original title of “Data and variables” with the structure of a list of frequently used commands and settings in a OCEAN Script. It’s been a very slow and boring process then I realized that I was essentially doing a language reference which is not what I did to jump start my simulation. So let’s scratch that and do it the right way, instead.

Let’s dive right into OCEAN Script!

Extending the script we built in previous post, we get a new script as below. The script will configure the simulation, run it, store data it generated, calculate the specifications of the opamp, and then write the result to an output file.

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
; This is a comment line. 
; The comment starts from ";" character and ends at the end of the line.

; 1. Setups for simulator, targeted design, model file,
; simulation type and parameters.
simulator( 'spectre )
design( "OceanScriptLib" "Opamp_tb" "schematic" )
createNetlist(?recreateAll t)
; 1.1. Check model file setting with your CAD support, if any.
modelFile( '("~/model.scs" "TYP") )
analysis('ac ?start "0.1" ?stop "1G" )

; 2. Set value of load capacitor at 5pF, bias current at 10uA.
; "CL" and "IB" are the values declared in schematic. desVar = design variable.
desVar( "CL" 5p )
desVar( "IB" 10u )

; 3. Save the current going through port VDD of component I1,
; for estimating current consumption of the opamp.
saveOption('save "selected")
save( 'v "/OUT" )
save( 'i "/I1/VDD" )

; 4. Execute the simulation
run()

; 5.1. Calculate GBW, PM, GM, OLGain, and IDC
; using built-in functions and store results in variables.
GBW = gainBwProd(VF("/OUT"))
PM = phaseMargin(VF("/OUT"))
GM = gainMargin(VF("/OUT"))
OLGain = ymax(dB20(real(VF("/OUT"))))
IDC = average(mag(IF("/I1/VDD")))

; 5.2. Read design variable CL and assign the result to calculation parameter Cl.
Cl = evalstring( desVar("CL") )

; 5.3. Calculate Figure-of-Merit of the opamp. FOM = GBW(MHz) * CL(pF) / IDC(mA)
; GBW(MHz) = GBW * 1e-6; CL(pF) = CL * 1e12; IDC(mA) = IDC * 1e3.
FOM = 1e3 * GBW * CL / IDC

; 6.1. Define, create the output file and write the first line into it.
out = outfile("~/Opamp.txt" "w")
fprintf(out, "GBW PM GM OLGain IDC FOM\n")
close(out)

; 6.2. Open ouput file and append calculated results into it.
out = outfile("~/Opamp.txt" "a")
fprintf(out,"%10.2e %10.2e %10.2e %10.2e %10.2e %10.2e\n",GBW,PM,GM,OLGain,IDC,FOM)
close(out)


I hope the explanation given in the code is clear enough. After reading the script, you may try to modify the code to your particular setup and put it to work. Remember to check out the simulation result in the output file, see how well your opamp performs.

P.S. It may seem that writing the script from scratch is an overwhelming task. Luckily, there is a faster way to dive into OCEAN Script, thanks to a built-in feature in ADE.

Once the evaluation bench for Opamp is done. Go to your ADE window to configure for your simulation. Then, in ADE go to Session > Save Ocean Script > a new window titled “Save Ocean Script to File” would pop-up. Enter path and file name for .ocn file.

I’m sure you get the idea.

Simulation setup for Opamp characterizations

Of course running a simulation without any setting any options/variables and getting any output data is neither fun nor productive. Hence, we will introduce these aspects into our OCEAN Script. Before that, it is necessary to establish some context for a typical test setup for an single-end opamp.

Simple simulation setup for Opamp characterization.

The DUT (Device Under Test) – the opamp has self-explanatory pins of VIN, VIP, OUT, VDD, GND, and IBIAS. It also has an instant name of I1, in this circuit.


Voltage source V0 supplies power for the whole opamp via net and pin VDD. DC current source IB sets biasing current to the opamp. Value for supply voltage – VDD = 1.8V, is typical for design in 0.18um CMOS process. We choose our biassing current IB = 10uA.  

Sinusoidal voltage source V1 connects to pin VIP. This provides AC input signal with suitable DC biasing for VIP. This voltage is usually set to VDD/2 = 0.9V, in this circuit.

Capacitor C1 and inductor L1 short VIN and OUT at DC and disconnect them at higher frequency. As a result, the config forms an unity gain buffer at DC, hence it sets a bias voltage to VIN which is the same with that of VIP. For this purpose, the values of C1 and L1 are chosen to be huge, for example 10F and 1GH.

Capacitor CL is the load the opamp drives. Its value is usually in pF range, say 5pF.

With this test setup, we will be able to estimate some major specifications of the opamp as follows: Open loop gain – OLGain, gain bandwidth – GBW, phase and gain margin – PM and GM, and current consumption – ID.

From these data, a simplified figure of merit – FOM of the opamp can be calculated. FOM estimates how much gain banwidth the opamp has with certain load capacitance while it burns certain amount of current.

That’s it for now.


PS: I created a simple component template for circuit schematic drawing here. Feel free to use it.

OCEAN Script – Simulated

As an OCEAN script for a simulation progresses, it loosely contains of three command groups, as follows:

  1. Simulation setup commands which are used to specify
    • location of schematic/netlist of the circuit to be evaluated;
    • type of simulation;
    • type of simulator;
    • options for simulator;
    • devices’ models;
    • nets(voltages) or currents to be saved…
  1. Simulation run command.
  2. Simulation data access commands which would
    • perform calculation(s) on saved results;
    • print or plot out saved/calculated data.


In this post, we’ll create a as-simple-as-possible script for our simulation. The script will only feature commands from the first two groups listed above.

For the said purpose, let’s assume that you have design an operation amplifier – opamp for short; I believe any Analog IC Designer has to design an opamp in his career. Furthermore, you have an evaluation setup for the opamp in “schematic” view of cell named “Opamp_tb” located in library “OceanScriptLib“.

Let’s write our first Ocean Script so once runs, it would perform a AC simulation on this evaluation circuit. The AC simulation is the most commonly used simulation type for opamp circuit.

Please read through the script for the Opamp_tb.ocn below. Explanations for it are in the comments.

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
; This is a comment line. The comment starts from ";" character and ends at the end of the line

; Begin of simulation setup
; Set the simulator as "spectre"
simulator( 'spectre )

; Location of circuit to be simulated based on library name, cell name, and view name
design( "OceanScriptLib" "Opamp_tb" "schematic" )

; Set up model information based on full path of the model file and corner name
; As an example, below command apply for model file “~/model.scs” and “TYP” - name for typical corner
modelFile( '("~/model.scs" "TYP") )

; AC simulation, from frequency of 1mHz to 1GHz
analysis(' ac ?start "1e-3" ?stop "1e9" )
; End of simulation setup

; Run the simulation
run()


Let’s save the script as Opamp_tb.ocn at home directory ~/, then head to CIW window to test the script in the same way described in Hello World post.

Please read the log which is posted in CIW window as the script runs. You’ll find that the script indeed executes the simulation, but nothing else shows up once it finishes. This is because our script lacks of any data saving and accessing commands. We will add that as our script extends in future posts.

OCEAN Script – Hello World

OCEAN script is a Cadence‘s proprietary scripting language for simulation automation. For analog designer, OCEAN script is quite useful for collection of simulation data which can be used to determine circuit’s performance with variations in environment or fabrication process. Furthermore, it is also handy when you try to optimize the design’s performance by varying a set of design parameters.

Before we take on serious scripts which can run dozens or even hundreds of simulations automatically, let’s start small with below script. Please save it as “helloWorld.ocn” in your home directory “~/”.

1
2
3
4
5
6
7
; This is a comment line.
; The comment starts from character ";" and ends at the end of the line.

; Output file definition.
out = outfile("~/helloWorld.txt" "w")
fprintf(out, "Hello World\n")
close(out)

I think the code is fairly self-explanatory and you may find that it would do nothing except creating a file in your home directory “~/” named “helloWorld.txt” whose content is just a string of “Hello World”.

The next step is to run just created script to see if it does as intended. To do this, go to the Command Interpreter Window (CIW), it’s the very first window shows up once you launch Cadence design tool. Then, type in a run command of

load "~/helloWorld.ocn"


and hit “Enter”.

Command Interpreter Windows and the console for Ocean Script run command.Modified from source.

Go to your home directory “~/” to check whether file “helloWorld.txt” is created with content of “Hello World” string. If so, congratulations on your first Ocean Script success!

More to come.

PS: File access ability is quite important in OCEAN script. This is due to the fact that, for each simulation, we would usually calculate specifications of the evaluated circuit and print them into a text file for the record, instead of to plot all the resulted curves of each specification.
Assessment based on text data is just much easier, that’s all.