SNL Fundamentals

Master the Simic Network Language: from file basics to TYPE and PART statements.

Network Description Files

Before any SIMIC simulation of a circuit can be performed, a complete description of the circuit must be provided in a form that SIMIC can read. This is accomplished by creating a Network Description File using the system editor or some automated means. The default extension for Network Description Files is net. SIMIC's network description language is called SNL (SIMIC Network Language). SNL is easy to learn. It allows a circuit to be described with great flexibility and precision.

File Extension: If a Network Description File's name is specified, but not its extension, SIMIC assumes that the extension is .net.

Types of SNL Statements

There are basically two types of SNL statements:

1. Specification Statements

These statements describe circuit topology and electrical characteristics, and allow commentary. Each SNL specification statement is composed of one or more keyword-fields having the following syntax:

<keyword>=<value_list>

Keyword-fields must be separated (delimited) by whitespace—one or more tabs and/or spaces. Within a keyword-field, optional whitespace may be inserted before and/or after the equals sign (=) for readability. If <value_list> contains more than one item, the items should be separated by commas (,). In special cases other delimiters, such as semicolons (;), must be used instead of commas. As with =, optional whitespace may precede and/or follow these delimiters.

There are four kinds of specification statements:

2. Directives

These SNL statements control the SIMIC circuit compiler. Most directives stand alone on a line, and all must be placed at the beginning of a SNL statement, optionally preceded by whitespace. Directives that begin with an exclamation mark (!) control the SIMIC parser. Those that begin with a percent sign (%) control the SIMIC circuit compiler.

Directive Description
!DELAY Declares the start of a section that defines delay-vs.-loading characteristics
!DOCUMENTATION Begins an annotation section (text ignored by SIMIC)
!FORMAT Defines the section's keyword ordering
!INCLUDE References other files to include during compilation
!LOGICAL Declares the start of a section that describes circuit topology
%DECLARE Describes collections of signals as vectors
Default Section: Every SNL file is assumed to begin with circuit topology information, thus the !LOGICAL directive is optional, unless topology is preceded by another section (!DELAY, or !DOCUMENTATION).

Basic SNL Guidelines

Blank Lines and Line Continuation

With one exception, blank lines may be freely inserted in SNL text to improve readability. Lines may be of any length, but they usually contain 80 characters or less to facilitate printing and editing. In order to enter a SNL statement spanning multiple lines, a dollar sign ($) is placed at the end of the line to be continued. The $ causes the following line to be appended, after removing any leading whitespace. Thus, if delimiting whitespace is required, it must appear before the $ character in the line being continued.

If the $ is followed by an =, then the rest of the physical line is treated as a comment, and thus ignored. If any characters follow the $ without an intervening = then an error is reported. For example:

This is $
a long sen$= This text is a comment
tence$
!

is read by SIMIC as:

This is a long sentence!

The exception noted above is a blank line immediately following a line being continued. Like any other continuation line, the blank line is appended to the continued line, thereby terminating it, since the blank line contains no $ character.

User-Defined Names

