|  |  | 
 | 
|  |  |  | 
|  |  | 
 | 
|  |  | Introduction | 
 
|  |  | The e language has a number of predefined data types including the integer and Boolean scalar types common to most programming languages. Below is list of data types that we will be seeing in detail in next few pages. As such e language data types are far better then what we find in SystemC and TestBuilder (man I hate type conversions).
 | 
|  |  | 
 | 
|  |  | 
  Scalar Types  
  Scalar Subtypes
  Enumerated Scalar Types
  Struct Types
  Struct Subtypes 
  List Types  
  The String Type
 | 
|  |  | 
 | 
|  |  | Scalar Data Types | 
 
|  |  | Scalar data types are one of the below
 | 
|  |  | 
 | 
|  |  | 
      Numeric
      Boolean
      Enumerated
 | 
|  |  | 
 | 
|  |  | Numeric and Boolean Scalar Types
 | 
|  |  | Below Table shows the e Numeric and Boolean scalar types
 | 
|  |  | 
 | 
|  |  | 
| Type Name |  Function
 |  
| int |  Represents numeric data, both negative and non-negative integers. Default Size = 32 bits
 |  
| uint |  Represents unsigned numeric data, non-negative integers only. Default Size = 32 bits
 |  
| bit |  An unsigned integer in the range 0-1.  Size = 1 bit
 |  
| byte |  An unsigned integer in the range 0-255.  Size = 8 bits
 |  
| time |  An integer in the range 0-263-1. Default Size = 64 bits
 |  
| bool |  Represents truth (logical) values, TRUE (1) and FALSE (0). Default Size = 1 bit
 |  | 
|  |  | 
 | 
|  |  | Example
 | 
|  |  | 
  1 <'
  2 struct data_types1 {
  3   // Signed Integer Date Type
  4   memory_address : int; 
  5   // Unsigned Integer Data Type
  6   memory_data    : uint;
  7   // Bit Data Type
  8   chip_enable    : bit;
  9   // Byte Data Type
 10   read_data      : byte;
 11   // Time Data Type
 12   current_time   : time;
 13   // Boolean Data Type
 14 };
 15 '>
You could download file data_types1.e
 here | 
|  |  | 
 | 
|  |  | Scalar Sub-Types | 
 
|  |  | You can create a scalar subtype by using a scalar modifier to specify the range or bit width of a scalar type. You can also specify a name for the scalar subtype if you plan to use it repeatedly in your program. Unbounded integers are a predefined scalar subtype.
 | 
|  |  | 
 | 
|  |  | 
  int [0..100] (bits: 7)
  int [0..100] (bits: 7)
  int (bytes: 1)
  int (bits: 8)
 | 
|  |  | 
 | 
|  |  | Example
 | 
|  |  | 
  1 <'
  2 
  3 type valid_range_a : int [0..100] (bits:8);
  4 type valid_range_d : int [0..150] (bytes:1);
  5 
  6 struct data_types2 {
  7   // Signed Integer Date Type
  8   memory_address : int (bits:8); 
  9   // Unsigned Integer Data Type
 10   memory_data    : uint (bits:8);
 11   // Valid range with bits
 12   read_address   : valid_range_a;
 13   // Valid range with byte
 14   read_data      : valid_range_d; 
 15 };
 16 '>
You could download file data_types2.e
 here | 
|  |  | 
 | 
|  |  | Enumerated Scalar Types | 
 
|  |  | As in any programming language, we can have enumerated data types in e language also, Below is the list of things for a e language enumerated scalar types.
 | 
|  |  | 
 | 
|  |  | 
  You can define the valid values for a variable or field as a list of symbolic constants.
  These symbolic constants have associated unsigned integer values.  
 By default, the first name in the list is assigned the value zero. 
 Subsequent names are assigned values based upon the maximum value of the previously defined enumerated items + 1.
   You can also assign explicit unsigned integer values to the symbolic constants.
  We can define named enumerated type as an empty type, This can be later extended.
 | 
|  |  | 
 | 
|  |  | Example
 | 
|  |  | 
  1 <'
  2 type   kind_default_values  : [good, bad];
  3 type   kind_assigned_values : [good = 2, bad = 3];
  4 type   kind_only_few        : [good = 3, bad];
  5 // Empty 
  6 type   packet_protocol: [];
  7 // Extend
  8 extend packet_protocol : [Ethernet, IEEE, foreign];
  9 //Sized 
 10 type   packet_kind: [good, bad] (bits: 2);
 11 
 12 struct data_types3 {
 13   packet_type  :  packet_protocol;
 14   packet_valid :  packet_kind;
 15 };
 16 // Just to check our code
 17 extend sys {
 18   data : data_types3;
 19   run() is also {
 20     gen data;
 21     print data;
 22     gen data;
 23     print data;
 24     gen data;
 25     print data;
 26   };
 27 };
 28 '>
