This is an old revision of the document!
Specifying gate sizes
The gate sizing can be specified using prs sub-language but using the newly introduced sizing sub-language is recommended. This tutorial will show how to specify gate sizes using the new sizing sub-language.
Before writing a prs for inverter, let’s assume that we have the following specification included in the configuration file. Here, unit_n
is the unit drive strength of the NMOS transistor and equal to 5 lambda
.
real lambda 0.3e-6 real p_n_ratio 2.0 int unit_n 5
Example 1 - Basic sizing
Now, using our inverter example from first tutorial (inv.act), we can specify sizing for unit sized inverter as:
defproc inv (bool? in; bool! out) { prs { in => out- } sizing{ out {-1} } } inv U1;
The statement out {-1}
specifies that nmos in the pull-down network is sized for unit drive strength i.e. 5 lambda
(1.5 μm
). The pmos in pull-up network will be sized automatically based on p_n_ratio
as 10 lambda
(3 μm
). We can also write this as out {+1}
to indicate that pmos pull-up should be sized for pmos unit drive strength (unit_n * p_n_ratio) i.e. 10 lambda
. In this case, the nmos in pull-down network will be sized automatically.
Example 2 - Using template
We could also write the same inverter description using template
keyword to design a parameterized inverter as:
template<pint sz> defproc inv (bool? in; bool! out) { prs { in => out- } sizing{ out {-sz} } } inv<1> U1; inv<2> U2;
Here, the drive strength of the pull-down network is specified using integer parameter sz
. Note that inverters of different drive strength can then be instantiated by statement inv<1> U1
for unit drive strength and inv<2> U2
for 2x drive strength.
Example 3 - Using implementation relation
The implementation relation is used to implement a type, process, or channel using another type, channel, or process. Let’s look at the example below:
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> () { } INVX1 A1; INVX2 A2;
Here, two inverters are defined using the implementation relation (written as <:
). The process INVX1
is an implementation of process szinv
which is an implementation of process inv
. In this example, processes INVX1
and INVX2
both have the same logical production rules but different sizing specifications.
The use of implementation relation may look unnecessary for a small component such as inverter but it can be useful in complex circuits. For example, a standard cell library of logical gates with multiple drive strengths can be designed by using the same logical description of each gate with different sizing.