The new Ibis????

First cut at the language reference manual.
====================================================================
History

Ibis began as a way to model particular types of devices, for
interconnect simulators, in such a way as to allow the interconnect to 
be analyzed and simulated without disclosing much about the drivers
and loads.  It assumed a circuit topology, and supplied parameters for 
it.  In time, we have outgrown it, and it seems we are constantly
adding to the model.  Each change requires committee approval,
implementation in several simulators.  Meanwhile, the chip vendor
waits. 

Also, by doing it once, we have all learned how to do it better, but
we are stuck with a lot because of backward compatibility.
====================================================================
Summary

This proposal is for a macro language that hopes to provide a way for
vendors to make new topologies as needed, while at the same time
providing backward compatibility by defining the old spec in the new
macro language.

The macro language describes a circuit, Spice like, with parameters
and a little program logic.  The parameters refer to tables, values,
or formulas in a separate section, whose syntax matches the existing
Ibis "Model" and "Submodel" sections.  The language can be
pre-processed to produce a netlist type description suitable for
simulation in a nodal simulator with limited nonlinear capability.

A standard library of macro models is considered to be part of the
language, in the same sense that "printf" is part of C.  This standard 
library provides the functionality we now have, and is a base for
customization.

Most devices will use the standard library, which provides the
functionality of IBIS-3.  In time, more will be added as the need
arises for other basic model types.  Then a modified [Model] section
will fill in the values.  All of the currently pending "Birds" that
apply to the Model or Submodel sections can be represented in this
format, thus would require no committee action to use.
====================================================================
Definition of the language

A new section is added [Define Something], where Something is probably 
Model or Submodel, ending with [End Define Something].  The contents
is a list of elements and pseudo elements that could make a Spice
style netlist, with parameters.

The header line contains [Define Something] followed by a name of the
something to be defined, and its connection node list in parenthesis.

Example:
[Define Model] series (pin1 pin2)
   starts a definition of a model with model type of "series", which
has 2 connections: pin1 and pin2.

