prs2net: automated netlist generation
The tool prs2net
can be used to automatically generate a hierarchical spice netlist from an .act
file. Parameters that control defaults and the output format are specified in a configuration file.
The overall way the tool works is as follows. First, it reads in the .act
file. This file is then “expanded”, which means that all parameters are expanded out. This requires instances of cells in the top-level file. In general, it might make sense to have a file test.act
that import
s the necessary act file and instantiates the top-level cell of interest.
Expanded versions of cells have their expanded template attached to their names. In the following example, after expansion, there are two cells: foo
(the unexpanded cell), and foo<>
(the expanded cell).
defproc foo(bool a, b) { prs { a => b- } } foo f;
If the instance foo f;
were missing, then foo
would not be expanded into foo<>
(since it is not used).
Basic Netlist Specification
Production rules are syntactically translated into a netlist. The gate order is taken from left to right, where the power supply is the leftmost node and the output is the rightmost node. This means that the rule
a & b -> c-
gets translated into a netlist that starts from GND
, then has transistors gated by a
followed by b
, and the drain of the final transistor is connected to c
. The netlist corresponding to just this rule is given by:
M0_ GND a #3 GND nch W=0.3U L=0.12U M1_ #3 b c GND nch W=0.3U L=0.12U
(The details may vary depending on your configuration file.) A close examination shows the gate ordering a
followed by b
, where a
is closer to GND.
Widths, Lengths, Flavors. The width and length of any transistor can be specified using size specifiers. For the same rule above, we could specify a different width for a
as follows:
a<20> & b -> c-
This says the width of the transistor for a
is 20 units (the multiplier is specified in the configuration file). Once a size specifier is provided, it is used by the expression until another specifier is seen. This is convenient, for example, when you need to specify that an entire stack uses the same width.
Length specifiers can also be used to change the default length of a transistor. The same example with a longer transistor (length 5) is given by:
a<20,5> & b -> c-
Finally, different transistor flavors can also be specified. The recognized flavors are specified in the ACT configuration file. Commonly used names are:
svt
: standard Vtlvt
: low Vthvt
: high Vt
The following shows how these can be used:
a<20,lvt> & b<20> -> c- q<10,5,hvt> & r<10,5> -> d-
In this example, the transistor gated by a
is low Vt, while the one gated by q
is high Vt. All others are standard Vt. Additional details are available in the prs sub-language documentation.
Pass Transistors. Pass transistors are specified using passn
, passp
, and transgate
. These also take the same width/size/flavor specifiers as described above. The syntax of these three constructs is:
passn(gate,src,drain)
: n-type pass transistorpassp(gate,src,drain)
: p-type pass transistortransgate(ngate,pgate,src,drain)
: a transmission gate withngate
andpgate
corresponding to the signals connected to the n-type and p-type transistor respectively (normally they will be complements of each other).
Each of these can contain a size directive as shown in the examples below:
prs { passn<10,3> (g,s,d) passp<10,4,lvt> (_g,s,d) }
Internal Precharges. Precharges are only on internal nodes, and new internal nodes are only created with an &
operator. So how about we say
a &{+expr} b
for a precharge to Vdd
(indicated by +
), and
a &{-expr} b
for a precharge to GND
(indicated by -
). Also, the type of the expression indicates which transistor type gets used. So, for instance
a &{+en} b -> c-
specifies a precharge to Vdd
with n-type transistors (since en
is uninverted). The same precharge with p-type transistors would be written
a &{+~_en} b -> c-
(assuming _en
was the complement of en
.)
Shared Gate Networks
The syntax supports building arbitrary shared-gate networks. This can be done via labels, indicated with the @
symbol. To illustrate, the following example
builds a shared gate network:
a & b -> @x- ~@x & w -> r0- ~@x & r -> r1-
The idea is that “@” is a label for the internal node. Note that @'s always appeared in the “wrong sense” in the production rule. The label @x
should not be confused with a bool
variable. This label is only internal to the production rule body.
The second construct is
tree { a & b & w -> r0- a & b & r -> r1- }
This specifies maximal sharing, i.e. build the shared-gate network by maximal prefix-sharing within the group. Finally, we can limit the size of the prefix by specifying a sharing-limit as follows
tree<1> { a & b & w -> r0- a & b & r -> r1- }
Output handling
ACT supports name mangling to sanitize the output so that it can be accepted by third-party tools. Since the largest variability in supported names is in different versions of SPICE, the prs2net
tool also accepts another configuration file option called net.mangle_chars
that can be used to change the name mangling that is used only for the output of prs2net
. (The meaning of this configuration parameter is the same as ''act.mangle_chars''.
Attributes
Attributes can be attached to a production rule or pass transistor/transmission gate
using standard .act
syntax. Some commonly used ones are:
keeper=0
: do not generate a keeper for this node, even if it looks like a state-holding gate.comb=1
: use combinational feedback rather than a standard staticizer if the node is state-holding.output=v
: used for pass transistors to force either the source, drain, or both to be labelled as an output. This is useful for thePININFO
directive emitted byprs2net
. If the valuev
has bit zero set, then the source is marked as an output node. Ifv
has bit one set, then the drain is marked as an output. By default, a node is considered an input if it does not have a production rule driving it.loadcap=v
: sets the load capacitance on the output to be a the specified value in fF. This is used to override the default setting specified in the configuration file.
The following shows how you can specify two C-elements, one with no staticizer, and another with combinational feedback.
prs { [keeper=0] a & b #> c- [comb=1] p & q #> r- }
Attributes currently recognized by prs2net
are:
Attribute | Meaning |
---|---|
keeper | The production rules for a signal are analyzed to determine if the pull-up and pull-down networks are perfect complements of each other. If they aren't, then a keeper is generated. There are two common scenarios when this behavior is undesired: (i) the gate is intended to be dynamic, and so it is state-holding but a staticizer should not be generated. Set keeper to 0 for this behavior. (ii) the gate looks state-holding, but it is actually a combinational gate because certain inputs are supposed to be complements of each other. In this case, set keeper to 2 . (iii) the gate is state-holding, is a C-element (uses #> ), is a two-input gate, and should use the H-topology C-element keeper structure. For this, set keeper to 3. |
comb | If set to 1, uses combinational feedback rather than a weak inverter for the staticizer; if 0, uses a weak inverter instead of combinational feedback |
iskeeper | used to let prs2net know that the specified production rule is in fact the manually specified staticizer/keeper circuit. prs2net labels transistors used for keepers in the spice netlist, and this attribute can be used to ensure that manually specified keepers are also labeled (with _keeper ). |
isckeeper | used to let prs2net know that the specified production rule is a combinational feedback style keeper circuit. These will be labeled with _ckeeper . |
loadcap | sets the load capacitance on the output to be a the specified value in pF. This is used to override the default setting specified in the configuration file |
oresis | sets output resistance for node. This resistance is added in series to the output of the gate, and overrides the default from the prs2net configuration file |
output | used for pass transistors to force either the source, drain, or both to be labelled as an output. This is useful for the PININFO directive emitted by prs2net. If the value v has bit zero set, then the source is marked as an output node. If v has bit one set, then the drain is marked as an output. By default, a node is considered an input if it does not have a production rule driving it. |
N_reff | sets the n-stack effective resistance, overriding the default computed by prs2net. This is used to compute strengths of staticizers. The resistance for one transistor is computed as L/W where L and W are the length and width of the transistor respectively. |
P_reff | same as N_reff, except sets strength of p-stack |