4. Defining Recognition Rules and Actions

4. 1. Description

GNS provides a highly efficient way to identify a hierarchical structure within a flat transistor netlist. This process is done by first identifying basic blocks made up exclusively of transistors. Those blocks are then merged by hierarchical rules to a higher level of abstraction. The process is repeated until all the user specified hierarchical rules have been fully exhausted. Each user-specified rule is a model corresponding to a single hierarchical level. Genius will try to find all the instances of each level starting from the models describing the transistor level blocks right up to the top-level hierarchical model. In addition, the user is given the possibility of specifying actions which are performed whenever instances of a model are identified within the circuit. This action consists of a C or TCL function which can do practically whatever the user wants. The operation of the GNS hierarchical recognition therefore requires a certain amount of user-supplied information and files. To provide this information the user must create a GNS library file which basically contains the file names of the models and actions.

4. 2. The Recognition Models

4. 2. 1. The Transistor Level Models

The first step in the hierarchical recognition is to identify the blocks at the lowest level. Those blocks are composed exclusively of transistors. The user must therefore provide models for each of the basic blocks to recognize. The actual recognition of these transistor-level blocks is performed by FCL, however this is transparent to the user since the GNS module handles the communication with FCL. The description of the transistor level blocks can be given either as a SPICE netlist or in a structural VHDL file.

The spice netlist is a classical flat transistor netlist but the VHDL description is done by instantiating transistors N or P. For this, there are two special components to describe the transistors:

COMPONENT tn
   PORT (
   grid: IN BIT;
   source, drain: INOUT BIT);
END COMPONENT;
 
COMPONENT tp
   PORT (
      grid: in bit;
      source, drain: inout bit);
END COMPONENT;

From the GNS point of view, there is no difference between these representations. For instance, an inverter could be described as:

In VHDL:

ENTITY inverter IS
   PORT (
   dout: out bit;
   din: in bit;
   vdd, vss: in bit);
END inverter;
 
ARCHITECTURE structural OF inverter IS
 
   COMPONENT tn
      PORT (grid: IN bit; source, drain: INOUT bit);
   END COMPONENT;
 
   COMPONENT tp
      PORT (grid: IN bit; source, drain: INOUT bit);
   END COMPONENT;
 
BEGIN
   tn_1: tn
      PORT MAP (grid=>din, source=>vss, drain=>dout);
   tp_1: tp
      PORT MAP (grid=>din, source=>vdd, drain=>dout);
END structural;

Or in SPICE:

.SUBCKT inverter dout din vdd vss
M1 vdd din dout vdd tp
M2 vss din dout vss tn
.ENDS

The user has the freedom to use whichever format he/she prefers. The library file is used to specify the format to be used for a particular model.

4. 2. 2. The Hierarchical Models

Once the basic transistor-level blocks have been identified within the circuit, the higher-level hierarchical models can be identified. In order to perform this hierarchical recognition, the user must specify, for each of the hierarchical levels, how the blocks are interconnected. This is done by providing a standard VHDL structural description of how the lower-level blocks are interconnected.

Structural VHDL provides a natural way of describing a hierarchical structure. The ENTITY construct effectively serves as a declaration for the recognition rule, as well as providing the interface of the component abstracted by application of the rule. The ARCHITECTURE block specifies the interconnection of blocks from the lower levels required by the rule. As in VHDL, the required lower-level blocks must be declared using the COMPONENT construct, this allows both implicit (order based) and explicit (name based) component instantiations. Anyway, using the format spice_hr rather than VHDL permits the description of a simple hierchical model without all the possibilties of the VHDL model (loops, vectors, ...).

For example, the rule required to recognize a bi-stable made up of two NAND gates would be written as follows:

ENTITY bistable IS
   PORT (
   r: IN BIT;
   s: IN BIT;
   q: OUT BIT;
   qn: OUT BIT;
   vdd, vss: IN BIT);
END bistable;
 
ARCHITECTURE nand_based OF bistable IS
 
   COMPONENT nand
      PORT (y: OUT BIT; in1, in2: IN BIT; vdd, vss: IN BIT);
   END COMPONENT;
 
BEGIN
   nand_1: nand
      PORT MAP (q, r, qn, vdd, vss);
   nand_2: nand
      PORT MAP (qn, s, q, vdd, vss);
END nand_based;

However, it is also possible to generate a bi-stable from two NOR gates. The user may therefore require that a single recognition rule consist of alternative internal structures. This is possible by providing multiple ARCHITECTURE blocks for a single ENTITY.

