This is an old revision of the document!


Sizing sub-language

The sizing sub-language is used to simplify gate sizing specifications. The prs sub-language already provides a mechanism to specify sizing, but this can become very verbose. For example, consider an inverter

prs {
  in => out-
}

Now, if we want the pull-up network to have width 20 units and the pull-down to have width 10 units, this gets turned into:

prs {
  in<10> -> out-
 ~in<20> -> out+
}

Note that the convenience of specifying combinational logic is lost, as two production rules have to be specified to control the sizes of all the gates.

Often all one is interested in is sizing the gates so that they have some unit drive strength, where the unit selected is technology/project specific. The sizing body is the way this can be specified. Suppose the net section of the configuration file specifies that the unit drive strength is 10 lambda, and that the p-to-n ratio is 2. In this case, one can write the following instead:

prs {
  in => out-
}
sizing {
  out {-1}
}

The sizing body is a semi-colon separated list of directives. In the example above, the directive out {-1} specifies that the pull-down network (indicated by -) is to be sized with the drive strength of a unit n-transistor (assumed to be 10 lambda, in our example).

This has the same effect as:

prs {
  in <10> -> out-
 ~in <20> -> out+
}

The p-to-n ratio is automatically used to size the pull-up network differently from the pull-down network.

prs {
  a & b => c-
  ~c => d-
}
sizing {
 c {-1}; d{-1}
}

The example above results in the following sizing:

prs {
  a<20> & b<20> -> c-
  ~a <20> | ~b <20> -> c+
  c <10> -> d-
  ~c <20> -> d+
}

Note that that series transistors are appropriately sized, as are the parallel ones. Note that the default standard length is used for all transistors.

Specifying sizing for a production rule that has manual sizing specified is a warning; in this case, the sizing directive is ignored.

Specifying flavors and multi-fingered devices

An example of the general form of the sizing directive is:

 sizing {
   out {-5,lvt,2 ; +4,lvt,2 }
 }

This says that the pull-down network should be sized with 5 times the drive strength, and all gates should use two fingers and lvt flavor transistors. The pull-up network should be sized with 4 times the unit drive strength, use lvt transistors, and two fingers. The order of the two drive strengths can be interchanged; i.e. this is the same as writing

sizing {
  out {+4,lvt,2 ; -5,lvt,2 }
}

If a circuit wants to use a different unit width, that can also be specified as follows:

sizing {
  unit_n <- 20;
  out {-1};
}

This says that the unit n-transistor is 20 lambda wide.

Example using implementation relation

The benefits of a sizing body are best illustrated when combined with the implementation relation. Consider the following example:

defproc inv (bool? i; bool! o)
{
  prs {
    i => o-
  }
}

template<pint drive>
defproc szinv <: inv()
{
  sizing {
     o {-drive}
  }
}

defproc INVX1 <: szinv<1> () { }
defproc INVX2 <: szinv<2> () { }

This is an example of defining two standard inverters, that correspond to the same logical production rules but having different sizing.

P/N ratios

The default sizing equalizes drive strengths for the pull-up and pull-down network. For gates used in cyclic control logic in asynchronous design, the optimal drive strengths are different. To use the optimal ratio, you can add:

prs {
  in[1] & in[0] #> out-
}
sizing {
  p_n_mode <- 1; /* this modifies the sizing */
  out {-1}
}

The ratio will be computed using parameters in the netlist section of the ACT configuration file.

Low leak addition on channel length

In some technologies, the minimum length devices have extremely high leakage. To avoid using these, you can specify an adjustment that will be added to the length to avoid this case. This adjustment is only applied to minimum length devices.

For adding a specified additional length to the minimum length of your transistors, activate leak_adjust.

prs {
  in => out-
}
sizing {
   leak_adjust <- 1;
   out{-1}
}

To configure how much is added add this line to the configuration

# add to length for leakage management [used if l=min length]
real leakage_adjust 15e-9

The length unit here is absolute (i.e. not scaled), so the amount specified above is 15nm.