Any names that are created must begin with either an underscore (_), question mark (?) or an alphanumeric character (0-9, a-z, A-Z). The remainder of the name can contain more alphanumeric characters, underscores, and question marks, as well as hyphens, percent signs, exclamation marks, and periods. However, if any other characters are to be used, such as a pound sign (#), or a backslash (\), then the name (or the portion containing the special character) must be enclosed in single (apostrophe) or double quotes.

Case Sensitivity

In case-insensitive mode (when SIMIC is not invoked with -s option—see Entering SIMIC in Basic Simulation), SIMIC converts all user-defined names to uppercase unless directed otherwise. Double quotes serve the dual role of providing this direction; the case of text enclosed within double quotes is preserved. Below are some examples:

Original Read As
abc ABC
"abc" abc
'abc' ABC
ab"c" ABc
'ab'"c" ABc
"ab'c'" ab'c'
'ab"c' AB"C

The !LOGICAL Section

The !LOGICAL section describes the circuit structurally, that is, as an interconnection of SIMIC primitives (built-in or user-defined) and macros, which are subcircuits containing primitives and/or other macros.

The circuit is described using a hierarchy of type and part specification statements. Each !LOGICAL section contains the definition of one or more types. Each such definition is called a type block.

Note: The !LOGICAL directive is implicitly assumed at the beginning of each Network Description File (default file extension .net). Therefore, if the NET file begins with a topological description section, it is not necessary to place the !LOGICAL directive at the beginning of the file.

Basic Type Block Structure

A type block is composed of a single type statement followed by one or more part statements. The one exception to this is the BOOLEAN type block, which has no associated part statements.

TYPE Statements

A type statement declares the beginning of a macro description, assigns the macro a name, defines its external pins—inputs, outputs, and busses (bidirectionals), and optionally specifies electrical attributes (e.g., delay, pin loading).

The simplest form of type statement is:

TYPE=<type_name> I=<input_list> O=<output_list>

where:

PART Statements

A part statement instantiates (places) a component within the type block. It assigns an instance name to the component, which must be unique within this type block. It specifies the type of component being instantiated (e.g., AND, NOR, or the type name of a macro defined elsewhere). It also specifies the interconnections with the other parts within the type block, or with the pins of the type block itself. Finally, it may also describe electrical characteristics of this component, such as output delay, pin loading, etc.

When considering part statements, it is vital to make a clear distinction between the type being defined (the <type_name> in the type statement) and the type being instantiated (the value of the TYPE= keyword-field of the part statement).

The simplest form of the part statement is:

PART=<part_name> TYPE=<referenced_type> I=<input_list> O=<output_list>

where:

Distinguishing TYPE from PART: Functionally (or semantically), type statements and part statements have totally different functions. Structurally, (or syntactically), the main difference between the two is that a type statement must contain a TYPE= keyword-field, but not a PART= keyword-field, while a part statement must contain both a TYPE= keyword-field and a PART= keyword-field.

Pin Order Association

Each user-defined net name specified in <input_list> or <output_list> is associated in a one-to-one correspondence with <referenced_type>'s defined pin order. For example, DL is a built-in SIMIC D-latch primitive. Its input pins are defined as NR, NS, C, D, in that order (active-low reset, active-low set, clock, and data, respectively), and its single output pin is defined as Q (see Built-in Primitives). The part statement:

PART=q TYPE=dl I=reset,set,clock,data O=l_out

instantiates a DL whose part name is q, which must be a unique part name within the containing type block. The DL's NR pin is connected to a net named reset, its NS pin to set, its C pin to clock, and its D pin to data. Its single output pin, Q, is connected to signal l_out.

Implicit Names and Connections

Connectivity between the internal nets and pins of the type being defined is established by the commonality of their names. In other words, pins declared in the type statement and nets with the same name are implicitly connected together within the same type block.

In contrast, no implicit association is made between user-assigned names and pin names of instantiated types that happen to be identical. Thus, in the above example, even though the assigned part name, q, is identical to the DL primitive's output pin name, no ambiguity is introduced, nor connectivity implied, by assigning this particular part name.

Implicit Output Naming

To reduce the amount of typing required, SIMIC supports an implicit naming convention for certain output signals. If a part statement instantiates a type that has only one output, then the O= keyword-field may be omitted. In this case, the output net will have the same name as its part. For example:

PART=q TYPE=dl I=reset,set,clock,data

is equivalent to:

PART=q TYPE=dl I=reset,set,clock,data O=q

Reserved Signal Names

There are three reserved signal names in SIMIC which have special meaning, and should not be used as the name of any primary or internal signals.

The three names are: ONE, UNUSED and ZERO, corresponding to logical-1, an unused component pin, and logical-0, respectively. The proper use for these reserved signal names is illustrated in examples throughout this Guide.

It is important to note that the reserved signal names will match the correct spelling, even if the cases don't match. Therefore: "one", "One", "ONE" etc. are all equivalent. Similarly, the names of SIMIC primitives are case insensitive; for example, "and", "And", "AND" etc. are synonymous.

Any input pin of a part may be connected to logical-0 or logical-1 by using the reserved words ZERO and ONE, respectively. For example:

PART=q TYPE=dl I=reset,one,clock,data

connects the DL's NS pin to ONE, thereby disabling this input.

SIMIC Primitives

A primitive is an element that SIMIC can model directly, without requiring a structural description containing simpler functions. SIMIC supports a number of built-in primitives that can be used as a basis for describing circuits:

A full description of each built-in SIMIC primitive can be found in the Built-in Primitives Catalog.

Primitives may also be user-defined. SIMIC supports defining new primitives by Boolean equations in type or part statements.

To use a primitive in a circuit description, enter the primitive's type name as the value of the TYPE= keyword-field in the part statement (e.g. TYPE=and). Built-in primitives that represent simple combinational gate functions (AND, OR, NAND, NOR, EXOR, EXNOR) may have from 1 to 32767 inputs, which can be specified in any order. However, for primitives whose inputs (or outputs) have dissimilar functions (such as flip-flops), or for user-defined primitives, it is very important to specify net names for the I= keyword in the exact order that SIMIC expects, when using by-order specification. The expected pin order for each built-in primitive is given in the associated Type Statement in the Built-in Primitives Catalog.

Complete Example: Johnson Counter

Figure 4 illustrates a 3-stage Johnson Counter, and a SNL description of this circuit. It contains three (3) rising-edge triggered D flip-flops, an inverter, and a buffer on the reset line. The part statements within the SNL description are indented for readability.

Johnson Counter Circuit Diagram

Figure 4: Three Stage Johnson Counter Circuit

TYPE=johnson_counter I=clock,reset O=q1,q2,q3
  PART=buf  TYPE=and  I=reset              O=rbuf
  PART=f1   TYPE=dcf  I=rbuf,one,clock,back  O=q1
  PART=f2   TYPE=dcf  I=rbuf,one,clock,q1    O=q2
  PART=f3   TYPE=dcf  I=rbuf,one,clock,q2    O=q3
  PART=back TYPE=inv  I=q3                  O=back

SNL Description of the Johnson Counter

Detailed Analysis

In describing the circuit to SIMIC, begin with the type statement, which declares the start of a macro definition. Again, use the TYPE= keyword-field to name the type, and the I= and O= keyword-fields to name the inputs and outputs, respectively.

TYPE=johnson_counter I=clock,reset O=q1,q2,q3

A type statement must be followed by one or more part statements (with the exception of the BOOLEAN type statement), each of which: (a) instantiates a primitive or macro, (b) gives this instance a unique part name, and (c) specifies the signals connected to its pins. The part statements for the JOHNSON_COUNTER are:

PART=buf  TYPE=and  I=reset              O=rbuf
PART=f1   TYPE=dcf  I=rbuf,one,clock,back  O=q1
PART=f2   TYPE=dcf  I=rbuf,one,clock,q1    O=q2
PART=f3   TYPE=dcf  I=rbuf,one,clock,q2    O=q3
PART=back TYPE=inv  I=q3                  O=back

johnson_counter has five parts, all of which are built-in primitives.

Examining each of the five part statements:

Cautionary Note: It is legal to assign the same signal name to the outputs of different parts—this causes the outputs to be wire-tied.

Again, notice that in the Johnson counter example, each element and signal are given unique names. Each part within a type block has a unique name, as does each type block pin. Moreover, in a circuit with multiple type blocks (this Johnson Counter only has one), each type name, specified in a type statement, must be unique.

SIMIC supports many options for describing the attributes of external pins and internal nets for any circuit (or subcircuit). A full list of the SNL keywords that SIMIC will recognize appears in the SNL Keywords Reference. It includes such attributes as OUTPUT-DRIVE, INPUT-LOAD and a host of other parameters useful in modeling a circuit. If unspecified, SIMIC supplies default values for all electrical attributes.