To recognize a bistable made up of either NAND or NOR gates, the user would add the following architecture construct to the preceding rule:

ARCHITECTURE nor_based OF bistable IS
 
   COMPONENT nor
      PORT (y: OUT BIT; in1, in2: IN BIT; vdd, vss: IN BIT);
   END COMPONENT;
 
BEGIN
   nor_1: nor
      PORT MAP (q, r, qn, vdd, vss);
   nor_2: nor
      PORT MAP (qn, s, q, vdd, vss);
END nor_based;

4. 2. 3. Generic Hierarchical Models

One of the most powerful features of the GNS recognition language is the ability to represent interconnections of an arbitrary number of identical structures. Both parallel structures and serial structures can be represented.

This important capability is provided for through the use of VHDL Generics coupled with GENERATE constructs. In standard VHDL a structural model can be made generic in exactly this way; it is the responsibility of the instantiation to specify the actual value of the generic variable. In our semantic, it is the role of the recognition module to identify the value.

A typical example of a parallel structure would be a rule to identify a column of an arbitrary number of bit-cells as part of a static RAM:

ENTITY column IS
   GENERIC (capacity: INTEGER);
   PORT (
   q, nq: INOUT BIT;
   com: IN BIT_VECTOR (1 TO capacity);
   vdd, vss: IN BIT);
END;
 
ARCHITECTURE structural OF column IS
 
   COMPONENT bitcell
      PORT (q, nq: INOUT BIT; com, vdd, vss: IN BIT);
   END COMPONENT;
 
BEGIN
   loop: FOR i IN 1 TO capacity GENERATE
      bit_i: bitcell
         PORT MAP (q, nq, com (i), vdd, vss);
   END GENERATE;
END structural;

Both the loop limits and the vector bounds can be specified as expressions. In this case, the expression for the lower limit must necessarily resolve to a constant and for the upper limit, the generic variable must be the only unknown.

In any case, in any one rule, it is not possible to have more than one GENERATE loop for which the limits are specified by a GENERIC whose value is to be identified. However, this is not a real limitation thanks to the unlimited hierarchy of the rules.

It is also possible to describe arbitrary numbers of components connected in cascade, for example, a chain of inverters can be represented by the following rule:

ENTITY invchain IS
   GENERIC (length: INTEGER);
   PORT (
   q, nq: INOUT BIT;
   con: IN BIT_VECTOR (0 TO length);
   vdd, vss: IN BIT);
END;
 
ARCHITECTURE structural OF invchain IS
 
   COMPONENT inverter
      PORT (y: OUT BIT; a, vdd, vss: IN BIT);
   END COMPONENT;
 
BEGIN
   loop: FOR i IN 1 TO length GENERATE
      inv_i: inverter
         PORT MAP (con (i), con (i-1), vdd, vss);
   END GENERATE;
END structural;

4. 2. 4. Exploiting Generic Variables

At each hierarchical rule level it is possible to exploit the value of generic variables obtained from lower levels of the hierarchy. The mechanism for this is identical to standard VHDL apart from the fact that the direction of transmission is from the lower levels upwards rather than from the upper levels downwards.

The transmission of generic values is specified using the GENERIC MAP construct. This construct specifies which generic variable in a rule takes the value of a generic variable defined in rule corresponding to an instantiated model.

For example, imagine we need the height of a column of bit cells in order to add an inverter in front each of the command inputs. We could use the following rule:

ENTITY buffered_col IS
   GENERIC (height: INTEGER);
   PORT (
      q, nq: INOUT BIT;
      bufcomb: IN BIT;
      vdd, vss: IN BIT);
END bistable;
 
ARCHITECTURE structural OF buffered_col IS
 
   COMPONENT column
      GENERIC (capacity: INTEGER);
      PORT (
         q, nq: INOUT BIT;
         com: IN BIT_VECTOR (1 TO capacity);
         vdd, vss: IN BIT);
   END COMPONENT;
 
   COMPONENT inverter
      PORT (out: OUT BIT; a: IN BIT; vdd, vss: IN BIT);
   END COMPONENT;
 
   SIGNAL bufcom: BIT_VECTOR (1 TO height);
 
BEGIN
   column_ins: column
      GENERIC MAP (height=>capacity);
      PORT MAP (q, nq, bufcom, vdd, vss);
 
   loop: FOR i IN 1 TO height GENERATE
      buf_i: inverter
         PORT MAP (bufcom (i), bufcomb (i), vdd, vss);
   END GENERATE;
 
