Subject: [sv-bc] RE: [sv-ec] Question: logic & reg - what is the difference?
From: Steven Sharp (sharp@cadence.com)
Date: Mon Jun 09 2003 - 14:03:36 PDT
>A "reg" is actually a composite object, it is the combination of a driver
>and a wire. When you write to it you are assigning to the driver and when
>you read you get the wire value (the resolution of all the drivers of the
>wire). "logic" is the (default) type of the driver.
I am afraid you are confused here. A reg is not resolved. When you write
to it, you write to the actual value. When you read from it, you get the
last value that was written. It works just like a variable in a normal
programming language. There are no drivers, no resolution, and no
separation of "driving value" and "effective value" (to use non-Verilog
terminology).
Now, if you attach a reg to a port, then there is an implicit continuous
assignment from the reg to the net on the other side of the port. That
net may have multiple drivers, and if you read that net you will get the
resolution of all the drivers. But this is not a property of a reg. It
is the property of the port with the reg attached, or of any port that
has a port expression attached that is not collapsed. (Note that I am
talking about Verilog here, which doesn't have variable or reference ports
or anything else that SV may have added to ports.)
Perhaps you have only used regs attached to ports.
>In order to extended the type system to handle signals with multiple
>data, strength and certainty values (user defined types) you need to be able
>to declare similar wire/driver pairs but with a different driver types, e.g.:
>
> typedef my_logic;
> ...
> reg my_logic foo; // create wire foo and driver of type my_logic
If you want a wire in Verilog, you declare a wire. If you want a driver,
you declare a module that drives the wire through a port, or a gate, or
a continuous assignment.
>An alternative approach is to declare and bind drivers explicitly, which
>would allow you to have multiple drivers shared by multiple processes e.g.:
>
> wire foo;
> driver logic d1(foo); // bind driver d1 to wire foo
> driver my_logic d2(foo);
>
> initial d1 = 1'bz;
>
> initial d2 = ml_inactive;
In Verilog, your "driver" things would be continuous assignments:
assign foo = d1;
assign foo = d2;
Verilog already has this covered.
>That approach has some advantages if you want to attach a driver to single
>element of a composite object e.g.:
>
> struct foo {
> logic b1;
> logic b2;
> } bar;
>
> driver logic fb1(bar.b1);
>
> initial fb1 = 1'b1;
Under the Cadence datatype proposal to the IEEE, which allows nets of struct
type, this could be done in a way consistent with existing Verilog:
wire foo bar;
assign bar.b1 = fb1;
Again, to get a net, you declare a net. To drive the net or a subpart of
the net, you declare a continuous assignment.
>Resolving multiple/user-defined types on a wire is a seperate discussion :-)
Indeed so.
Steven Sharp
sharp@cadence.com
This archive was generated by hypermail 2b28 : Mon Jun 09 2003 - 14:06:44 PDT