[sv-bc] Errata: Complex Data Types of Wires (fwd)

From: Shalom.Bresticker@freescale.com
Date: Thu Aug 26 2004 - 20:34:50 PDT

  • Next message: Charles Dawson: "Call for participation: IEEE 1800 CC - errata committee"

    -- 
    Shalom Bresticker                        Shalom.Bresticker @freescale.com
    Design & Reuse Methodology                           Tel: +972 9  9522268
    Freescale Semiconductor Israel, Ltd.                 Fax: +972 9  9522890
    POB 2208, Herzlia 46120, ISRAEL                     Cell: +972 50 5441478
      
    [ ]Freescale Internal Use Only      [ ]Freescale Confidential Proprietary
    

    ---------- Forwarded message ---------- Date: Thu, 26 Aug 2004 18:58:25 +0200 From: "Jonathan Bradford;Freiburg" <bradford@micronas.com> To: sv-bc@eda.org Cc: sv-ec@eda.org Subject: [sv-bc] Errata: Complex Data Types of Wires

    Complex Data Types of Wires

    Motivation

    This is a request based on usage of System Verilog for an extension to System Verilog for accessing wires with complex data structures implied by their driving registers or data destinations. The examples have been modified to the proposed syntax in the summary.

    In System Verilog the interface can have signals declared as wires or variables.

    The wires can be declared as vectors or vectors of vectors or arrays of vectors, reflecting whether they are packed or unpacked data types. The wire can also be of various resolved types, such as tri1 (pullup) or trireg (holding) etc. The wire can also be in signed or unsigned (default) arithmetic.

    The variables can also be declared as vectors and vectors of vectors and arrays of vectors. They can also be defined as many other data types, as packed types for implementation such as structures etc, or unpacked for verification such as dynamic arrays etc. Again these may have attributes for signed or unsigned arithmetic and packed or unpacked data storage.

    But there is no resolution capability. i.e. they may be written to discretely by assignments in procedural code or a single structural assignment (continuous or connectivity).

    When implementing an RTL design it is safe to model states in the design using variables in the interfaces, so long as there is a single direction of signal flow and no multiple drivers.

    There are a number of constructs in System Verilog language to ensure this, such as interface modports with output statements for the variable to be written and the use of always_ff to constrict the assignments to these interface variables. These constructs restrict structural and procedural assignment to the state variables and implicate registered outputs in the single driving blocks.

    This allows the use of variables with complex data definitions such as structs etc in RTL implementation.

    However there are scenarios in RTL implementation where it is necessary to allow bidirectionality or at least multiple drivers (and enables) onto a common bus.

    This implies that only wires can be used for these interface signals. The driving variables are then explicitly assigned to, from the modules interfaced to the bus.

    But wires cannot be defined with such complex data structures as variables. Hence once a value is on the wires in the bus in the interface, it is not possible to use those signal values as easily as in the original variables. This is especially the case for structs.

    There are two main problems

    o wires containing values driven by variables of complex type must be

    correctly sized, throughout the interface hierarchy.

    o components of values on wires implied by the 'shape' of the driving

    variable need to be made accessible wrt those `shapes' rather than the explicit 'shape' of the wire.

    i.e.

    // a register driving the bus might be :-

    typedef struct packed { logic ecc; logic [7:0] data; } MemLoc;

    MemLoc mem_r;

    // whereas the signal in the interface - driven by multiple modules (enabled) :-

    wire [8:0] memsig;

    modport driver (inout [8:0] memsig);

    // a user of the interface signal needs to know where ecc and data are !

    my_ecc = memsig[8]; my_data = memsig[7:0];

    If the definition of the structure were changed, the design hierarchy must be worked through to change all these structural references to the wires that transport signal values.

    One way to do this particular example is to use casting:

    my_ecc = MemLoc'(memsig).ecc my_data = MemLoc'(memsig).data

    However a cast cannot be an lvalue or an output port, so a more general facility is needed. A language extension to allow a packed data type to be associated with a wire vector can provide this generality and reduce the typing:

    The structure must be packed. The structure can be either 4-state or 2-state, but 4-state is recommended to maintain compatibility between variables and wires of the same type. There is one wire for each bit or logic, and the wire can have the normal range of strength values. The wire can be of type tri1, tri0, trireg, supply0, supply1 etc.

    Example

    // wire and interface definition

    wire <MemLoc> memsig;

    modport driver (inout <MemLoc> memsig);

    // this is similar to // wire [$bits(MemLoc)-1:0] memsig;

    // wire element of `shape` access

    my_ecc = memsig.ecc;

    my_data = memsig.data;

    assign memsig = mem_r;

    assign memsig.ecc = ^mem_r.data;

    Hence if the structure MemLoc changes, the slice access routines for the wire signals remain unchanged.

    In reality there is nothing changed in the behaviour of variables and wires, only in how their content is perceived.

    This perception of the shape is also independent of the driver, as there can be multiple drivers of the aggregate wire. The same wire may therefore be perceived in multiple ways :-

    typedef struct packed {logic [1:0] ignore, logic [6:0] ascii} CharLoc;

    my_data [7:0] = memsig.data; my_data [7:0] = CharLoc'(memsig).ascii; // msb becomes 0

    typedef union packed {MemLoc ML; CharLoc CL;} AnyLoc; AnyLoc anysig;

    my_data [7:0] = {anysig.ML.ecc, anysig.CL.ascii};

    Furthermore if the structure definition contains attributes such as signed for the arithmetic of its members, this is maintained for a member access, but not for the corresponding slice.

    typedef struct packed { logic signed [7:0] a; logic [7:0] b; } Slog;

    wire <Slog> slog_sig;

    if (slog_sig.a >>1 == slog_sig[15:8] >>1) $display ("Not all the time, No");

    The problem with respect to overloaded operators can be exemplified by considering a user defined structure to represent a fixed point number with fields for mantissa and exponent. Currently when a wire is used as an argument to such an operator, there is no way to infer that the value within the wire should be the mantissa and exponent as opposed to the integral integer value of a wire. However this is resolved when a wire has a structure definition.

    Summary

    A proposal for a collection of wires to be treated as a structure, as explained above.

    This proposal is to allow a type identifier to be used instead of signing and packed dimensions in net declarations.

    net declaration ::= net_type_or_trireg [ drive_strength | charge_strength ] [ vectored | scalared ] [ signing ] { packed_dimension } [ delay3 ] list_of_net_decl_assignments | net_type_or_trireg [ drive_strength | charge_strength ] [ vectored | scalared ] < type_identifier > [ delay3 ] list_of_net_decl_assignments ;

    The type_identifier should be limited to packed types.

    The < > characters are used to remove ambiguity.

    --

    ________________________________________________________________________ ________

    /\ Jonathan Bradford mailto:bradford@micronas.com <mailto:bradford@micronas.com>

    \/

    /\/\ MICRONAS GmbH http://www.micronas.com <http://www.micronas.com>

    /\/\/\

    \/\/\/ Hans-Bunte-Str.19 Tel: +49 (0)761 517 2884

    \/\/ D-79108 Freiburg Fax: +49 (0)761 517 2880

    \/ Germany



    This archive was generated by hypermail 2.1.4 : Thu Aug 26 2004 - 20:29:18 PDT and
    sponsored by Boyd Technology, Inc.