Data Object Kinds

From: Kathy McKinley (mckinley@cadence.com)
Date: Thu Mar 04 2004 - 06:59:40 PST


Since the issue of confusing semantics for "reg" came up last week,
I thought that the following write-up on the current Verilog semantics
(from Steven Sharp) might be helpful:

------------------------------------------------------------------------------

Data Object Kinds

Verilog has data objects that can have a value of a given type. There
are three kinds of data objects in Verilog: parameters, variables, and
nets. These different kinds of data objects may hold values of the same
type, but differ in their update semantics (how the value is set).

Parameters

A parameter is a constant. Its value is set during compilation and
cannot be modified afterwards. The standard defines how the value is
determined, based on the parameter declaration and parameter overrides.
Parameters, localparams and specparams are subcategories of parameters,
which have slightly different rules about how their values can be set.

Attributes are also constants with values set during compilation.
However, they are not really data objects in the usual sense, because
they cannot be read by the Verilog code.

Genvars are not really data objects either. As specified in the current
generate proposal, they are not accessible to the Verilog code. They
are used during compilation to set the values of implicit localparams.

Variables

A variable is set to a value by a procedural assignment, and holds its
value between assignments (exactly like a variable in most programming
languages). In the 1364-1995 standard, they were commonly called "regs",
because that keyword was used in the most common type of declaration.

The term "reg" was presumably chosen because the original language
designer expected them to be used to represent hardware registers.
They do have a basic feature in common with hardware registers: there
is a specific operation to set their value, after which they hold the
value until it is set to something different. They do not always
represent a hardware register in the mind of the designer or the
output of a synthesis tool. However, such variables are still set
within the language by procedural assignments and hold their value
between assignments. The procedural assignment itself is instantaneous
and has no lasting duration.

In addition to regs, there are also integer, time, real and realtime
variables. In Verilog-1995, these keywords implied both a datatype and
the variable object kind. However, in Verilog-2001, it became legal to
apply these keywords as datatypes for a parameter object kind. This
was an initial step toward making datatypes orthogonal with data object
kinds.

All formal arguments of Verilog tasks and functions are variables. The
act of calling a task or function automatically performs a procedural
assignment from the actual argument expression to the formal argument
variable for input and inout arguments. Returning from a task or
function automatically performs a procedural assignment from the formal
argument variable to the actual argument for an output or inout argument
(so any actual argument passed to an output or inout argument must be
a variable). The formal argument variables can also be assigned like
normal variables from inside the task or function (or even via
hierarchical names from outside it, a little known fact). The return
value of a function is also a special variable, which is generally
set within the function, and then read by the caller as the function
value.

Named events are not really data objects, since they do not have a
data value, and therefore a datatype. However, the triggering operation
could be considered an "update", or abstraction of a change to the value
that they don't actually have, and an event control can wait for that
abstract change. Since the triggering operation is a procedural
statement, like a procedural assignment, named events are closest to
matching variables in their "update semantics".

Nets

A net is driven continuously by zero or more drivers, such as a
continuous assignment or gate. The drivers connected to a net are
determined during compilation, and remain continuously connected to
the net, contributing (or driving) a value onto the net. The resulting
value of the net is determined based on the contributions of all of
the drivers connected to it. Exactly how this is determined is based
on the net type, and the strength of the drivers. (While the strength
could be considered part of the value being driven, it is derived from
the driver and not generally accessible for anything other than the
built-in resolution of the net value. Therefore, it is best to regard
it as separate from the data value.)

The net types in Verilog are wire, tri, wand, triand, wor, trior, tri0,
tri1, supply0, supply1, and trireg. Some of these are synonyms for
each other. The net type affects how the final value is determined
(what is called a "resolution function" in VHDL). Some are equivalent
to having extra implicit drivers attached. The trireg is a special
case that feeds the previous result value back, creating a sort of
memory element (which is intended to model charge storage nodes). It
is possible for a driver to contribute a "Z" or high-impedance value,
which all net types treat as having no effect on the result value.
This can lead to confusion in terminology, since this is sometimes
described as "not driving" (in electrical terms), but at other times
described as "driving Z" (since from a language viewpoint, the driver
is still attached and contributing a value, which is Z).