You could download file data_types3.e
 here | 
|  |  | 
 | 
|  |  |   data = data_types3-@0: data_types3
	----------------------------------------------	@data_types3
0	packet_type:                    foreign
1	packet_valid:                   good
  data = data_types3-@1: data_types3
	----------------------------------------------	@data_types3
0	packet_type:                    foreign
1	packet_valid:                   bad
  data = data_types3-@2: data_types3
	----------------------------------------------	@data_types3
0	packet_type:                    Ethernet
1	packet_valid:                   good
 | 
|  |  | 
 | 
|  |  |  | 
|  |  | 
 | 
|  |  | Struct Types | 
 
|  |  | 
 | 
|  |  | Structs are the basis building blocks for any e language based testbenches. This are similar to class in C++ and thus are used for constructing compound data structures. Like in C++ and C, we can use this compound data structures in all the places like
 | 
|  |  | 
 | 
|  |  | 
  Can be used as regular data types in any context where a type is required 
 The default value for a struct is NULL
   Passing to/from methods (functions in C).
  Can be used in another stuct as normal data type
  You can also define a variable using a struct type.
 | 
|  |  | 
 | 
|  |  | Example
 | 
|  |  | 
  1 <'
  2 struct data_types4 {
  3   mem_addr : uint (bits : 8);
  4   mem_data : uint (bytes: 1);
  5   mem_rdwr : bit;
  6 };
  7 // Just to check our code
  8 extend sys {
  9   data : data_types4;
 10 
 11   print_struct(pdata : data_types4) is {
 12     outf ("Address   : %d\n",pdata.mem_addr);
 13     outf ("Data      : %d\n",pdata.mem_data);
 14     outf ("Read      : %d\n",pdata.mem_rdwr);
 15   };
 16   run() is also {
 17     out("Generating............");
 18     gen data;
 19     print_struct(data);
 20     out("Generating............");
 21     gen data;
 22     print_struct(data);
 23     out("Generating............");
 24     gen data;
 25     print_struct(data);
 26   };
 27 };
 28 '>
You could download file data_types4.e
 here | 
|  |  | 
 | 
|  |  | Generating............
Address   : 189
Data      : 58
Read      : 0
Generating............
Address   : 120
Data      : 148
Read      : 1
Generating............
Address   : 34
Data      : 148
Read      : 0
 | 
|  |  | 
 | 
|  |  | We will see more on the structs in next section.
 | 
|  |  | 
 | 
|  |  | List Types | 
 
|  |  | List is same as that we find in TCL lanuage. List types hold ordered collections of data elements where each data element conforms to the same type. Items in a list can be indexed with the subscript operator [ ], by placing a non-negative integer expression in the brackets. List indexes start at zero. You can select an item from a list by specifying its index.
 | 
|  |  | 
 | 
|  |  | Lists are defined by using the list of keyword in a variable or a field definition. 
 | 
|  |  | 
 | 
|  |  | Note :e does not support multi-dimensional lists (lists of lists). To create a list with sublists in it, you can create a struct to contain the sublists, and then create a list of such structs as the main list. The default value of a list is an empty list.
 | 
|  |  | 
 | 
|  |  | There are two of lists in e language
 | 
|  |  |  | 
|  |  | 
 | 
|  |  | List methods | 
 
|  |  | There are many default methods provided by e language to work with list data types. Some of them are listed below
 | 
|  |  | 
 | 
|  |  | 
  size() : This is used to set the size of the list.
  add()  : Add an item to the end of a list
  add0() : Add an item to the head of a list
  clear(): Delete all items from a list
  delete() : Delete an item from a list
  insert(index,item) : Insert an item in a list at a specified index
  pop() : Remove and return the last list item
  pop0() : Remove and return the first list item
  push() : Add an item to the end of a list
  push0() : Add an item to the head of a list
  resize() : Change the size of a list
  key():Get the item that has a particular key
  key_index():Get the index of an item that has a particular key
  key_exists():Check that a particular key is in a list
 | 
|  |  | 
 | 
|  |  | Regular Lists | 
 
|  |  | The examples below is a regular list, Where we can access a item with []. 
 | 