END structural;

As we can see from the above example, in order to exploit a generic variable whose value obtained by a rule at a lower level, is is necessary to:

The GENERIC MAP can be either explicit (as in the above example) or implicit, in which case the association is made based upon the order of the GENERIC declarations in the COMPONENT.

Generic variables whose values are obtained through GENERIC MAPs can be used in the same way as generic variables identified in the rule. That is for:

A rule can contain any number of GENERATE statements defined by GENERIC variables obtained in this way, since their limits are precisely defined at the beginning of the validation of the rule.

4. 3. VHDL Recognition Rules Reference

This section contains the complete grammar of the structural VHDL subset used to represent the GNS recognition rules. Only entity and structural architecture declarations are required. Before giving the BNF for each of these two parts, we illustrate them with a general example.

The legend for the following BNF grammar definitions are:

<name> is a syntax construct item
name is a lexeme
[<name>] or [name] is an optional item
<name>* is zero or more items
<name>+ is one or more items
<name> -> indicate a syntax definition to an item
|| introduces an other syntax definition for an item

First of all, each rule requires an entity declaration such as:

ENTITY levelA IS
   GENERIC ( VAR, VAR1, ...: integer );
   PORT (
      a INOUT BIT;
      b: IN BIT_VECTOR(1 TO var);
      ...
      vdd, vss: IN BIT);
END;

The entity describes the model "levelA". A model can be instantiated with parameters. All the parameters used later in the architecture part of the model must be present in the model entity. One, and only one, of the generic variables can be the special variable whose value must be determined during execution of the rule.

The complete entity grammar allowed is as follows:

<entity> -> ENTITY <name_of_model> IS
            [GENERIC ( <list_of_variables>+ );]
            PORT ( <list_of_ports>+ );
            END [<name_of_model>];
 
<list_of_variables> -> <<variable_decl>;>* <variable_decl>
 
<variable_decl> -> [VARIABLE] <<identifier_list>: INTEGER
 
<identifier_list> -> <<identifier>,>* <identifier>
 
<list_of_ports> -> <<port_decl>;>* <port_decl>
 
<port_decl> -> <identifier_list>: <port_type>
 
<port_type> -> IN <mode>
            || OUT <mode>
            || INOUT <mode>
 
<mode> -> BIT
       || BIT_VECTOR <array>
 
<array> -> ( <expression> TO <expression> )
        || ( <expression> DOWNTO <expression> )

The expression in the array statement is a standard arithmetic expression which can depend on all the generic variables defined in the entity, even the special generic variable whose value must be identified during execution of the rule.

The architecture section of a rule is composed of 2 parts: the component declarations and the model instantiations in the architecture body. The component of a model should have the same interface and the same generic variables found in the entity statement for the same model. The grammar of the architecture body is elementary.

A typical example shows loops instantiating multiple instances and single instantiations:

architecture ArchiLevelA of levelA is
 
COMPONENT levelB1 
   GENERIC (varB2, ...: integer)
   PORT ( ... 
      q: IN BIT_VECTOR(1 TO varB2);
      ...
      vdd,vss: IN BIT);
END COMPONENT;
 
BEGIN
   loop0: FOR i IN 1 TO var GENERATE
      instB1_i: levelB1 
         GENERIC MAP (varB2=>var1, ...)
         PORT MAP ( ... );
   END GENERATE;
 
   loop1: FOR j IN 1 TO var1*2 GENERATE
      instD1_j: levelD1 
         GENERIC MAP ( ... )
         PORT MAP ( ... );
   END GENERATE;
 
   instance_fcl: levelFCL1 GENERIC MAP (...) PORT MAP ( ... );
   instance_l2: levelC PORT MAP ( ... );
END;

The complete architecture grammar allowed is as follows:

<architecture> ->
        ARCHITECTURE <name_of_archi> OF <name_of_model> IS
        <component>*
        <signal_decl>*
        <architecture_body>*
 
<signal_decl> -> SIGNAL <identifier_list>: <mode>;
 
<component> -> COMPONENT <name_of_model>
               [GENERIC ( <list_of_variables>+ );]
               PORT ( <list_of_ports>+ );
               END COMPONENT;
 
<architecture_body> -> BEGIN
                       <architecture_element>*
                       END [<name_of_archi>];
 