Anything emerging from the "sink" side of a module port (the inside
of an input port, the outside of an output port, or either side of
an inout port) is always a net. If the "source" side is not a net
then there will always be an implicit continuous assignment created
from the "source" value to the "sink" net. If a port is declared as
an output reg port, then there is a reg inside the module, but it
still emerges as a net, with an implicit continuous assignment from
the internal reg to the external net. If both "source" and "sink"
sides are nets, then an implementation may still insert a continuous
assignment (except for inout ports). It may instead "collapse" the
port, combining the two nets into one larger net, with all of the
drivers of both nets connected to it. In this way, a net may actually
be modeled as a distributed object that crosses module boundaries to
connect things together, the way the designer probably visualizes it.

In present Verilog, a net can only have a value of the standard 4-value
logic datatype (or a vector or array thereof). There is a standard
kludge used to place real values onto a vector net, so that it can be
transmitted through a port.

Sources of Confusion

There is a lot of confusion about the differences between variable and
net objects. Most of this probably comes from regarding the output of
synthesis as defining the semantics of the Verilog language. This is
incorrect. The semantics of the Verilog language are defined by the
Verilog standard. A synthesis tool may produce output that does not
exactly match those semantics. Even though the designer may regard
this output as the actual circuit that they were trying to specify
with their Verilog RTL, a Verilog simulator must still follow semantics
defined by the standard in simulating that RTL.

As noted previously, a reg may not always be synthesized as a hardware
register. It may be synthesized as a physical net instead. A reg may
have been used with a so-called "combinational always block", to model
combinational logic. With sufficient style restrictions, the variable
update semantics used for the reg can mimic the effects of net update
semantics. As long as the always block has full sensitivity, performs
a procedural assignment to the reg in all paths, and is the only process
that writes to the reg, the visible effect is the same as a continuous
assignment to a net. However, this does not make the reg into a net
from the viewpoint of the Verilog language. It is still being updated
instantaneously by procedural assignments, not continuously driven like
a net.

Conversely, a Verilog simulator may implement a continuous assignment
to a single driver of a net with a mechanism much like a combinational
always block. The LRM may describe the behavior this way to make it
clear how it can be implemented. However, the conceptual model of a
continuous assignment is that it drives continuously. This is admittedly
an abstract distinction. The difference is only visible when there are
multiple drivers or writers to a single object.

Procedural continuous assignments add another possible source of
confusion. When applied to variables, they behave much like a continuous
assignment or combinational always block. Since they override any
procedural assignments or previous procedural continuous assignment to
the same variable, they guarantee that there is only one active "driver"
of the variable. Under these circumstances, there is no way to
distinguish whether their update semantics are those of a combinational
always block or a continuous assignment. Because a procedural continuous
assignment resembles a continuous assignment in assigning an expression
and evaluating and assigning its value again whenever the expression
changes value, it is convenient to regard it like a continuous assignment,
even though that doesn't match the normal update semantics for a variable.

Similarly, $deposit (a nonstandard system task) and some PLI calls can
change the value of a net without continuously driving it. The behavior
of this is unpredictable and nonportable. Since nets are conceptually
viewed as being continuously driven, not updated under defined
circumstances, the standard does not specify when this value will
get overwritten with the driven value. It should clearly be overwritten
if the driven value changes, but might or might not be overwritten in
other situations. This makes the behavior implementation-dependent. It
is probably best to just ignore this questionable capability.



This archive was generated by hypermail 2.1.4 : Thu Mar 18 2004 - 05:27:13 PST and
sponsored by Boyd Technology, Inc.