Elements to provide:
	Spice compatible:
		Resistor (R)	(defines v = f(i) or i = f(v))
		Capacitor (C)	(defines q = f(v))
		Inductor (L)	(defines flux = f(i))
		VCVS (E)	(defines Vout = f(Vin))
		VCCS (G)	(defines Iout = f(Vin))
		Isource (I)	(defines fixed I)
		Vsource (V)	(defines fixed V)
		Subckt (X)	(used for submodel, driver schedule)
	Extended, Spice like (available in some Spice's):
		Voltage controlled Resistance (VCR)	(defines R = f(v))
		Voltage controlled Admittance (VCG)	(defines Y = f(v))
		Voltage controlled Capacitance (VCCAP)	(defines C = f(v))
	Extended, beyond Spice:
		Trigger	(activates anything time dependent)
		Alarm	(sends a notice when something happens)
		Driver	(a complex device for backward compatibility)
	Note: all values can also be functions of time and temperature

Extended elements are specified by a "dot" line, which is optional for 
the basic lines, and allowed to provide a consistent syntax.

Basic syntax for simple elements:
	<label> (<nodes>) <value>
   or	<type> <label> (<nodes>) <value>

Example:
	R12 (2 4) 10k
	.resistor R12 (2 4) R=10k

The value can take on several forms:
	1. simple value (10k)
	2. scalar symbolic value (C_comp)
	3. built-in symbolic value (VT)
	4. 1d table symbolic (I=Pullup[V])
	5. 2d table symbolic (I=Pullup[V,T] or I=Series_mosfet[Vc,Vo])
	6. Expressions made of combinations of above.
		Operators are: +, -, *, /, || with usual bindings

Expressions must be simple enough to be evaluated once when the file
is read, producing a result which is one of the first 5 above.
Although the symbolic forms look like they could take arbitrary
arguments, only a few are allowed, depending on the basic type of the
element.  For example, a capacitor will always be either Q=something
or C=something, and the expression can only depend on its own voltage
(V), time, and temperature (TEMP).  Time could be the actual
simulation time or relative to a "trigger".

The or operator ( || ) allows multiple values to be specified, using
the first one that is valid and ignoring the rest.  This too is
evaluated once when the file is read.  The purpose is to handle
optional keywords.
====================================================================
Keywords

.alarm (<time value expression>)
This sends an alarm (some kind of notification) when some event
happens in the circuit.  It is intended to show conditions like
overvoltage or events to the user.  It is evaluated during simulation.

.assert (<static logical expression>)
This is a statement of a condition that must always be true.  It is
intended to be used as a check for errors in the [Model] section when
the structure is parameterized.  It is evaluated at "compile time".

.correlate
Defines a correlation for min and max values.  Syntax is one of:
.correlate key1/key2=min/max <value_keys>
.correlate key1/key2=max/min <value_keys>
.correlate key1=min <value_keys>
.correlate key1=max <value_keys>
<value_keys> is a list of value parameter names that could have
typ/min/max values.  Wildcards (glob format) are allowed and encouraged.

.define (<name> = <value expression>)
Defines (or redefines) a name to represent the <value expression> much 
like the #define in C.

.export
Defines a list of local symbols that can be visible outside the unit.
It is primarily used to show the state of a device to a user.

.if (<static logical expression>),
.elseif (<static logical expression>),
.endif
This corresponds to the #if family of preprocessor commands in C.  The 
condition is evaluated when the [Model] section is first encountered,
or at "compile time".

.inherit
This says to include or "inherit" another model or base as part of the 
one being defined.  It can be thought of as almost a text inclusion,
but in the case of multiple inheritance, if both base models include a 
common base, that common base is only included once.

.local
This declares node names to be local.  The purpose is to catch
errors.  All nodes must be declared, either as locals or by being
passed in as parameters.

.select (<value expression>),
.case,
.end select

.trigger (<time value expression>)
This generates an "event" when some condition is met, such as a signal 
crossing a threshold.  It can then be used to activate waveform
generators or anything that could be time dependent.
====================================================================
Expression evaluation

There are 3 types of expressions used here:
  value expression
  static logical expression
  time value expression
====================================
value expression:
The expression is evaluated at compile time to produce a scalar value or
table which is evaluated at run time.  A subexpression is considered
to be "true" if it can be successfully evaluated, which usually means
if all of the symbols are defined.  If a symbolic name is not defined, 
that section evaluates to false.  The actual result is not a truth
value, but a value that is used as a table or number.  The first
section that can be successfully evaluated becomes the value.  It is
an error if no sections can be successfully evaluated.

At least one section must be accepted (as defined) at compile time.

Certain values are used as flags:
  open: remove this component, leaving it open.
  short: remove this component, combining the out (first 2) nodes into 
a single node.

Example:
  TTpower * POWER_Clamp[-V] / VT || open
TTpower and VT are scalars.  POWER_Clamp is a table.  At compile
time, a new table is produced keeping the independent variable, and
substituting the result of evaluating the math expression for all
dependent variable entries.  The resulting table is the same size as
the POWER_Clamp table, and uses -V as the independent variable.
====================================
static logical expression:
The expression is evaluated at compile time to produce a truth value.
Any symbol not defined, or defaulted, evaluates to false.  A symbol
not defined is usually the name of a parameter or table in the [Model] 
section of the file.  A symbol defaulted is usually a connection to
the circuit block that is not passed in.
====================================
time value expression:

The expression is evaluated both at compile time and at run time, like
the value expression.  The compile time evaluation removes sections
that cannot be evaluated, like the value expression.  The run time
expression gives the time at which the logical expression becomes
true.

At least one section must be accepted (as defined) at compile time.

The value "never" can be used as the final test in case all sections
fail at compile time.  Any test that never happens returns the value
"never". 

Comparison operators are interpreted as follows:
a > b    the time a rises past b, or b falls past a
b < a    the same
a == b   the time a passes b, going in either direction

Example:
  (a > b || c < d || never)
Assuming all terms are defined, it returns the time that a exceeds b
or c becomes less than d, whichever comes first.  

If any of a,b,c,d are not defined, that term is dropped, so suppose a
is not defined, it becomes equivalent to:
  (c < d || never)

If a and c are both not defined, it becomes (never).

Example:
  (a > b || c < d)
This works the same as above, except for the case where a and c are
both not defined, which is now an error, at compile time.
====================================================================
====================================================================