<architecture_element> -> <simple_instantiation>
                       || <loop_instantiation>
 
<loop_instantiation> ->
        <blockname>:
        FOR <identifier> IN <expr> <direction> <expr>
        GENERATE
        <instantiation>+
        END GENERATE;
 
<simple_instantiation> ->
        <blockname>: <identifier>
        [GENERIC MAP ( <generic_assignment> )]
        PORT MAP ( <port_assignment> );
 
<direction> -> TO
            || DOWNTO
 
<instantiation> -> <loop_instantiation>
                || <simple_instantiation>
 
<generic_assignment> -> <identifier_list>
                     || <explicit_assignment_list>
 
<explicit_assignment_list> ->
        <<explicit_assignment>,>* <explicit_assignment>
 
<explicit_assignment> -> <identifier> => <identifier>
 
<port_assignment> -> <signal_list>
                  || <explicit_sig_assign_list>
 
<signal_list> -> <<signal>,>* <signal>
 
<signal> -> <identifier> [<array>]
 
<explicit_sig_assign_list> ->
        <<explicit_sig_assign>,>* <explicit_sig_assign>
 
<explicit_sig_assign> -> <identifier> => <signal>

The instantiation of a model is done by assigning the generic variable of the instance to the local generic variables of the current model and by linking the instance port to the model signals. The <identifier> is the model name and <blockname> the instance name.

The user can also use a "for" statement to try to instantiate a set of instances whose number is known. In this case, the expressions defining the bound of the "for" statement have no restriction and can depend on any of the known generic variables.

The user may also wish to recognize an unknown number of instances such as cells in parallel or in series. In this case, the left or right expression in the "for" statement contains an unknown generic variable and at least one of the port vector will depend on this variable. The expression with the generic variable has certain restrictions. The only legal operators are '+', '-', '/' and '*'.

When trying to find a number of cells in a "for" statement, Genius will always try to match as many instances as possible.

4. 4. The Actions

The user can associate an action to a model. This action can be put directly at the end of the VHDL file if it's a C action or in a separate file. If the action is written in TCL it can be defined in the main TCL script. The action is a C or TCL function which has the same name as the model. This function is given the values computed for all the generic variables of the model. Those values are assigned to variables with the same name as the generic variables of the model.

For any given model, there can be several versions due to the fact that each recognized instance of a model can differ from another depending on the values attributed to the generic variables used to match the model. A unique name for each version is passed as an argument to the function as a string "char *model".

The action is called for each recognized instances remaining after all the recognition rules have been applied. A unique name for each instance is passed as an argument to the function "char *instance".

void levelA (char *model, char *instance, int VAR, int VAR1, ...)
{
	...
}

In TCL, generic variables are made available as global TCL variables. Be aware that calling TCL script within GNS, affects main TCL script.

proc levelA {} {
  global model instance VAR VAR1 ...
  ...
}

The actions are called at the end of the complete recognition phase for all the instances to keep (see Library File) in the circuit. The instances to keep but only used by an higher hierarchical level are destroyed. Their actions will therefore not be executed.

The C action function is interpreted by GNS, therefore there are certain limitations in what the user can do. However, the action functionality can be expanded by the use of dynamic libraries. Dynamic libraries, containing user-defined functions which can be called from within actions, are easily created with the help of the genapi tool.

4. 4. 1. Types

The action interpreter authorizes use of the following base types:

Pointers types or one dimensional arrays types based on the above type ar also recognized.

Additionally, any other pointer types can be specified so long as they are only used in user-defined function calls (see dynamic library).

Static variables are authorized. They are global to all the actions.

4. 4. 2. Supported Operators

All the basic C arithmetic and logic operations are possible on the authorized interpreter types.

4. 4. 3. Functions

The interpreter can manage the following standard C functions:

The following built-in non standard functions are also implemented:

