[sv-bc] RE: [sv-ec] Question: logic & reg - what is the difference?


Subject: [sv-bc] RE: [sv-ec] Question: logic & reg - what is the difference?
From: Kevin Cameron (sv-xx@grfx.com)
Date: Mon Jun 09 2003 - 15:05:42 PDT


> From: Steven Sharp <sharp@cadence.com>
>
> >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.

I'm not confused. The unattached case is just a degenerate case that behaves
as you describe - the driving value and effective value are the same, and
since propogation is immediate there is no difference between a reg and
a variable as far as ther user is concerned.

>
> >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.

I meant "wire" in a more physical sense. A port is not really a driver, it's
just connectivity - viewing it as a driver leads to bad modelling semantics.
In general a driver should map to some active piece of circuitry i.e. a
transistor for ICs, ports don't.

> >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.

Not really. You can use a single explicit driver from multiple processes, each
assign statement creates a seperate driver.

>
> >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.

That would be equivalent if you can do all that is needed with a single process,
the explicit driver approach allows you to break the behavior up e.g. you could
add:

    always @(clk) fb1 = data;
    always @(reset) fb1 = 1'b0;

bar.b1 gets the last value assigned to fb1, no resolution is performed as would be
with three assign statements.

It's more like:

    struct foo {
      logic b1;
      logic b2;
    } bar;

    reg fb1;

    alias fb1 = bar.b1;

    initial fb1 = 1'b1;
    ...

except that creates a wire (fb1) with an implicit driver, rather than just the driver.

Kev.
    
> >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 - 15:07:31 PDT