http://sourceforge.net/projects/ngspice/ (under FreeBSD 4.5)
http://www1.linear.com/software/ (SwitcherCad for Windows)
I needed an IBIS to Spice translator, and had located a free one at
the Intusoft web site. This is also a tool that runs under Windows...
http://www.intusoft.com/utilities.htm (IBIS to SPICE converter)
Finally, for completeness, you can convert the SPICE deck back to IBIS
using the NCSU "S2IBIS2" package. In theory, this should give back the
original IBIS file (but it doesn't...)
http://www.eigroup.org/IBIS/tools.htm (pointer to tools)
http://www.eda.org/pub/ibis/s2ibis/s2ibis2_v1.1 (the two files)
The IBIS spec is available at:
http://www.eigroup.org/IBIS/specs.htm
********************************************************************
There have been a couple of requests over the years, as to how to
translate the output of the Intusoft IBIS2SPICE tool, so it can run
under Spice. Spice doesn't have the if-then-else clause used by
IBIS2SPICE, so I had to find another way to input a piecewise
linear data table into Spice. I started with unit step functions,
as they could switch on y=ax+b equations over the appropriate
interval.
When I first tried using unit step functions, I had syntax problems
which would cause both of the above Spice programs to hang in a
loop. I decided to try fitting a mathematical function to
the data instead -- to keep a long story short, the fitting method
wasn't successful, as the curve fitting I tried didn't have a low
enough error compared to the original data. (I tried a high order
Chebyshev polynomial basis set and also a rational P(x)/Q(x)
polynomial fit and both were bad, but for different reasons.)
Eventually, I added a few printf's to ngspice, to determine where in
the three pass parser that Spice was hanging. It turned out that
the current Spice parser doesn't like (a + -b), but does like
(a - b). So, a unary minus is not handled properly. Once I tracked
this down, the rest of the conversion was straight forward.
I've written an awk script that encapsulates the changes needed to
go from the Intusoft IsSpice acceptable format to Spice 3F5
acceptable format. Here is the script entitled "i2sfix.awk". Lines
with a # are comments -- you can snip these if you wish.
Note: I've only tried this with a 3.3V CMOS I/O. I don't know exactly
how many different I/O types the Intusoft tool supports, so other I/O
types are left as an exercise :-)
#****************************** i2sfix.awk *****************************
#
# Intusoft has graciously provided a free tool for converting IBIS
# models back to spice-like form. The "template.mdl" file provided
# with the tool is supposed to be customizable to work with any Spice
# but there are some limitations. There are two options in the
# ibis2spice, to format the power_clamp, gnd_clamp, pullup, and pulldown
# characteristics, and neither option is directly useful in Spice 3F5.
# This awk script finds "chunks" of these piecewise linear tables
# and replaces them with unit step functions. (Select "Option2" in
# the ibis2spice format pulldown.) My efforts have concentrated on
# ngspice (Spice 3F5 based), so I don't know if this will work in 2G6.
# Tested with version 1.4 of ibis2spice (see their Help:About menu).
#
# To use:
# 1) ibis2spice - generate blah.lib from blah.ibs
# select the option that generates lines like
# + (V(1,2) < -3.300 ) ? 1.000n * V(1,2) + -1.286 :
# + (V(1,2) < -3.200 ) ? 540.000m * V(1,2) + 496.000m : ; -3.200 -1.232
#
# 2) Find a copy of awk and execute
#
# awk -f i2sfix.awk blah.lib >blah.fix
#
# 3) Use .include blah.fix in the spice deck, to make the blah subcct
# available for simulation.
# 4) I recommend setting up the test load for the golden
# waveforms in the original blah.ibs and compare the
# waveforms with those obtained from the translated
# model. You may want to adjust the ramp generators RTR / RTF
# to get the rise/fall times listed in the original ibis file
# as the 20% to 80% time.
#
# Note: This conversion script modifies the Intusoft design intent
# slightly. The IBIS standard says only one of XPULLUP or XPULLDOWN
# should be turned on at any one time, so I added an enable pin to
# each model. This turned out to make a difference, only if the
# original model data didn't pass through (0,0). So, for good models,
# this doesn't do anything. Also, I replaced V7 with E7, to isolate
# the switching current from the ramp generators from the output --
# again only theoretically necessary.
#
# PN: June 10, 2002.
BEGIN {
# Please excuse my crappy awk scripting! I'm pretty rusty.
# a_chunk_line is 1 when a piecewise linear table entry is found
a_chunk_line = 0
# in_chunk is 1 when we're somewhere in the middle of a table
in_chunk = 0
# Bracket balance for PULLUP and PULLDOWN
extra_closing_bracket = 0
}
# computed boolean - 1 if matches the first three fields of...
#+ (V(1,2) < 900.000m) ? 27.300m * V(1,2) + 11.270m : ; 900.000m 35.840m
# Done here, as this is common to chunk processing
{ a_chunk_line = ( $1 == "+" && $2 == "(V(1,2)" && $3 == "<" )
# Note: The following adds a space between 900.000m and the ")"
if ( a_chunk_line == 1 ) {
gsub( "m)", "m )", $0 )
}
}
# No case statement in awk, so if-then-else
{ # Simple translations from Intusoft IsSpice to Spice3f5
if ( $1 == "*DEFINE" && $2 == "{RTF}=" ) {
rtf = $3
} else if ( $1 == "*DEFINE" && $2 == "{RTR}=" ) {
rtr = $3
} else if ( $0 == "B1 820 0 V=V(100) & V(500)" ) {
print "* Unit step functions replace the original syntax"
print "B1 820 0 V=2.4*U( V(100)-1.2 )*U( V(500)-1.2 )"
} else if ( $0 == "B2 830 0 V= V(500) & ~V(100)" ) {
print "B2 830 0 V=2.4*U( V(500)-1.2 )*U( 1.2-V(100) )"
} else if ( $1 == "B3" ) {
# B3 300 850 I= V(830) > 1.2 ? 0 : V(300,850) / {RTR}
print "B3 300 850 I=U( 1.2-V(830) )*V(300,850) / " rtr
} else if ( $1 == "B4" ) {
# B4 840 400 I= V(820) > 1.2 ? 0 : V(840,400) / {RTF}
print "B4 840 400 I= U( 1.2-V(820) )*V(840,400) / " rtf
} else if ( $0 == "XPULL_DOWN 2 400 8 840 PULL_DOWN" ) {
print "XPULL_DOWN 2 400 8 840 830 PULL_DOWN"
} else if ( $0 == "XPULL_UP 3 300 850 8 PULL_UP" ) {
print "XPULL_UP 3 300 850 8 820 PULL_UP"
} else if ( $0 == "V5 6 5 " ) {
print "V5 6 5 DC 0.0"
} else if ( $0 == "V6 8 6 " ) {
print "V6 8 6 DC 0.0"
} else if ( $0 == "V7 220 8 " ) {
print "* Using E7 to isolate S1/S2 switching noise from node 8"
print "E7 220 0 8 0 1.0"
} else if ( $0 == ".SUBCKT PULL_UP 3 4 1 2" ) {
print "* Added enable signal to PULL_UP model"
print ".SUBCKT PULL_UP 3 4 1 2 5"
print "* Connections Out+ Out In+ In Enable"
getline
} else if ( $0 == "BPULL_UP 3 4 V=" ) {
print "BPULL_UP 3 4 V=U( V(5)-1.2 )*("
extra_closing_bracket = 1
} else if ( $0 == ".SUBCKT PULL_DOWN 3 4 1 2" ) {
print "* Added enable signal to PULL_DOWN model"
print ".SUBCKT PULL_DOWN 3 4 1 2 5"
print "* Connections Out+ Out In+ In Enable"
getline
} else if ( $0 == "BPULL_DOWN 3 4 V=" ) {
print "BPULL_DOWN 3 4 V=U( V(5)-1.2 )*("
extra_closing_bracket = 1
} else if ( $1 == ".ENDS" ) {
extra_closing_bracket = 0
print
} else if ( a_chunk_line == 1 && in_chunk == 0 ) {
# + (V(1,2) < -3.300 ) ? 1.000n * V(1,2) + -1.000m :
# First line of a table. Only needs one unit step to handle
# less than or equal to this voltage. Intusoft adds this
# entry to define voltages outside the defined range.
in_chunk = 1
# Spice hates unary - and + !
if ( substr($11,1,1) == "-" ) {
sub( "-", "", $11 )
$10 = "-"
}
printf("+ U( %s-V(1,2) )*( %s%s%s%s%s )\n",
$4, $7, $8, $9, $10, $11)
# Now, remember the voltage limit used,
# for lines other than the first or last of a chunk.
lower_v = $4
} else if ( a_chunk_line == 1 && in_chunk == 1 ) {
# + (V(1,2) < -2.500 ) ? -500.000u * V(1,2) + -2.050m
sign = "-"
if ( substr(lower_v,1,1) == "-" ) {
sub( "-", "", lower_v )
sign = "+"
}
if ( substr($11,1,1) == "-" ) {
sub( "-", "", $11 )
$10 = "-"
}
# 2nd to n-1 th line case.
# The first of two plus signs is the "continuation" character.
printf("++ ( U( V(1,2)%s%s )+U( %s-V(1,2) )-1 )*",
sign, lower_v, $4)
printf("( %s%s%s%s%s )\n", $7, $8, $9, $10, $11)
lower_v = $4
} else if ( a_chunk_line == 0 && in_chunk == 1 ) {
# last line of a chunk. Intusoft adds this entry to define
# voltages outside the defined range (a good thing).
# + 1.000n * V(1,2) + -1.300
sign = "-"
if ( substr(lower_v,1,1) == "-" ) {
sub( "-", "", lower_v )
sign = "+"
}
if ( substr($6,1,1) == "-" ) {
sub( "-", "", $6 )
$5 = "-"
}
printf("++ U( V(1,2)%s%s )*( %s%s%s%s%s )",
sign, lower_v, $2, $3, $4, $5, $6)
if (extra_closing_bracket == 1) {
print " )"
} else {
print ""
}
in_chunk = 0
# invalidate lower_v - this value should never be printed
lower_v = "FIX_ME"
} else { # for all other lines, just print them
print
}
}
#************************** end i2sfix.awk *****************************
(I placed a PostScript picture in a second post. This text description
is with respect to the picture, so convert the "part 2" post before
reading this...)
I understand some of this model, but not all of it. The model starts in
the upper right corner. Two logic gates (emulated with unit step
functions), turn on the upper or the lower half of the driver circuit.
The rise and fall times of the model are controlled by the ramp
generators (upper and lower left corners of the figure).
Before a 0 to 1 transition, switch S1 is closed, which causes node 850
to be at 0.0 volts. When the INPUT changes from 0 to 1 (and ENABLE is
asserted), switch S1 releases, and the B3 switched resistor is turned
on. B3 pulls the lower side of capacitor C1 to the plus rail, with time
constant RTR*C1 (parameter RTR is the rise time in the IBIS file).
When the ramp reaches the positive rail voltage, the XPULLUP applies
the full value of the lookup table inside it. The "force" applied is
a function of how much difference there is between the current output
voltage (node 8) and the voltage the driver is trying to make (the
logic 1 provided by node 850). When the driver output (as seen at node
8) reaches the positive rail, XPULLUP stops requesting more drive.
The PULLUP drive consists of several conversion steps. The input to
XPULLUP is effectively Vtable = VCC-Voutput, and since XPULLUP is a
VCVS (voltage controlled voltage source), a voltage is produced which
is referenced to the positive rail. This, in turn, is applied to
VCCS (voltage controlled current source) G2, which has a 1:1 gain. If
XPULLUP outputs 1 volt, then G2 will output 1 amp. Now, the curious
part is the role of resistors R1 and R2. Instinct says they are being
used to convert from current to voltage (as if a voltage source is
desired as the output characteristic of the driver). By using S2IBIS2,
the proper output impedance characteristic is seen, looking into this
network (because it is the slope of V versus I that counts, as opposed
to the instantaneous value). However, be aware that if you are using
node 300 to monitor power consumption, you will find too much current
flowing into this node.
I tried constructing my own driver, by using a B element to place a
non-linear resistance between the positive rail and the output node,
and the output waveform had the right shape, but it had small
stairsteps along its edge. So, the voltage-current-voltage chain used
by Intusoft has more merit than going directly with a non-linear
resistor.
Another question is the design of the ramp generator. To me, the shape
of the ramp is arbitrary. Intusoft chose an RC charging curve, whereas
I would have chosen a linear ramp (which can be achieved with
a switched constant current source into a capacitor). A linear ramp
would at least make it easier to adjust the subcircuit to get the
correct value of rise/fall times. I don't think the IBIS spec defines
how PULLUP or PULLDOWN turn on.
Voltage sources V7, V6, and V5 are zero volt sources, used to allow
Spice to monitor the current flow. The XPWRCLAMP and XGNDCLAMP are
non-linear resistors which are always enabled, and these give the
clamping characteristic of the input gate ESD protection diodes.
************************************************************************
Miscellaneous notes:
Software issues:
1a) ngspice:
The LTRA transmission line doesn't work in ngspice-rework14. Since
I don't understand all the matrix stuff/time steps/Newton-Raphson in
Spice, I don't know exactly why. What I notice is that someone has
removed some heuristic time stepping cruft from the original code and
replaced it with a simplified approach. The observed symptoms are that
at the propagation delay time of the line (24 inches would be roughly
4.4ns), I get a "time step too small" error. I can change the PULSE
source delay from the shown value of 1ns, and the time step error
still occurs at 4.38ns. Here is a test deck (that works in
SwitcherCad). This test is of a matched series damped termination
into a transmission line. It should give a delayed and correct
amplitude signal at the output node 3.) Placing loads on the output of
the transmission line doesn't help. The option method=gear usually
helps with time step too small problems.
From ltra_1.cir of Spice3F5, simplified, 24inch lossy line
.options method=gear
v1 1 0 pulse(0 4 1ns 1ns 1ns 20ns 40ns)
rseries 1 2 50
o2 2 0 3 0 lline
.model lline ltra r=0.2 g=0 l=9.13e-9 c=3.65e-12 len=24 truncnr
.save v(1) v(2) v(3)
.tran 0.01ns 60ns 0 0.1ns
.end
doAnalyses: TRAN: Timestep too small; time = 4.3812e-09,
timestep = 1.25e-22: cause unrecorded.
1b) ngspice:
Parser has a few problems. Firstly, for B models, if there is a syntax
error, ngspice will hang without printing any details about the error.
In particular, expressions of the form (a + -b) cause problems. To
debug this, I added printf statements to inppas1.c, inppas2.c, and
inppas3.c, to identify where the hang might be occurring. I changed
the source deck to suit the parser.
1c) ngspice:
Include files don't work. If you place ".include blah.lib" in the main
.cir file, the program complains about freeing some pointer. This
turned out to be an uninitialized pointer in inpcom.c. The fix was
"copys = NULL" just before "if (*s == '~')".
2a) s2ibis2:
The program had trouble creating the golden waveforms for the IBIS
file. Turned out that it was duplicating its own dummy node names.
In s2ispice.c, around line 2137, there are some references to
nodelist[]. There is a potential order of evaluation problem, as
"nodelist[nodeIndex]" and "nodeList[++nodeIndex]" appear in the same
line. I changed the second one to "nodeList[nodeIndex+1]" and did
the increment in a separate statement. There are multiple lines
like this.
s2ibis2 also has some strange ideas about data reduction. The IBIS
standard says that tables should have 100 or fewer entries. s2ibis2
removes data points from the table according to its own definition
of "interesting" areas of the curve. This is dangerous, because it
assumes that no one will be using a novel pad design. This is why
some commercial IBIS files are missing data between -1.0 and -1.5
volts. If you are making IBIS models professionally, I'd consider
taking this clever code out. Similarly, there are comparisons to
"clamptol" and the like, for current values in V/I tables. Why
not just leave the data points alone, in the form they were
delivered from the spice simulation? Changing the data can
affect the following test...
Right now, if I use IBIS2SPICE, followed by s2ibis2, I don't get
back the original driver impedance characteristic. I'm not sure
the IBIS standard is rigorous enough to pass this test. Maybe
someone who has access to HSPICE can test s2ibis2 against the
HSPICE built-in IBIS conversion method, to see if it is possible
to get back an IBIS model with the same drive strength.
(When downloading the source, there is a fix file as well, which
has a replacement source file. Do "make depend" and "make sun4"
if using FreeBSD. You may also want to set YACC=yacc.)
3a) Switchercad:
I'm getting the occasional internal error from this program, while
running a converted ibis subckt along with a length of LTRA
transmission line. The message is "internal error #62 - read 20480
expected 22876". I'm using version 1.12j. The workaround is to
restart the program and try again. The output of the LTRA model
reminds me of stuff I was seeing 10 years ago -- it is not the
same as Hspice and seems too pessimistic when it comes to
reflections. So, the final hurtle to a free simulation environment
is finding a better transmission line model. (Some suggests of how
to do this can be found in the ltra test circuits in the examples
directory of the Berkeley 3F5 package.
See ftp://ic.eecs.berkeley.edu/pub/Spice3/sp3f4.kit.tar.Z which
contains these examples. I haven't tried the alternatives yet.)
Enjoy,
Paul
Hey this is nifty. This should allow anyone to download the IBIS models
from any vendor, convert to spcie .model statements, and then simulate it in
spice.
Sounds like you did this for 3.3V driver model.
Do the free versions of spice support the simple transmission line model?
Austin
Simulators based on Spice 3F5 have a lossless model (Txxx) and the lossy
model ltra (Oxxx). The lossy model is not perfectly general and cannot handle
the setting of RLCG at the same time. You can do an RLC based model, setting
G=0. I guess I was spoiled by HSPICE, as it is going to take me a long time
to create a model and parameters that look right. The alternative is to
construct a model based on lumps, where you can do anything you want. In
the past, I've heard of one individual who characterized a conductor in a
test board with a network analyser, then mathematically fitted a ladder
network of components to match that characteristic. This is certainly
beyond my capabilities. Such models have extended simulation times, due
to the large number of passive components involved.
If you examine the three files ltra_1.cir, ltra_2.cir and ltra_3.cir in
the Spice package ftp://ic.eecs.berkeley.edu/pub/Spice3/sp3f4.kit.tar.Z
you can see how both approaches can be constructed.
I guess even with all this "free" software, there still is no free lunch.
Paul
Something else.
Maybe some of you out there can help me. I'd like to compare the Intusoft
converted Spice model against a real Spice model. The Philips web site
is the closest I've come, to finding commercial device models in both
IBIS and Spice form. Unfortunately, the Philips Spice model for LVC32
devices uses a LEVEL=3 MOS model and the channel is 0.8u. The Spice 3F5
level 3 code computes Leff and Weff and checks to see if they are smaller
than 1.0u, so this model won't run in Spice. This is the closest I've
come to having models of both that I can use to compare Spice with
translated IBIS.
http://www.philipslogic.com/support/ibis/
http://www.philipslogic.com/support/ibis/lvc32/ibs/lvch32244a.ibs
http://www.philipslogic.com/support/spice/lvc32.zip
Does anyone know what valid changes I could make to these
models from the LVC32 Spice files ? Here are the transistor models
and a couple of instances of them, from the lvc32.zip collection.
************************************************
* NOMINAL N-CHANNEL TRANSISTOR *
* UCB-3 PARAMETER SET *
************************************************
.MODEL MNEN NMOS
+LEVEL = 3
+KP = 154E-6
+VTO = 0.57
+TOX = 15E-9
+NSUB = 7.8E16
+GAMMA = 0.70
+PHI = 0.65
+VMAX = 187E3
+RS = 7.5
+RD = 7.5
+XJ = 0.26E-6
+LD = 0.11E-6
+DELTA = 1.89
+THETA = 0.072
+ETA = 0.043
+KAPPA = 0.0
+WD = 0.0
***********************************************
* NOMINAL P-CHANNEL TRANSISTOR *
* UCB-3 PARAMETER SET *
***********************************************
.MODEL MPEN PMOS
+LEVEL = 3
+KP = 63.7E-6
+VTO = -0.67
+TOX = 15.0E-9
+NSUB = 6.0E16
+GAMMA = 0.84
+PHI = 0.65
+VMAX = 1.0E6
+RS = 10
+RD = 10
+XJ = 0.30E-6
+LD = 0.04E-6
+DELTA = 2.88
+THETA = 0.189
+ETA = 0.091
+KAPPA = 0.0
+WD = -0.03E-6
Here are a couple of transistors using these models.
MP1 3 4 50 50 MPEN W=150U L=0.8U AD=220P AS=400P PD=175U PS=175U
MN3 3 4 60 60 MNEN W= 70U L=0.8U AD= 80P AS=170P PD= 80U PS= 80U
Thanks,
Paul
Good news about tline support. Without it, it would be useless. You even need it
to model the packages themselves, as using a single RLC pi network for the package
can be false and misleading (usually is) at the edge rates we run at now. Lossy
lines are useful if you have to go more than about 6" (100 mm).
We routinely do a QA check comparing the spice models with the IBIS models here at
Xilinx. There is some small differences right before and at the over shoot and
undershoot probably mostly affected by the t-line models used, and other
idosyncrasies of the simulators, but in the switching region, and in terms of the
overall results, they are close enough for signal integrity work. Because the
silicon can be fast or slow, or anywhere inbetween (short poly, wide poly, strong
nmos, strong pmos, etc etc etc), the actual results will vary much more than
comparing two simulators.
Some things spice is more useful for are things like ground bounce (lifting
ground, inserting impedances, modeling power return paths), and examining eye
patterns for psuedorandom data patterns (although some high end IBIS simulators
can do this too). Also modeling a 3.3V driver into a 2.5V input (some IBIS
simulators do not allow more than one Vcco).
I have had folks call and demand why the 90% point is different by 3 mV between
spice and IBIS. They have missed the point entirely of SI engineering, where a
SWR of 2:1 is supposed to be good enough to work under all corners. Is it?
Recently a customer called and asked why the IO didn't work the way it did in
simulation. I simulated it, and the simulations matched their pcb pictures
perfectly! They had done the simulations, and never notcied the drive strength
was too weak (duty cycle was 40/60), and then wondered why the eye pattern was so
bad. Running the simulation is only the first step. Then you must examine it to
see what you get, and think about what the simulation is telling you.
Slow corner? Duty cycle distortion? Rise and fall times? Fast corner? All of
the same? What effect will this have on data signals? Eye patterns? Clock
signals? Since IBIS (and spice) does not take care of ground bounce (not without
extra modeling work with spice anyway), what effect will bounce have on the
signal?
Austin