FILE *avtfopen(char *name, char *extension, char mode) ....
opens a file taking into account the global configuration file for the seek directories and compression filter. Legal values for the mode are: READ_TEXT and WRITE_TEXT
int gnsModelVisited(char *model);
Returns 1 if the given model has already been marked as visited, 0 otherwise. Used to avoid duplicating actions.
void gnsMarkModelVisited(char *model);
Marks the given model as having been visited, to avoid duplicating the action.
char *char_to_string(int size, char caract);
returns a string which length is 'size'. The string is filled with the character 'caract'.
char *onehot_to_bit(int size, int bitnum);
returns a string which length is 'size'. The string is filled with the value (1<<bitnum) in binary format.
char *onehot_to_hexa(int size, int bitnum);
returns a string which length is 'size'. The string is filled with the value (1<<bitnum) in hexadecimal format.
char *onehot_to_octa(int size, int bitnum);
returns a string which length is 'size'. The string is filled with the value (1<<bitnum) in octal format.
char *onecold_to_bit(int size, int bitnum);
returns a string which length is 'size'. The string is filled with the value not(1<<bitnum) in binary format.
char *onecold_to_hexa(int size, int bitnum);
returns a string which length is 'size'. The string is filled with the value not(1<<bitnum) in binary hexadecimal format.
char *onecold_to_octa(int size, int bitnum);
returns a string which length is 'size'. The string is filled with the value not(1<<bitnum) in octal format.
char *genius_date();
returns a string containing the current date and time.

Note that each of the string generation functions always returns a pointer to the same address. If you wish to keep the string over multiple calls of the same function, you will have to copy the result into another string variable.

4. 4. 4. Loops and conditional statements

Genius interpreter handle the following C loop and conditional constructs:

The reserved words "return" and "break" are also supported as well as the standard function call "exit(<errcommand>)".

4. 4. 5. Dynamic Libraries

The user can create his own dynamic library whose functions can be called from within GNS actions. To do so, he has to provide a simplified header file containing the function prototypes. Global variables are not allowed. The use of the tool genapi will automatically generate the dynamic library from the header file and the .c files given by the user.

4. 5. The Library File

The library file contains a list of all the rule files and supplementary information required by the recognition module. The transistor level models, the hierarchical models and the action files are all referenced here. The library file can also indicate built-in template recognition rules and actions to use in the recognition process.

Each line of the library file can have two format. The first one is for the user defined rules and actions and the second one for the template instantiations:

 <model_file> [: [priority=<num>]
                  [, keep=<yes|no>]
                  [,format=<spice|vhdl|spice_hr>] ]; 

The names of a model_file does not have to respect a particular format, except if the file is supposed to be a TCL script. In this case the file must be interpreted by TCL the suffix must be ".tcl" else the file is considered to be VHDL or C. The format directive specifies whether a transistor-level recognition rule is in SPICE or VHDL format. In the case of files containing actions, the format must not be specified.

The priority defines the order of recognition for models. Lower value means higher priority. Independent recognition rules are applied in order of specified priority. This option can be critical if one model is a subset of another model.

Finally, the "keep" flag tells genius whether the user is interested in keeping the recognized instances of a model. The user is generally interested by the top level of his hierarchy but he can keep other recognized instances (see also gnsKeepAllCells configuration). The <modelname>_yagroot.<vhd|spi> file will contain only the instances whose model keep flag have been set.

In the case of template instantiations, the syntax follows:

 <model_name> <model_instance_name> {
   [ rule=<file_spec> ]
   [ rules={ <file_spec> [, ...] } ]
   [ action=<file_spec> ]
   [ actions={ <file_spec> [, ...] } ]
   [ <model_identifier>=<new_identifier> [, ...] ]
 } [: [priority=<num>]
       [, keep=<yes|no>]  ];

The model_name is the name of one of the built-in templates available in the distribution or in the paths given by 'gnsTemplateDir' and 'gnsLibraryDir' variables. The model name can be overridden by model_instance_name but the model_name can be used if the template is instantiated once.

By default, the template rules and actions will be used for the recognition but they can also be overridden by specifying a <file_spec> which has exactly the same syntax as the user defined rule except the trailing semicolon. Several files can be specified for the rules and the actions, for instance, if different architectures are spread over multiple files.

All the identifier <model_identifier> of the template rules can be renamed by <new_identifier> depending on the user wish. This is handy to change the instance models, connector names or generic variable names in the rules.

Finally, an overall priority and keep flag can be specified for the instantiated model. Their meaning is the same as for the user defined rules and actions.

4. 6. Symmetry and Coupling

Due to the nature of bottom up recognition, any symmetry in the identified components can cause recognition difficulties which are not immediately obvious. Cells are identified at a particular hierarchical level without knowing how they will be connected in the higher level. Because of this, GNS cannot guarantee the precise ordering of any symmetric cell connectors. In the example below representing the memory cell, the connectors q and nq are symmetric. This means that from the perspective of the individual cell there is nothing to distinguish between these two connectors. When performing the recognition of the memory cell, There is nothing to prevent the memory cell being recognized the other way round to that which the user would have expected.

