A contribution statement is used to give values to continuous signals, in particular to branch potentials or flows:
analog begin V(res) <+ r * I(res); end
This statement says that the voltage on the branch named ‘res’ should be driven so that the voltage on the branch should equal r multiplied by the current through the branch.
Contributions may be either explicit, as above, or implicit. Implicit contributions have the target on both sides of the contribution operator. For example:
analog begin I(cap) <+ c * ddt(V(cap) - r*I(cap)); end
This implements the series combination of a resistor and a capacitor.
Implicit contributions to branch flows can be used to easily create series combinations whereas implicit contributions to branch potentials can be used to create parallel combinations. For example, the following creates the parallel combination of an inductor and a conductor:
analog begin V(ind) <+ l * ddt(I(ind) - g*V(ind)); end
Multiple contributions to the same branch in the same analog process accumulate. For example:
analog begin I(out) <+ gm * V(in); I(out) <+ g * V(out); I(out) <+ c * ddt(V(out)); end
This is equivalent to:
analog I(out) <+ gm * V(in) + g * V(out) + c * ddt(V(out));
Multiple contributions to a branch flow can be viewed as creating multiple parallel branches. For example, the above example is equivalent to the parallel combination of the output of a controlled current source, a conductor, and a capacitor. Similarly, multiple contributions to a branch potential can be viewed as creating multiple series branches.
The target (left side) must be a branch signal: an access function applied to a continuous branch. The branch may be a named (or explicit) branch, or it may be an unnamed (or implicit) branch, which are given as a single net or a pair of nets. When an implicit branch is given as a pair of nets, the branch is assumed to connect the two nets. When an implicit branch is specified as a single net, the branch is assumed to connect that net to ground.
Here is a resistor module that uses a explicitly declared or named branch:
module resistor (p, n); parameter real r = 0; branch (p, n) res; analog V(res) <+ r*I(res); endmodule
Here is a resistor module that uses a implicitly declared or unnamed branch:
module resistor (p, n); parameter real r = 0; analog V(p,n) <+ r*I(p,n); endmodule
Descriptions that employ unnamed branches are a little more compact, but also the formulation of the branches is constrained (multiple contributions to flows give a shunt toplogy and to potentials gives a series topology). For this reason people use unnamed branches with the branch topology is simple, and switch to named branches for the more complicated topologies.
The actual contributions occur after the analog block has been evaluated, meaning that the branch values do not change between statements in the analog block. As such, so as long as the values of the right-hand side expressions are not affected, the order of the contribution statements is inconsequential. So for example, these two analog blocks are equivalent:
analog begin V(in) <+ 200m; V(out) <+ 5*V(in); end analog begin V(out) <+ 5*V(in); V(in) <+ 200m; end
An indirect assignment is an alternative to the contribution statement. It also drives a particular branch potential or flow so that a given equation is satisfied, but in this case the driven branch potential or flow need not be in the specified equation. This feature is rarely needed, however it occasionally allows you to describe a component that would cumbersome to describe with contributions. For example, it is possible to describe an ideal opamp using:
analog begin: V(out): V(pin,nin) == 0; end
This can be read as ‘drive V(out) such that V(pin,nin) == 0’.
The left side of the equation must be either a branch potential or flow, the right side is an expression. The equation may be implicit or explicit.
The driven branch must not also be a target of a contribution statement.
A assignment evaluates the expression on its right hand side and then immediately assigns the value to the variable on its left hand side:
a = b + c;
The target (left side) of an analog assignment statement may only be a integer or real variable. It may not be signal or a wire.
Contribution versus Assignment¶
For people new to Verilog-A and Verilog-AMS, contribution and assignment seem to be doing very similar things, and this can confuse them. Here the differences between contribution and assignment are highlighted.
|Operates on||branch signals||variables|
|Evaluates||after all processes||immediately|
|Formulation||implicit or explicit||explicit only|