This section is a first cut at documentation. If you actually want to install a model, please ask for more information. Your questions will help me write the more complete documentation. (aldavis@ieee.org)
To create a model using this method, you create one file, with the extension .model. A separate program, modelgen processes this file to generate the appropriate .cc and .h files. The resulting files are equivalent to the subcircuit method of creating models.
There are two primary sections, device and model. Most models have both, but a device can use several different models as long as they are derived from a common base and designed to work together. It is standard practice to share like this. For example, all of the MOS models use the same device section.
Any model can inherit from another model, thus reducing the need for repetition when code or parameters are the same in different models, and allowing several to use the same device section.
This model compiler has restrictions that will be removed in future releases. Not all device types can be fully done with it, due to missing features. Often, it is necessary to finish the job manually. In this release (0.30), the diode fully uses it, but not the way I want to. The MOSFET uses the cc_direct to finish the job. Two functions do_tr and tr_needs_eval must be provided this way. Code placed here is simply copied out.
As a general rule, when using the name = value form, the value is delimited by whitespace, or possibly other tokens. If you want blanks in the value string, put it in quotes. It is recommended to quote any value string that is comprised of more than one word, even if there are no blanks.
The circuit subsection has 5 parts, in order.
Each local node may have two optional attributes:
The required fields, in order, are:
After that, optional fields are used to assign attributes. Not all are legal or appropriate with all element types.
The tr_probe subsection is where you list the probes for transient and DC analysis. It is a list of name = value pairs, where the value is an expression that calculates or looks up the value.
You can reference any device parameter directly, or others with the appropriate struct prefixing.
You can reference probes on internal elements with the syntax ``@'', followed by the element label, followed by the probe name in square brackets. For example, ``@Cj[Capacitance]'' refers to the probe named ``Capacitance'' on the element ``Cj''. It is your responsibility to see that the element actually exists, and that it has a probe with that name.
You can reference node voltages with the same syntax, but the ``device'' name is formed by prefixing the node name with ``n_''.
You can also call functions, and make arbitrary expressions. In general, the code is just copied over, with the exception of the probes, which are modified to the internal format.
The probe name in the generated model will be non-case-sensitive. To the model compiler, upper case letters must match exactly, and lower case letters are optional. For example, ``CGSOvl'' in the model file can be referred to as cgso, cgsov, or cgsovl, or any variants differing only in case.
This subsection defines information that is not shared between instances. In general, that which must be maintained as different, even though devices are identical, is placed here.
This subsubsection lists all of the ``calculated parameters''. In this case, it means that which is calculated during simulation, the state information.
The format for each item is: type, name, comment, attributes, semicolon.
The only attribute appropriate is ``default'', which is the default value set by the constructor.
This section defines information that the simulator may share between instances. Most parameters specified by the user are placed here, allowing the simulator to share data for identical devices.
You can designate one of the raw_parameters to be the ``value''. When a number is given without a name, it is assigned to this one.
This subsubsection lists all of the ``raw parameters'', the parameters supplied by the user on the instance line. The format and available attributes are described in the ``Parameter lists'' section, which follows.
This subsubsection lists all of the ``calculated parameters'', the parameters not supplied by the user on the instance line. Instead, the are calculated based on other input. The format and available attributes are described in the ``Parameter lists'' section, which follows.
In this release, this section is a dummy. Put a stub here if you define a do_tr later. Otherwise leave it out. This will change in a future release.
The eval sections are evaluators that turn the primitive resistors and capacitors into advanced behavioral elements.
The body is the core of a C++ function, which is copied over directly after attaching some headers. Given some ``x'', this function computes ``f(x)'' and its derivative with respect to x. The primary communication is through the structure ``d->_y0''. The input is ``d->_y0.x''. You must evaluate the function, and place the result in ``d->_y0.f0'' and its derivative in ``d->_y0.f1''. The exact meaning of these values depends on what type of element it is.
For the primitives ...
In addition, all relevant parameters are available with the appropriate prefix. See the section accessing data in code blocks. Most are read-only.
The prefix d-> refers to the element being processed. This data is read-write.
The keys subsection consists of a number of keywords that are used in the .model statement to identify this model. Different keys can be used to represent variants, such as ``NMOS'' and ``PMOS'' to represent the N and P channel devices. Each one is followed by an assignment to be made when the key is present.
It is required, at least once in the hierarchy. Additional keys can be used to select a particular model, as an alternative to the level parameter.
The independent subsection list all of the ``independent'' parameters supplied by the user in the .model statement.
This subsubsection lists all of the ``raw parameters'', the parameters supplied by the user on the .model line. The format and available attributes are described in the ``Parameter lists'' section, which follows.
This subsubsection lists all of the ``calculated parameters'', the parameters not supplied by the user. Instead, they are calculated based on other input. The format and available attributes are described in the ``Parameter lists'' section, which follows.
This subsubsection lists parameters that have already been defined in base classes, that need a change for this particular type. You can override most attributes, giving the benefit of defining it locally, while retaining most from the base. The format and available attributes are described in the ``Parameter lists'' section, which follows.
These subsubsections define C++ code that is inserted into the function that calculates values, scales, and checks limits. The block code_pre is inserted before the automatically generated code. The block code_post is inserted after the automatically generated code.
The size_dependent subsubsection is similar to the independent subsubsection except that it defines a base paramater and scale factors so a custom value can be generated based on the device size.
Every parameter in this subsubsection actually generates a set of four. The first is the base, as in the independent subsubsection. In addition, the same name prefixed by ``L'' is the length dependency, the name prefixed by ``W'' is the width dependency, and the name prefixed by ``P'' is the product (length * width) dependency.
You must provide a code_pre section, which must declare and define values for ``L'' (length) and ``W'' (width).
The actual value is calculated by: nom + ld/L + wd/W + pd/(W*L);, where nom is the nominal value, ld is the length dependency (key name has the ``L'' prefix), wd is the width dependency (key name has the ``W'' prefix), and pd is the product dependency (key name has the ``P'' prefix).
The temperature_dependent subsubsection contains a list of parameters that are calculated based on temperature, and two code blocks (code_pre and code_post to make the calculations.
This code is evaluated at run time, possibly every time step, whenever temperature changes. Some Spice models throw calculations not related to temperature into the temperature block. This is very bad practice. In Gnucap, temperature is local and time variant.
The tr_eval subsubsection is the actual model evaluation code for nonlinear DC and transient analysis. This code must calculate all state variables (data listed as ``calculated'' in the device section, except those that are part of one of the subcircuit elements. Inputs and outputs are through the d-> structure.
This function only needs to fill in the calculated data. The details, like differentiating charge in capacitors, is left to the subcircuit elements. It is also not necessary to check convergence. This, too, is left to the subcircuit elements.
Most parameters are available, usually read-only, in any code block, with the appropriate prefix:
The format for each item is: type, name, comment, attributes, semicolon.
The available attributes are: