Extending struct And subtypes
Expending the existing structs are done to add struct members to a previously defined struct or struct subtype.
Members added to the base struct type in extensions apply to all other extensions of the same struct.
Thus, for example, if you extend a method in a base struct with is only, it overrides that method in every one of the like children.
Parameter | Description |
struct-subtype | Adds struct members to the specified subtype of the base struct type only. The added struct members are known only in that subtype, not in other subtypes. |
base-struct-type | The base struct type to extend. |
member... | The contents of the struct. The following are types of struct members |
. | -data fields for storing data |
. | -methods for procedures |
. | -events for defining temporal triggers |
. | -coverage groups for defining coverage points |
. | -when, for specifying inheritance subtypes |
. | -declarative constraints for describing relations between data fields |
. | -on, for specifying actions to perform upon event occurrences |
.. | -expect, for specifying temporal behavior rules |
The extension of a struct can be empty, containing no members.
Example
1 <'
2 struct structs_units4 {
3 addr : byte;
4 data : byte;
5 rd_wr: bool;
6 };
7
8 // Empty Extension
9 extend structs_units4 {
10
11 };
12
13 // New elements added
14 extend structs_units4 {
15 drive_delay : uint;
16 };
17
18 // Add new method
19 extend structs_units4 {
20 say_hi() is {
21 out ("Hello Dude");
22 };
23 };
24 '>
Extending SubTypes |
A struct subtype is an instance of the struct in which one of its fields has a particular value. A struct subtype can optionally be specified with extend, so that the extension only applies to that subtype.
1 <'
2 struct structs_units5 {
3 addr : byte;
4 rd_wr: bool;
5
6 when TRUE'rd_wr structs_units5 {
7 data : byte;
8 };
9 };
10
11 // Short Way to extend subtype
12 extend TRUE'rd_wr structs_units5 {
13 write_delay : uint;
14 };
15
16 // Second natual way to extend subtype
17 extend structs_units5 {
18 when TRUE'rd_wr structs_units5 {
19 no_writes : byte;
20 keep no_writes < 10;
21 keep write_delay < 10;
22 };
23 };
24
25 extend sys {
26 obj : structs_units5;
27 // This method shows a sub type can accessed
28 print_obj () is {
29 if (obj.rd_wr == TRUE) {
30 out ("Access Type is : Write");
31 outf("Access Address is : %x\n",
32 obj.addr);
33 outf("Access Data is : %x\n",
34 obj.as_a(TRUE'rd_wr structs_units5).data);
35 outf("Access write_delay is : %x\n",obj.
36 as_a(TRUE'rd_wr structs_units5).write_delay);
37 outf("Access no_writes is : %x\n",obj.
38 as_a(TRUE'rd_wr structs_units5).no_writes);
39 } else {
40 out ("Access Type is : Read");
41 outf("Access Address is : %x\n",obj.addr);
42 };
43 };
44 // Just generate the obj and print it
45 run() is also {
46 for {var i : int = 0; i < 2; i = i + 1} do {
47 gen obj;
48 print_obj();
49 };
50 };
51 };
52
53 '>
Access Type is : Write
Access Address is : 74
Access Data is : 2b
Access write_delay is : 7
Access no_writes is : 9
Access Type is : Read
Access Address is : e6
Defining Fields
Defines a field to hold data of a specific type. You can specify whether it is a physical field or a virtual field, and whether the field is to be automatically generated. For scalar data types, you can also specify the size of the field in bits or bytes.
Note : You can reference a field before it is declared as long as the declaration of the field is in the same file. In the case of cyclic import, the field may be declared in one of the current set of imported files.
Syntax :[!][%] field-name[: type] [[min-val .. max-val]][((bits | bytes):num)]
Parameter | Description |
! | Denotes an ungenerated field. The ! and % options can be used together, in either order. |
% | Denotes a physical field. The ! and % options can be used together, in either order. |
field-name | The name of the field being defined. |
type | The type for the field. This can be any scalar type, string, struct, or list. If the field name is the same as an existing type, you can omit the type part of the field definition. Otherwise, the type specification is required. |
min-val..max-val | An optional range of values for the field, in the form. If no range is specified, the range is the default range for the field s type. |
(bits | bytes, num) | The width of the field in bits or bytes. This syntax allows you to specify a width for the field other than the default width. This syntax can be used for any scalar field, even if the field has a type with a known width. |
Physical Fields
A field defined as a physical field (with the % option) is packed when the struct is packed. Fields that represent data that is to be sent to the HDL device in the simulator or that are to be used for memories in the simulator or in Specman Elite, need to be physical fields. Nonphysical fields are called virtual fields and are not packed automatically when the struct is packed, although they can be packed individually.
If no range is specified, the width of the field is determined by the field's type. For a physical field, if the field's type does not have a known width, you must use the (bits | bytes : num) syntax to specify the width.
Ungenerated Fields
A field defined as ungenerated (with the ! option) is not generated automatically. This is useful for fields that are to be explicitly assigned during the test, or whose values involve computations that cannot be expressed in constraints.
Ungenerated fields get default initial values (0 for scalars, NULL for structs, empty list for lists). An ungenerated field whose value is a range (such as [0..100]) gets the first value in the range. If the field is a struct, it will not be allocated and none of the fields in it will be generated.
Assigning Values to Fields
Unless you define a field as ungenerated, Specman Elite will generate a value for it when the struct is generated, subject to any constraints that exist for the field. However, even for generated fields, you can always assign values in user-defined methods or predefined methods such as init(), pre_generate(), or post_generate(). The ability to assign a value to a field is not affected by either the ! option or generation constraints.
Example Of Fields
1 <'
2 struct structs_units6 {
3 %addr : byte;
4 %data : byte;
5 %rd_wr: bool;
6 rd_wt : uint [0..100];
7 wr_wt : uint [0..100];
8 ! drive_delay : uint [0..10];
9 };
10
11 extend sys {
12 obj : structs_units6;
13 run() is also {
14 for {var i : int = 0; i < 2 ; i = i + 1} do {
15 gen obj;
16 print obj;
17 };
18 };
19 };
20 '>
obj = structs_units6-@0: structs_units6
---------------------------------------------- @structs_units6
0 %addr: 116
1 %data: 2
2 %rd_wr: FALSE
3 rd_wt: 77
4 wr_wt: 78
5 !drive_delay: 0
obj = structs_units6-@1: structs_units6
---------------------------------------------- @structs_units6
0 %addr: 230
1 %data: 240
2 %rd_wr: TRUE
3 rd_wt: 58
4 wr_wt: 26
5 !drive_delay: 0
drive_delay is always 0, as it not generated.
Bạn Có Đam Mê Với Vi Mạch hay Nhúng - Bạn Muốn Trau Dồi Thêm Kĩ Năng