Generating Corners for ADE-XL with Python

I’ve been using ADE-XL to run corner simulations lately. I like that it lets me set up a specification for simulations (AKA a scoreboard) and then runs through different corners. And it supports distributed or parallel computing.

But getting things like corner definitions in there is difficult. You’d have to hand-enter them. Luckily, Cadence allows you to load these definitions from a CSV file or an XML format they call SDB.

The CSV file is pretty useless. The reason is that each corner entry is another column in the file, not another row. This is the transpose of the way everyone else does CSV files—where a row is another record, and the columns are the fields in that record.

But, with some use of Python’s etree XML capabilities, you can get the SDB file to work pretty easily.

Here’s a sample script that takes a sample SDB file (which you can export from ADE-XL) and then adds multiple corners.

The first section makes all the different corner combinations of process, voltage and temperature. As a small tangent, I also constructed all the process corners themselves (slow/fast NMOS, slow/fast PMOS, etc).

Posted in Analog Professional | Tagged , , , , , | Leave a comment

Read CSV files as a Matlab struct array

I like CSV files for their portability (Python, Excel), ease of debug, and lightweight nature (no SQL databases etc). However, one key aspect of CSV files is that they are column-oriented–that is, you have to keep track of which data is in which column.
In python, csv.DictReader and csv.DictWriter do this for you–you don’t have to keep track of which data is in which column; the reader/writer does this for you.
I was looking for something similar in Matlab, so that I can read CSV files. In Matlab, the structure array is ideal for this, as it lets you create an array (one record per row) with structured data (one field per column).
The following file is something I wrote to read in CSV data. It returns a structure array, where the field names are given by a header line in the CSV file. It supports both numeric and string data in the CSV fields, with one caveat: all text-valued fields must occur contiguously and be the first columns in the file.

Posted in Analog Professional | Tagged , | Leave a comment

More updates to the CDSVN scripts

Our friend from Brazil (Nilton Jr) sent us the attached update last year: CDSVN. I’m just getting around to posting them now. I haven’t tried them out, but they are “customizations [they] made to [their] environment”.

Also, we got another contribution from Iou Bingyong: He says:

I’m in China and I have tried your script today . It works fine in IC615, great works!
I wrote a skill script to add the “Subversion” menu in schematic/layout editor. In this way the “menus” sub-directory is not needed and I think this should be a little easier to setup.

Posted in Analog Professional | Tagged , , | Leave a comment

Shortcut to plot relative to reference signal

Ocean/skill script follows. Select a net. Press ctrl-g. Now that net is your “reference”. Select a different net (or the same net if you are fond of trivial signals). Press ctrl-r that second net is plotted relative to the reference.

This is useful for debugging multiple supply domains, supply/ground bounce, and differential circuits.

procedure( relVT(netname)
VT(netname) – VTGND

procedure( selVT()
path = geGetAdjustedPath(wid strcat(geGetInstHier(wid) “/” car(geGetSelSet())~>net~>name))

procedure( setGnd()
path = geGetAdjustedPath(wid strcat(geGetInstHier(wid) “/” car(geGetSelSet())~>net~>name))
VTGND = VT(path)

procedure( plotSelVT()
let( ((sVT selVT()))

hiSetBindKey(“Schematics” “CtrlR” “plotSelVT()”)
hiSetBindKey(“Schematics” “CtrlG” “setGnd()”)

Posted in Analog Professional | Tagged , , , , , | Leave a comment

Cadence (awd) Waveform Colors

Hex & RGB values:
FF00000; (255,0,0)
01CC66; (1,204,102)
FFBFF2; (255,191,242)
FF8000; (255,128,0)

Posted in Analog Professional | Tagged , , , , | Leave a comment

Creating a Nyquist plot with Cadence

Cadence has a stability analysis that returns loop gain (return ratio). Typically, this is done using a log sweep of frequency. The reason is that doing a uniform linear sweep results in too large frequency steps for low frequencies and/or too large of a step for higher frequencies.

Unfortunately, when you do a logarithmic sweep, you can’t cover from negative to positive frequencies–which is what you want when you generate a Nyquist plot. With the code below, you can reflect the positive frequencies onto negative to get the full Nyquist plot:

; load “~/cadence/skill/”
lg = -getData(“loopGain” ?result “stb”)
; abConcatWaveforms externally defined
lg2 = abConcatWaveforms(flip(conjugate(lg)) lg)
w = newWindow()
ocnYvsYplot(?wavex real(lg2) ?wavey imag(lg2))
stb_x = xmin(abs(lg2-complex(-1.0,0.0))**2)
stb_margin = value(lg2, stb_x)
addTitle(sprintf(nil “stb_margin = %f dB” -dB20(stb_margin)))
xLimit( list(-1.6 0.2) )
yLimit( list(-0.5 0.5) )

You’ll need Andrew Beckett’s abConcatWaveforms function defined and loaded.

Posted in Analog Professional | Tagged , , , , , | Leave a comment

For loops in Cadence

If one is doing an analysis over a range of variables, one should use the paramAnalysis ocean function. That said, I’m constantly having to look up how to do a for loop in Skill. So, I’m placing a couple examples where I know I can get to them.

Read More

Posted in Analog Professional | Tagged , , | Leave a comment

Skill File I/O

I keep having to look this up, so I’m going to put it here for easy reference:

Open a File

h = outfile("new_file.txt", "w")
h = infile("existing_file.txt")
h = outfile("partial_file.txt", "a")

Opens new file for writing, existing file for reading, and partial file for appending, respectively.

Write to a file

write("Hello World!\n", h)
fprintf(h, "gm = %f", OP("/M23" "gm"))
print(OP("/M23" "gm"), h)
pprint(OP("/M23" "gm"), h)

Write “Hello World!” to a file (newlines are explicit); construct formatted string and write to file; print using native format to a file; pretty-print (useful for nested lists etc) to a file. File handle is h.

Read from a file

str = lineread(h)

Reads a single line as a string

Posted in Analog Professional | Tagged , , | Leave a comment