====== Specifying gate sizes ====== The gate sizing can be specified using [[language:langs:prs|prs]] sub-language but using the newly introduced [[language:langs:sizing|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 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 [[language:impl#implementation|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 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.