Previous Section Next Section

4.4 Defining List Fields

List fields are used very frequently in e. Lists of any data type, enumerated type, or user-defined struct can be defined in e.

An initial size can be specified for the list. The list initially contains that number of items. The size conforms to the initialization rules, the generation rules, and the packing rules. Even if an initial size is specified, the list size can change during the test if the list is operated on by a list method that changes the number of items. All list items are initialized to their default values when the list is created. For a generated list, the initial default values are replaced by generated values. The syntax for a list declaration is shown below.

[!][%]list-name[[length-exp]]: list of type ;

The components of a list field definition are shown in Table 4-4 below.

Table 4-4. Components of a List Field Definition

!

Do not generate this list. The "!" and "%" options can be used together, in either order.

%

Denotes a physical list. The "!" and "%" options can be used together, in either order.

list-name

Names the list being defined.

length-exp

Indicates an expression that gives the initial size for the list. The expression must evaluate to a non-negative integer.

type

Indicates he type of items in the list. This can be any scalar type, string, or struct. It cannot be a list.

Lists are dynamic objects that are used for holding stimulus items, struct instances, data values, etc. Lists can be resized. Example 4-5 illustrates a list definition.

Example 4-5 List Field Definition
Example of a list field definition
<'
//Define a struct cell
struct cell {
    %data: list of byte; //Physical Field: List of 8-bit values
    %length: uint; //Physical Field: Unsigned integer
    strings: list of string; //Virtual Field: List of Strings
};
//Define a struct packet

struct packet {
    %is_legal: bool; //Physical Field: Boolean
    cells: list of cell; //Virtual Field: List of struct cell
                         //This field will contain multiple instances
                        //of struct cell
};
//Extend the sys struct
extend sys {
    packets[16]: list of packet; //Virtual Field: List of 16 instances
                                 //of packet struct
};
'>

4.4.1 List Operations

Many pseudo-methods are available to operate on lists. When a list field is defined, the pseudo-methods can be used with that list field. Table 4-5 shows the commonly used pseudo-methods that are available to operate on a list. Any arguments required by the predefined method go in parentheses after the predefined method name. Pseudo-methods can be called in actions or constraints.

Once a list field or variable has been declared, you can operate on it with a list predefined method by attaching the predefined method name, preceded by a period, to the list name. Many of the list pseudo-methods take expressions as arguments and operate on every item in the list. Table 4-5 shows the most commonly used pseudo-methods available for lists.

Table 4-5. Pseudo-methods for Lists

Name

Arguments

Description

Example

add(item);

push(item);

add(list);

Item of the same list type OR

List of same type.

Adds the item or list to the end of the list.

var i_list: list of int;
i_list.add(5);

add0(item);

push0(item);

add0(list);

Item of the same list type OR

List of same type.

Adds the item or list to the start of the list.

var i_list: list of int;
i_list.add0(5);

clear();

None

Deletes all items from the list.

var a_list;
a_list.clear();

delete(index);

Non-negative integer index.

Deletes the item at index location. Index=0 is the first item in the list.

var l_list: list of int =
            {2; 4; 6; 8};
l_list.delete(2);
//Deletes 6 from list
//Result {2; 4; 8};

insert(index,item);

insert(index, list);

Non-negative integer index.

Item of the same list type OR

List of same type.

Inserts the item or list at the specified index.

var l_list := {10; 20; 30};
l_list.insert(1, 99);
//Result {10; 99; 20; 30};

pop(item);

Item of the same list type.

Removes the last item from the list and returns it.

var l_list := {10; 20; 30};
l_list.pop();
//Result {10; 20};
//Return value = 30

pop0(item);

Item of the same list type.

Removes the first item from the list and returns it.

Same as delete(0).

var l_list := {10; 20; 30};
l_list.pop0();
//Result {20; 30};
//Return value = 10

resize(size);

Integer indicating size to which the list is resized.

Resizes the list to the declared size and initializes all elements to the default value unless specified otherwise.

