Introduction

I had been working on a pulse-width-modulation (PWM) design. It was a pseudo-digital implementation, in that the output was clocked by a high-speed clock. The actual switching rate was much lower than this clock. I wanted to simulate this design in Cadence/Spectre by running a transient and then taking an FFT.

However, I ran into a bit of a snag: the quantization clock and my input clock rates were defined by the design, and they weren’t up to me. Moreover, these weren’t related by a power of 2. Unfortunately, Cadence Ocean (Skill) commands only allow for a radix-2 (power of 2 length) FFT. So, I was stuck. I needed a way to do a non-radix-2 FFT in Cadence. Here’s how I solved it using Matlab and getting Cadence and Matlab to talk (in a limited fashion).

What I ended up doing was writing some Skill IPC (inter-process communication) code that:

  1. Dumped the time-domain data to a text file on disk (in Cadence/Skill)
  2. Read the time-domain data using Matlab
  3. Perform the FFT (in Matlab)
  4. Write the frequency-domain data to a text file (in Matlab)
  5. Read the frequency-domain data (in Cadence/Skill)
  6. Plot FFT and compute SNR/SNDR (in Cadence/Skill)

The scripts

These files are copyright Poojan Wagh, 2009. They are released under the GPL. See http://www.gnu.org/licenses/gpl.txt.

These files come with absolutely no warranty, expressed or implied. Use at your own risk. If these scripts destroy your entire design database, that’s your fault for using them.

The Ocean Script

Here’s the ocean script I used. It’s called text.txt, because it is actually contained as a cell-view (text file type). Here’s a run-through of the code:

I’ve defined runscript() as a function which loads and executes a text-file cell-view.

library, cell, view, proc (typ/wcs/bcs), etc. are all defined as skill variables for easier changing & for future corner simulation

In case we want to use LSF for load-balancing

WORKAREA_DIR is the area where cadence is started. The PWM dump-out file will be in a mattfft subdirectory of it.

runit determines whether we run the simulation or just plot the FFT/SNR/SNDR. plotpsd determines if we plot the power spectral density (PSD) or not (mostly for debugging).

inputmag is how high of an input signal we are sending to the PWM modulator. fR is the switching rate. fQ is the sampling rate. Note that fR=36*fQ, so this we don’t want a radix-2 FFT. Doing a radix-2 FFT would result in spectral leakage (and corrupt our SNR measurement).

I run the simulation for a total of $$\over{ncyc+kcyc}{fR}$$ cycles of fR. However, I throw away the first kcyc cycles to allow for startup transients.

This (above) is a little wrapper skill function that sends a command to Matlab. I made it so that it also displays the command being executed in Cadence (for debugging).

The following function computes the PSD by sending commands to Matlab

You’ll notice that the skill variables are actually sent to matlab, not hard-coded anywhere. So, changing the variable assignments in the skill/ocean file will be reflected in Matlab. Several Matlab helper functions are used:

  • readpwm reads the text file
  • getpsd computes the psd
    • bh4 defines a minimum 4-term blackman-harris window; when I wrote this script, it was not available in Matlab

Each of these Matlab .m files are included in the attached tarball. In addition, I define a few Ocean/Skill helper functions:

sumpsd sums up spectral power over a frequency range (fstart to fend):

getpow gets the spectral power of a tone centered at fc and takes into account spectral growth around fc by speclobew bins of the FFT:

Define simulator, output directory, etc:

In case we want to use LSF for load-sharing:

Define the test bench cell to be simulated (in read-only mode):

Define model files. Note that the proc,cap, etc. Skill variables are used:

Define the simulation time and analysis options:

Define design variables. Note that these are assigned from the Skill variables, so changing just the skill variables at the top of the file propage down through the design netlist and into matlab

UltraSim simulation options:

Actually run the simulation:

Dump out the time-domain file:

Compute the PSD through Matlab

I use vim 🙂

ReadPWM

This little matlab function reads the text file and assigns variables in Matlab:

GetPSD

This matlab function gets the PSD from the time-domain data:

Note that it also does the limiting function (using only the last psdlen values in the time-domain data).

BH4

Minimum 4-term blackman-harris window:

The Tarball

All the above scripts are contained matfft.

IPC

All of the above was done using Cadence IPC. This is basically a set of functions that let you remote-control another command. The standard input/output (stdin/stdout) of the child process is connected to the Cadence instance. Using ipcReadProcess in Cadence reads the child’s stdout. Using ipcWriteProcess writes to the child’s stdout. In theory, one could run any Matlab program from Cadence using this method.

However, one could read/write to any text-mode program using this method. For a while, I thought about using FFTW and coding a small C program to compute the above FFT’s. The same C program could be controlled using IPC. However, I wasn’t getting paid to program (at the time), and I already had most of the functions already in Matlab.