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. ==================================================================== ====================================================================