2-state 4-state behaviour

From: Dave Rich (David.Rich@synopsys.com)
Date: Mon Apr 05 2004 - 16:23:56 PDT

  • Next message: Clifford E. Cummings: "Re: 2-state 4-state behaviour"

    Hi,

    I while back I had a discussion with Kurt about the packed 2/4 state issue and orthogonality with
    wires. He suggested I post it to this group. BTW, I am now on the btf-dtype reflector

    If its not too late...

    A reason to have packed structs behave as a 4-state vectors when used as a whole is that a packed
    struct is basically an implied union, and the behavior should match that of an explicit union. This
    is a better reason, and adds to the "good for the implementation" reason I gave at the btf-dtype
    meeting.

    For example, suppose I have the following explicit packed union:

    typedef struct packed {
        bit [7:0] byteA;
        reg [7:0] byteB;
    } AB_t;

    union packed {
        AB_t AB;
        reg [15:0] V;
    } U;

    initial begin
        U.AB.byteA = 8'h55;
        U.AB.byteB = 8'hzz;
        V = V << 4;
        $displayh(V); // expect to see 5zz0
        $displayh({U.AB.byteA,U.AB.byteB}); // expect to see 50z0
        end

    Now lets take the implicit union version. AB as a whole is a 4-state bit vector that is in an
    implied union with the packed structure.

    AB_t AB;
    initial begin
        AB.byteA = 8'h55;
        AB.byteB = 8'hzz;
        AB = AB << 4;
        $displayh(AB); //expect to see 5zz0
        $displayh({AB.byteA,AB,byteB}); //expect to see 50z0

    A similar approach with can be used when overlaying data types with wires.

    In Verilog-2001, the strength system is used for driving wires and passing through MOS primitives.
    However, when reading wires, they are converted to a 4-state values. Using SystemVerilog
    terminology, we would say that "they are cast to a 4-state value when used in an integral expression"

    A wire declared with a user defined data type should behave as an implicit union between the wire
    net type and variable data type. You always uses the net type for driving, and the data type for
    reading. (you never write to a wire, except via the PLI) What this means is that you can have
    multiple drivers with different strengths on an wire with a user defined type, and the wire will be
    resolved using the standard rules for that net type. It is only when that wire needs to be cast to
    an integral expression that the data type is used.

    For example, lets say I have a wired and declared with the type AB_t above.

    wand <AB_t> ABw;
    pullup pA[7:1] (ABw.byteA[7:1]); // pullup all but bit 0
    pullup pB[7:1] (ABw.byteB[7:1]); // pullup all but bit 0
    buf (ABw.byteA[7],0); // will be 0 because strong0 overrides pull1
    buf (ABw.byteB[7],0); // will be 0 because strong0 overrides pull1
    buf (ABw.byteA[6],1'bx); // will be 0 because strongX overrides pull1, and X cast to 0
    buf (ABw.byteB[6],1'bx); // will be X because strongX overrides pull1
    buf (weak0,weak1) (ABw.byteA[5],0); // will be 1 because pull1 overrides weak0
    buf (weak0,weak1) (ABw.byteB[5],0); // will be 1 because pull1 overrides
    weak0
    buf (pull0,pull1) (ABw.byteA[4],0); // will be 0 because wire-and of 1 and 0
    buf (pull0,pull1) (ABw.byteB[4],0); // will be 0 because wire-and of 1 and 0
    buf (pull0,pull1) (ABw.byteA[3],1); // will be 1 because wire-and of 1 and 1
    buf (pull0,pull1) (ABw.byteB[3],1); // will be 1 because wire-and of 1 and 1
    buf (pull0,pull1) (ABw.byteA[3],1'bx); // will be 0 because wire-and of 1 and x, cast to 0
    buf (pull0,pull1) (ABw.byteB[3],1'bx); // will be x because wire-and of 1 and x
    initial #1 #1 for (i=7;i>=0;i=i-1) $display("%b %v %b %v ",
            ABw.byteA[i], ABw.byteA[i], ABw.byteB[i], ABw.byteB[i],,i);
    endmodule

    Will display
    0 St0 0 St0 7
    0 StX x StX 6
    1 Pu1 1 Pu1 5
    0 Pu0 0 Pu0 4
    0 PuX x PuX 3
    1 Pu1 1 Pu1 2
    1 Pu1 1 Pu1 1
    0 HiZ z HiZ 0

    Note that the only difference in the table above is the x and z is
    converted to 0 for binary representation of byteA.

    With this proposal, "logic" becomes the default type for wires and behaves exactly as a wire would
    in Verilog.

    wire <logic> foo; // is equivalent to
    wire foo;

    By making "logic" the default type for both reg and wire, I believe we merge all the different
    proposals together and still be backwards compatible with existing SV. (still need to work out the
    best syntax)

    Dave

    --
    --
    David.Rich@Synopsys.com
    Technical Marketing Consultant and/or
    Principal Product Engineer
    http://www.SystemVerilog.org
    tele:  650-584-4026
    cell:  510-589-2625
    


    This archive was generated by hypermail 2.1.4 : Mon Apr 05 2004 - 16:06:13 PDT and
    sponsored by Boyd Technology, Inc.