|  |  | 
 | 
|  |  | Example
 | 
|  |  | 
  1 <'
  2 type packet_protocol : [ETHERNET, IEEE, ATM];
  3 
  4 struct packet {
  5   protocol     :  packet_protocol;
  6   // payload is list of bytes
  7   // Which size is always 10 bytes
  8   payload      : list of byte;
  9   keep payload.size() == 10;
 10 };
 11 // Just to check our code
 12 extend sys {
 13   // Create the list of the packets
 14   data : list of packet;
 15   // Set number of packets to generate to 4
 16   // i.e. set the size of list 
 17   keep data.size() == 4;
 18   run() is also {
 19     gen data;
 20     for each in data do {
 21       print it;
 22       print it.payload;
 23     };
 24   };
 25 };
 26 '>
You could download file list_example.e
 here | 
|  |  | 
 | 
|  |  |   it = packet-@0: packet
	----------------------------------------------	@list_example
0	protocol:                       IEEE
1	payload:                        (10 items)
  it.payload =  (10 items, dec): 
	             133 185  157 142 231 104   85 230 102 168  	.0	
  it = packet-@1: packet
	----------------------------------------------	@list_example
0	protocol:                       ATM
1	payload:                        (10 items)
  it.payload =  (10 items, dec): 
	               2  44  224 216 156  14  216  12  52  80  	.0	
  it = packet-@2: packet
	----------------------------------------------	@list_example
0	protocol:                       ETHERNET
1	payload:                        (10 items)
  it.payload =  (10 items, dec): 
	             112 201  150  25 244 227  194 171  77  96  	.0	
  it = packet-@3: packet
	----------------------------------------------	@list_example
0	protocol:                       ETHERNET
1	payload:                        (10 items)
  it.payload =  (10 items, dec): 
	              69 214   58 191 194 192   64 252 143  82  	.0	
 | 
|  |  | 
 | 
|  |  | Keyed Lists | 
 
|  |  | A keyed list data type is similar to hash tables or association lists found in other programming languages. The declaration below specifies that memory is a list of byte, and that the addr filed is used as the hash key.
 | 
|  |  | 
 | 
|  |  | Example
 | 
|  |  | 
  1 <'
  2 struct base_object {
  3    addr : byte;
  4    data : byte;
  5 };
  6 
  7 struct keyed_list {
  8    ! memory  : list (key:addr) of base_object;
  9   // writing to a keyed list
 10   write_item(object : base_object) is {
 11      memory.add(object); 
 12      print object;
 13   };
 14   // Reading from keyed list
 15   read_item(object : base_object) is {
 16      var local_object : base_object = memory.key(object.addr);
 17      print local_object;
 18   };
 19 };
 20 // Just to check our code
 21 extend sys {
 22   data      : base_object;
 23   mem_model : keyed_list;
 24   run() is also {
 25     gen data;
 26     mem_model.write_item(data);
 27     mem_model.read_item(data);
 28   };
 29 };
 30 '>
You could download file keyed_list.e
 here | 
|  |  | 
 | 
|  |  |   object = base_object-@0: base_object
	----------------------------------------------	@keyed_list
0	addr:                           116
1	data:                           2
  local_object = base_object-@0: base_object
	----------------------------------------------	@keyed_list
0	addr:                           116
1	data:                           2
 | 
|  |  | 
 | 
|  |  | Keyed lists cannot be generated. Trying to generate a keyed list results in an error. Therefore, keyed lists must be defined with the do-not-generate sign. The only restriction on the type of the list elements is that they cannot themselves be lists 
 | 
|  |  | 
 | 
|  |  | String Type | 
 
|  |  | The predefined type string is the same as the C NULL terminated (zero terminated) string type. You can assign a series of ASCII characters enclosed by quotes (" ") to a variable or field of type string.
 | 
|  |  | 
 | 
|  |  | Example
 | 
|  |  | 
  1 <'
  2 extend sys {
  3   // Declare a variable as string type
  4   my_string : string;
  5   run() is also {
  6     my_string = "This is sample string";
  7     print my_string;
  8   };
  9 };
 10 '>
You could download file string.e
 here | 
|  |  | 
 | 
|  |  |   my_string = "This is sample string"
 | 
|  |  | 
 | 
|  |  | You cannot access bits or bit ranges of a string, but you can convert a string to a list of bytes and then access a portion of the string. 
 | 
|  |  | 
 | 
|  |  | 
 | 
|  |  | 
 | 
|  |  |  | 
|  |  | 
 |