extend sys {
run() is also {
var q_list: list of byte;
q_list.resize(200);
//Resizes list to 200 bytes
};
};

size()

None

Returns an integer equal to the number of items in the list. A common use for this method is in a keep constraint, to specify an exact size or a range of values for the list size.

<'
extend sys {
p_list: list of packet;
keep p_list.size() == 10;
//Size of generated list is
//exactly 10.
};
'>

is_empty()

None

Checks if the list is empty and returns a boolean value. Returns TRUE if list is empty, or FALSE if the list is not empty.


<'
extend sys {
b_list[5]: list of byte;
lmeth() is {
var no_l: bool;
no_l =
\~\~\~\~\~\~sys.b_list.is_empty();
   sys.b_list.is_empty();
//no_l will be FALSE
};
};
'>

4.4.2 Keyed Lists

Keyed lists are used to enable faster searching of lists by designating a particular field or value which is to be searched for. A keyed list can be used, for example, in the following ways:

Although all of the operations that can be done using a keyed list can also be done using a regular list, using a keyed list provides an advantage in the greater speed of searching a keyed list. The general syntax for defining a keyed list is as follows.

![%]list-name: list(key: key-field) of type ;

The components of a keyed list definition are described in Table 4-6 below.

Table 4-6. Defining Keyed Lists

!

Do not generate this list. For a keyed list, the "!" is required, not optional.

%

Denotes a physical list. The "%" option may precede or follow the "!".

list-name

Names the list being defined.

key-field

Indicates the key of the list. For a list of structs, it is the name of a field of the struct. This is the field or value which the keyed list pseudo-methods will check when they operate on the list. For a list of scalars, the key can be the it variable referring to each item. The keyword it is context dependent and points to the relevant object in a particular context. See Table 4-7 and Example 4-6 for details on usage of the it variable.

type

Indicates the type of items in the list. This can be any scalar type, string, or struct. It cannot be a list.

Besides the key parameter, the keyed list syntax differs from regular list syntax in the following ways:

A keyed list is a distinct type, different from a regular list. This means that you cannot assign a keyed list to a regular list, nor assign a regular list to a keyed list. Table 4-7 shows three pseudo-methods associated with keyed lists.

Table 4-7. Keyed List Pseudo-methods

Name

Arguments

Description

Example

key(key-exp);

The key of the item that is to be returned

Returns the list item that has the specified key, or NULL if no item with that key exists in the list.

var l_list: list(key: it)
      of int = {5; 4; 3; 2; 1};
print l_list.key(5);
//prints 5

Key_index

(key-exp);

The key to be searched for

Returns the integer index of the item that has the specified key, or returns UNDEF if no item with that key exists in the list.

var l_list: list(key: it)
      of int = {5; 4; 3; 2; 1};
print l_list.key_index(2);
//prints 3

Key_exists

(key-exp);

The key to be searched for

Returns TRUE if the key exists in the list, or FALSE if it does not.

var l_list: list(key: it)
      of int = {5; 4; 3; 2; 1};
print l_list.key_exists(2);
//prints TRUE

Example 4-6 shows an instance in which the list named cl is declared to be a keyed list of four-bit uints, with the key being the list item itself. That is, the key is the value of a four-bit uint. A list of 10 items is built up by generating items and adding them to the keyed list in the for loop.

Example 4-6 Keyed Lists
Example of keyed lists
<'
extend sys {
    !cl: list(key: it) of uint(bits: 4);
    run() is also {
        var ch: uint(bits: 4);
        for i from 0 to 10 {
            gen ch;
            cl.add(ch);
        };

        if cl.key_exists(8) then {
            print cl;
            print cl.key_index(8);
        };
    };
};
'>

Results
cl =  (10 items, decimal):
             4 5 8 3 14 9 11 4 5 13

cl.key_index(8) = 2

We discussed only simple applications of keyed lists. Keyed lists can be used with complex structs, where a field in that struct can be used as a key.

Previous Section Next Section