The user must pay careful attention to any possible symmetry in the models to recognize. For example, if the user wants to recognize a column of memory cells connected in parallel, he would provide a rule to identify an arbitrary number of memory cells with the q ports connected together and the qn ports connected together. However, if q and qn ports are symmetric then q ports may be connected to qn ports and vice versa but nonetheless corresponding to a column of memory cells.

The case of symmetry also occurs often when dealing with vectors. A user may require the identification of two instances connected together by vectored ports. However, the signal connected to bit(0) of one of the ports is not necessarily the signal connected to bit(0) of the other port. The order of the indexing of the vectored ports depend on the order of the recognition algorithm.

To cope with this problem of symmetry, GNS provides for a mechanism of pragma directives included as comments in the model files. Each pragma directive consists of the list of symmetric connectors. The connectors can be single connectors or the radical of a vectored connector. Use of the radical of a vector implies that all the connectors of the vector are symmetric to each other. Each group of symmetric connectors must be declared in a unique pragma.

In VHDL rules, the pragma is declared in the model entity after the port declarations as follows:

	-- pragma symmetric [<single_connector>|<connector_radical]+

In SPICE, for symmetric connector in transistor-level cells, the pragma can be placed anywhere as follows:

* pragma symmetric [<single_connector>|<connector_radical]+

With symmetry comes the additional difficulty of coupled symmetry. When GNS tries to match together recognized instances with symmetric connectors and the initial match fails, it only knows that there are connectors which can be swapped. It will then try to swap around the symmetric connectors until a match is found. In reality, the symmetry handling is more efficient than this, but that's the basic idea.

In the above example of a column multiplexer, there are 2 sets of symmetric connectors:

In the example i0 depends on a0 and i1 depends on a1. It's obvious that if i0 and i1 are swapped, a0 and a1 must also be swapped. a0 is effectively coupled with i0 and a1 is coupled with i1. If the coupling dependencies are not explicitly stated, GNS may swap the connectors in one of the symmetric sets but not the other, thus corrupting the connectivity of the recognized instance.

The user must therefore also be careful about the coupled symmetric connectors in a model else GNS will be able be match instances for which the connectivity described by the rule is not respected.

In the same way as for standard symmetric connectors, pragma directives must be used to define the couplings:

In VHDL rules, the pragma is declared in the model entity after the port declarations as follows:

	-- pragma coupled [<single_connector>|<connector_radical]+

In SPICE, for symmetric connector in transistor-level cells, the pragma can be placed anywhere as follows:

	* pragma coupled [<single_connector>|<connector_radical]+

The entity declaration for the multiplexer would therefore be as follows:

ENTITY mux IS
   PORT (
      i0, i1: INOUT BIT;
      a0, a1: INOUT BIT
   );
-- pragma symmetric i0 i1
-- pragma symmetric a0 a1
-- pragma coupled i0 a0
-- pragma coupled i1 a1
END;

The user should be aware that symmetric connector imposes a restriction on how the rules can be written. If a particular rule contains a loop instantiation (of the special kind which determines the value of a generic) and the instances in the loop are connected together by symmetric connectors, then is not possible, in the same rule, to connect these connectors to anything outside the loop apart from a set of symmetric connectors.

This is not actually a restriction on what can be recognized since structures which require this kind of description can always be handled by introducing an additional rule hierarchy.

4. 7. Other PRAGMAs

	-- pragma without <name0> [<name1]*

Matches the hierarchical recognition rule only in no correspondance is found for the given instances or transistors.

	-- pragma exclude <name0> [<name1]*

After the each recognition of the rule, the given instances are put back in the available instance list so they can be used again in the recognition rules (even the current one). This permits sharing of instances/transistors between rules.

	-- pragma exclude_at_end <name0> [<name1]*

The same as "exclude" but the given instances can not be reused by the current rule. They will be available for the next ones.

	-- pragma forcematch <name0> [<name1]*

The given names apply to transistor, instances and net names. This option, will match the names in the rule if they are in the given list. Name match for instances won't work for GNS recognized instances as their name is automatically generated. Instead blackboxed instances can use this option. If '_' is used in a given name, it can be matched with a hierarchy separator. eg. circuit blackbox instance xlevel.xcells will be matched by xlevel_cells.

	-- pragma unused <name0> [<name1]*

Each connector in the given list is unused meaning there is no real correspondance to them in the netlist.